node-v4.2.6/000755 000766 000024 00000000000 12650222331 012742 5ustar00iojsstaff000000 000000 node-v4.2.6/.editorconfig000644 000766 000024 00000001064 12650222322 015420 0ustar00iojsstaff000000 000000 root = true [*] end_of_line = lf charset = utf-8 trim_trailing_whitespace = true [vcbuild.bat] end_of_line = crlf [*.{md,markdown}] trim_trailing_whitespace = false [{lib,src,test}/**.js] indent_style = space indent_size = 2 [src/**.{h,cc}] indent_style = space indent_size = 2 [test/*.py] indent_style = space indent_size = 2 [configure] indent_style = space indent_size = 2 [Makefile] indent_style = tab indent_size = 8 [{deps,tools}/**] indent_style = ignore indent_size = ignore end_of_line = ignore trim_trailing_whitespace = ignore charset = ignore node-v4.2.6/.eslintignore000644 000766 000024 00000000137 12650222322 015446 0ustar00iojsstaff000000 000000 lib/punycode.js test/addons/doc-*/ test/fixtures test/**/node_modules test/disabled test/tmp*/ node-v4.2.6/.eslintrc000644 000766 000024 00000007240 12650222322 014571 0ustar00iojsstaff000000 000000 env: node: true # enable ECMAScript features ecmaFeatures: arrowFunctions: true binaryLiterals: true blockBindings: true classes: true forOf: true generators: true objectLiteralShorthandMethods: true objectLiteralShorthandProperties: true octalLiterals: true templateStrings: true rules: # Possible Errors # list: https://github.com/eslint/eslint/tree/master/docs/rules#possible-errors ## check debugger sentence no-debugger: 2 ## check duplicate arguments no-dupe-args: 2 ## check duplicate object keys no-dupe-keys: 2 ## check duplicate switch-case no-duplicate-case: 2 ## disallow assignment of exceptional params no-ex-assign: 2 ## disallow use of reserved words as keys like enum, class no-reserved-keys: 2 ## disallow unreachable code no-unreachable: 2 ## require valid typeof compared string like typeof foo === 'strnig' valid-typeof: 2 # Best Practices # list: https://github.com/eslint/eslint/tree/master/docs/rules#best-practices ## require falls through comment on switch-case no-fallthrough: 2 # Stylistic Issues # list: https://github.com/eslint/eslint/tree/master/docs/rules#stylistic-issues ## use single quote, we can use double quote when escape chars quotes: [2, "single", "avoid-escape"] ## 2 space indentation indent: [2, 2] ## add space after comma comma-spacing: 2 ## put semi-colon semi: 2 ## require spaces operator like var sum = 1 + 1; space-infix-ops: 2 ## require spaces return, throw, case space-return-throw-case: 2 ## no space before function, eg. 'function()' space-before-function-paren: [2, "never"] ## require space before blocks, eg 'function() {' space-before-blocks: [2, "always"] ## require parens for Constructor new-parens: 2 ## max 80 length max-len: [2, 80, 2] ## max 2 consecutive empty lines no-multiple-empty-lines: [2, {max: 2}] ## require newline at end of files eol-last: 2 ## no trailing spaces no-trailing-spaces: 2 # require space after keywords, eg 'for (..)' space-after-keywords: 2 # ECMAScript 6 # list: http://eslint.org/docs/rules/#ecmascript-6 ## Suggest using 'const' wherever possible prefer-const: 2 # Strict Mode # list: https://github.com/eslint/eslint/tree/master/docs/rules#strict-mode ## 'use strict' on top strict: [2, "global"] # Variables # list: https://github.com/eslint/eslint/tree/master/docs/rules#variables ## disallow use of undefined variables (globals) no-undef: 2 ## disallow declaration of variables that are not used in the code no-unused-vars: [2, {"args": "none"}] # Custom rules in tools/eslint-rules require-buffer: 2 new-with-error: [2, "Error", "RangeError", "TypeError", "SyntaxError", "ReferenceError"] # Global scoped method and vars globals: DTRACE_HTTP_CLIENT_REQUEST : false LTTNG_HTTP_CLIENT_REQUEST : false COUNTER_HTTP_CLIENT_REQUEST : false DTRACE_HTTP_CLIENT_RESPONSE : false LTTNG_HTTP_CLIENT_RESPONSE : false COUNTER_HTTP_CLIENT_RESPONSE : false DTRACE_HTTP_SERVER_REQUEST : false LTTNG_HTTP_SERVER_REQUEST : false COUNTER_HTTP_SERVER_REQUEST : false DTRACE_HTTP_SERVER_RESPONSE : false LTTNG_HTTP_SERVER_RESPONSE : false COUNTER_HTTP_SERVER_RESPONSE : false DTRACE_NET_STREAM_END : false LTTNG_NET_STREAM_END : false COUNTER_NET_SERVER_CONNECTION_CLOSE : false DTRACE_NET_SERVER_CONNECTION : false LTTNG_NET_SERVER_CONNECTION : false COUNTER_NET_SERVER_CONNECTION : false escape : false unescape : false node-v4.2.6/.gitattributes000644 000766 000024 00000000060 12650222322 015631 0ustar00iojsstaff000000 000000 test/fixtures/* -text vcbuild.bat text eol=crlf node-v4.2.6/.gitignore000644 000766 000024 00000002256 12650222322 014737 0ustar00iojsstaff000000 000000 core vgcore.* v8*.log perf.data perf.data.old .waf* tags .lock-wscript *.pyc doc/api.xml tmp/ test/tmp*/ iojs iojs_g node node_g *.swp .benchmark_reports /.project /.cproject icu_config.gypi /out # various stuff that VC++ produces/uses Debug/ !node_modules/debug/ Release/ !doc/blog/** *.sln !nodemsi.sln *.suo *.vcproj *.vcxproj !custom_actions.vcxproj *.vcxproj.user *.vcxproj.filters UpgradeLog*.XML _UpgradeReport_Files/ ipch/ *.sdf *.opensdf /config.mk /config.gypi /config_fips.gypi *-nodegyp* /gyp-mac-tool /dist-osx /npm.wxs /tools/msvs/npm.wixobj /tools/osx-pkg.pmdoc/index.xml /test/addons/doc-*/ email.md deps/v8-* deps/icu deps/icu*.zip deps/icu*.tgz deps/icu-tmp ./node_modules android-toolchain/ .svn/ # generated by gyp on Windows deps/openssl/openssl.props deps/openssl/openssl.targets deps/openssl/openssl.xml # generated by gyp on android /*.target.mk /*.host.mk deps/openssl/openssl.target.mk deps/zlib/zlib.target.mk # not needed and causes issues for distro packagers deps/npm/node_modules/.bin/ # build/release artifacts /*.tar.* /SHASUMS*.txt* # test artifacts tools/faketime icu_config.gypi test.tap # Xcode workspaces and project folders *.xcodeproj *.xcworkspace node-v4.2.6/.mailmap000644 000766 000024 00000020554 12650222322 014371 0ustar00iojsstaff000000 000000 Aaron Heckmann Abe Fettig Alex Kocharin Alex Kocharin Alexey Kupershtokh Alexis Campailla Alexis Sellier Alexis Sellier Andy Bettisworth Aria Stewart Arlo Breault Artem Zaytsev Arnout Kazemier <3rd-Eden@users.noreply.github.com> Atsuo Fukaya Ben Noordhuis Ben Taber Bert Belder Bert Belder Bert Belder Brandon Benvie Brian White Brian White Caleb Boyd Charles Chew Choon Keat Charles Rudolph Claudio Rodriguez Colin Ihrig Christopher Lenz Dan Kaplun Daniel Berger Daniel Chcouri <333222@gmail.com> Daniel Gröber Daniel Gröber Daniel Pihlström Danny Nemer Dave Pacheco David Siegel Domenic Denicola Domenic Denicola Eduard Burtescu Einar Otto Stangvik Elliott Cable EungJun Yi Evan Larkin Evan Lucas Evan Lucas Farid Neshat Fedor Indutny Felix Böhm Felix Geisendörfer Felix Geisendörfer Friedemann Altrock Fuji Goro Gabriel de Perthuis Gil Pedersen Henry Chin Herbert Vojčík Icer Liang Igor Soarez Igor Zinkovsky Isaac Z. Schlueter Isaac Z. Schlueter Jake Verbaten James Hartig Jan Krems Jered Schmidt Jeremiah Senkpiel Jerry Chin Joe Shaw Johan Bergström Johan Dahlberg Johann Hofmann Jonas Pfenniger Jonathan Ong Jonathan Persson Jonathan Rentzsch Josh Erickson Joshua S. Weinstein Junliang Yan Junliang Yan Jérémy Lal Jérémy Lal Kai Sasaki Lewuathe Karl Skomski Kazuyuki Yamada Keith M Wesolowski Kelsey Breseman Koichi Kobayashi Kris Kowal Kyle Robinson Young Luke Bayes Maciej Małecki Malte-Thorben Bruns Malte-Thorben Bruns Marcin Cieślak Marcin Cieślak Marti Martz Martial James Jefferson Mathias Pettersson Matthew Lye Michael Bernstein Michael Wilber Micheil Smith Micleusanu Nicu Mikael Bourges-Sevenier Miroslav Bajtoš Mitar Milutinovic Nebu Pookins Nicholas Kinsey Nikolai Vavilov Onne Gorter Paul Querna Peter Flannery Phillip Johnsen Ray Morgan Ray Solomon Raymond Feng Rick Olson Roman Klauke Roman Reiss Ron Korving Ryan Dahl Ryan Emery Sakthipriyan Vairamani Sam Mikes Sam P Gallagher-Bishop Sam Shull Sam Shull Sambasiva Suda Sam Roberts San-Tai Hsu Scott Blomquist Sergey Kryzhanovsky Shannen Saez Shigeki Ohtsu Siddharth Mahendraker Simon Willison Stanislav Opichal Stefan Bühler Steven R. Loomis Todd Kennedy TJ Holowaychuk TJ Holowaychuk Tadashi SAWADA Takahiro ANDO Ted Young Thomas Lee Thomas Reggi Tim Caswell Tim Price Tim Smart Tim Smart Tom Hughes Tom Hughes-Croucher Trevor Burnham Tyler Larson Vincent Voyer Willi Eggeling Yazhong Liu Yazhong Liu Yazhong Liu Yorkie Yazhong Liu Yorkie Yoshihiro KIKUCHI Yosuke Furukawa Yuichiro MASUI Zachary Scott Zoran Tomicic # These people didn't contribute patches to node directly, # but we've landed their v8 patches in the node repository: Daniel Clifford Erik Corry Jakob Kummerow Kevin Millikin Lasse R.H. Nielsen Michael Starzinger Toon Verwaest Vyacheslav Egorov Yang Guo node-v4.2.6/android-configure000755 000766 000024 00000001026 12650222322 016266 0ustar00iojsstaff000000 000000 #!/bin/bash export TOOLCHAIN=$PWD/android-toolchain mkdir -p $TOOLCHAIN $1/build/tools/make-standalone-toolchain.sh \ --toolchain=arm-linux-androideabi-4.9 \ --arch=arm \ --install-dir=$TOOLCHAIN \ --platform=android-21 export PATH=$TOOLCHAIN/bin:$PATH export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc export CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++ export LINK=$TOOLCHAIN/bin/arm-linux-androideabi-g++ ./configure \ --dest-cpu=arm \ --dest-os=android node-v4.2.6/AUTHORS000644 000766 000024 00000077265 12650222322 014033 0ustar00iojsstaff000000 000000 # Authors ordered by first contribution. Ryan Dahl Urban Hafner Joshaven Potter Abe Fettig Kevin van Zonneveld Michael Carter Jeff Smick Jon Crosby Felix Geisendörfer Ray Morgan Jérémy Lal Isaac Z. Schlueter Brandon Beacher Tim Caswell Connor Dunn Johan Sørensen Friedemann Altrock Onne Gorter Rhys Jones Jan Lehnardt Simon Willison Chew Choon Keat Jered Schmidt Michaeljohn Clement Karl Guertin Xavier Shay Christopher Lenz TJ Holowaychuk Johan Dahlberg Simon Cornelius P. Umacob Ryan McGrath Rasmus Andersson Micheil Smith Jonas Pfenniger David Sklar Charles Lehner Elliott Cable Benjamin Thomas San-Tai Hsu Ben Williamson Joseph Pecoraro Alexis Sellier Blaine Cook Stanislav Opichal Aaron Heckmann Mikeal Rogers Matt Brubeck Michael Stillwell Yuichiro MASUI Mark Hansen Zoran Tomicic Jeremy Ashkenas Scott González James Duncan Arlo Breault Kris Kowal Jacek Becela Rob Ellis Tim Smart Herbert Vojčík Krishna Rajendran Nicholas Kinsey Scott Taylor Carson McDonald Matt Ranney James Herdman Julian Lamb Brian Hammond Mathias Pettersson Thomas Lee Daniel Berger Paulo Matias Peter Griess Jonathan Knezek Jonathan Rentzsch Ben Noordhuis Elijah Insua Andrew Johnston Brian White Aapo Laitinen Sam Hughes Orlando Vazquez Raffaele Sena Brian McKenna Paul Querna Ben Lowery Peter Dekkers David Siegel Marshall Culpepper Ruben Rodriguez Dmitry Baranovskiy Blake Mizerany Jerome Etienne Dmitriy Shalashov Adam Wiggins Rick Olson Sergey Kryzhanovsky Marco Rogers Benjamin Fritsch Jan Kassens Robert Keizer Sam Shull Chandra Sekar S Andrew Naylor Benjamin Kramer Danny Coates Nick Stenning Bert Belder Trent Mick Fedor Indutny Illarionov Oleg Aria Stewart Johan Euphrosine Russell Haering Bradley Meck Tobie Langel Tony Metzidis Mark Nottingham Sam Stephenson Jorge Chamorro Bieling Evan Larkin Sean Coates Tom Hughes Joshua Peek Nathan Rajlich Peteris Krumins AJ ONeal Sami Samhuri Nikhil Marathe Vitali Lovich Stéphan Kochen Oleg Efimov Guillaume Tuton Tim Cooijmans Dan Søndergaard Silas Sewell Wade Simmons Daniel Gröber Travis Swicegood Oleg Slobodskoi Jeremy Martin Michael Wilber Sean Braithwaite Anders Conbere Devin Torres Theo Schlossnagle Kai Chen Daniel Chcouri <333222@gmail.com> Mihai Călin Bazon Ali Farhadi Daniel Ennis Carter Allen Greg Hughes David Trejo Joe Walnes Koichi Kobayashi Konstantin Käfer Richard Rodger Andreas Reich Tony Huang Dean McNamee Trevor Burnham Zachary Scott Arnout Kazemier George Stagas Ben Weaver Scott McWhirter Jakub Lekstan Nick Campbell Nebu Pookins Tim Baumann Robert Mustacchi George Miroshnykov Mark Cavage Håvard Stranden Marcel Laverdet Alexandre Marangone Ryan Petrello Fuji Goro Siddharth Mahendraker Dave Pacheco Mathias Buus Henry Rawas Yoshihiro KIKUCHI Brett Kiefer Mariano Iglesias Jörn Horstmann Joe Shaw Niklas Fiekas Adam Luikart Artem Zaytsev Alex Xu Jeremy Selier Igor Zinkovsky Kip Gebhardt Stefan Rusu Shigeki Ohtsu Wojciech Wnętrzak Devon Govett Steve Engledow Pierre-Alexandre St-Jean Reid Burke Vicente Jimenez Aguilar Tadashi SAWADA Jeroen Janssen Daniel Pihlström Stefan Bühler Alexander Uvarov Aku Kotkavuo Peter Bright Logan Smyth Christopher Wright Glen Low Thomas Shinnick Mickaël Delahaye Antranig Basman Maciej Małecki Evan Martin Peter Lyons Jann Horn Abimanyu Raja Karl Skomski Niclas Hoyer Michael Jackson Ashok Mudukutore Sean Cunningham Vitor Balocco Ben Leslie Eric Lovett Christian Tellnes Colton Baker Tyler Larson Tomasz Janczuk Ilya Dmitrichenko Simen Brekken Guglielmo Ferri <44gatti@gmail.com> Thomas Parslow Ryan Emery Jordan Sissel Matt Robenolt Jacob H.C. Kragh Benjamin Pasero Scott Anderson Yoji SHIDARA Mathias Bynens Łukasz Walukiewicz Artur Adib E. Azer Koçulu Paddy Byers Roman Shtylman Kyle Robinson Young Tim Oxley Eduard Burtescu Ingmar Runge Russ Bradberry Andreas Madsen Adam Malcontenti-Wilson Avi Flax Pedro Teixeira Johan Bergström James Hartig Shannen Saez Seong-Rak Choi Dave Irvine Ju-yeong Park Phil Sung Damon Oehlman Mikael Bourges-Sevenier Emerson Macedo Ryunosuke SATO Michael Bernstein Guillermo Rauch Dan Williams Brandon Benvie Nicolas LaCasse Dan VerWeire Matthew Fitzsimmons Philip Tellis Christopher Jeffrey Seth Fitzsimmons Einar Otto Stangvik Paul Vorbach Luke Gallagher Tomasz Buchert Myles Byrne T.C. Hollingsworth Cam Pedersen Roly Fentanes Ted Young Joshua Holbrook Blake Miner Vincent Ollivier Jimb Esser Sambasiva Suda Sadique Ali Dmitry Nizovtsev Alex Kocharin Ming Liu Shea Levy Nao Iizuka Christian Ress Rod Vagg Matt Ezell Charlie McConnell Farid Neshat Johannes Wüller Erik Lundin Bryan Cantrill Yosef Dinerstein Nathan Friedly Aaron Jacobs Mustansir Golawala Atsuo Fukaya Domenic Denicola Joshua S. Weinstein Dane Springmeyer Erik Dubbelboer Malte-Thorben Bruns Michael Thomas Garen Torikian EungJun Yi Vincent Voyer Takahiro ANDO Brian Schroeder J. Lee Coltrane Javier Hernández James Koval Kevin Gadd Ray Solomon Kevin Bowman Erwin van der Koogh Matt Gollob Simon Sturmer Joel Brandt Marc Harter Nuno Job Ben Kelly Felix Böhm George Shank Gabriel de Perthuis Vladimir Beloborodov Tim Macfarlane Jonas Westerlund Dominic Tarr Justin Plock Toshihiro Nakamura Ivan Torres Philipp Hagemeister Mike Morearty Pavel Lang Peter Rybin Timothy J Fontaine Joe Andaverde Tom Hughes-Croucher Eugen Dueck Gil Pedersen Tyler Neylon Josh Erickson Golo Roden Ron Korving Brandon Wilson Ian Babrou Bearice Ren Ankur Oberoi Atsuya Takagi Pooya Karimian Frédéric Germain Robin Lee Kazuyuki Yamada Adam Blackburn Willi Eggeling Paul Serby Andrew Paprocki Ricky Ng-Adam Aaditya Bhatia Max Ogden Igor Soarez Olivier Lalonde Scott Blomquist Francois Marier Brandon Philips Frederico Silva Jan Wynholds Girish Ramakrishnan Anthony Pesch Stephen Gallagher Trevor Norris Sergey Kholodilov Tim Kuijsten Michael Axiak Chad Rhyner Kai Sasaki Lewuathe Nicolas Chambrier Ben Taber Luke Arduini Luke Bayes Tim Bradshaw Nirk Niggler Johannes Ewald James Hight Mike Harsch Chris Dent Alexandr Emelin James Campos Dan Milon Dave Olszewski Tim Price Jake Verbaten Jacob Gable Andy Burke Sugendran Ganess Rick Yakubowski Jim Schubert Victor Costan Dan Kohn Arianit Uka Andrei Sedoi Eugene Girshov Evan Oxfeld Lars-Magnus Skog Raymond Feng Aaron Cannon Xidorn Quan Paolo Fragomeni Henry Chin Julian Gruber JeongHoon Byun Iskren Ivov Chernev Alexey Kupershtokh Manav Rathi Benjamin Ruston Marcin Kostrzewa Suwon Chae David Braun Mitar Milutinovic Michael Hart Andrew Hart Rafael Garcia Tobias Müllerleile Stanislav Ochotnicky Ryan Graham Kelly Gerber Ryan Doenges Sean Silva Miroslav Bajtoš Olof Johansson Sam Roberts Kevin Locke Daniel Moore Robert Kowalski Nick Sullivan Benoit Vallée Ryuichi Okumura Brandon Frohs Nathan Zadoks Rafael Henrique Moreira Daniel G. Taylor Kiyoshi Nomo Nick Desaulniers Veres Lajos Yuan Chuan Krzysztof Chrapka Linus Mårtensson Peter Rust Jeff Barczewski Shuan Wang Wyatt Preul David Björklund Dav Glass Andrew Chilton Antony Bailey Forrest L Norvell Evan Solomon Eran Hammer Matthias Bartelmeß Daniel Chatfield Eivind Uggedal Edward Hutchins James Halliday ChrisWren Duan Yao Matthew Aynalem Vsevolod Strukchinsky Jay Beavers Mathias Buus Eric Schrock Jeff Switzer Glen Mailer Jason Gerfen Patrik Stutz Zarko Stankovic Maxim Bogushevich Phillip Alexander Thom Seddon Nick Simmons Jacob Groundwater Jackson Tian fengmk2 Tim Wood Linus Unnebäck Vladimir Kurchatkin David Chan Alexis Campailla Nikolai Vavilov Michael Ridgway Yazhong Liu Gabriel Falkenberg Kai Groner Lalit Kapoor Steven Kabbes Gabriel Farrell Nicolas Kaiser Ahamed Nafeez Cam Swords Paul Loyd Benjamin Waters Lev Gimelfarb Peter Flannery Tuğrul Topuz Lorenz Leutgeb ayanamist gluxon Tom Gallacher Jo Liss Jun Ma Jacob Hoffman-Andrews Keith M Wesolowski Maxime Quandalle Oguz Bastemur Yuriy Nemtsov Benjamin Waters iamdoron Austin Moran Kenan Sulayman Christian Pedro Ballesteros Anton Khlynovskiy Nicolas Talle Mike Pennisi Maxwell Krohn Saúl Ibarra Corretgé Greg Brail Shuhei Kagawa Josh Dague Goh Yisheng (Andrew) James Pickard Andrew Low Nick Apperson C. Scott Ananian Yuki KAN Evan Carroll William Bert goussardg Geir Hauge Farrin Reid Ben Noordhuis Denys Zariaiev Sean McArthur Rasmus Christian Pedersen Forrest L Norvell Adrian Lang Feross Aboukhadijeh Refael Ackermann Taojie Greg Sabia Tucker Dan Kaplun Colin Ihrig Greg Sabia Tucker Mark Stosberg Calvin Metcalf Ryan Cole Kevin Decker Rohini Harendra Chris Barber Michael Kebe Nick Muerdter Roman Klauke Xavi Magrinyà Euan Ed Morley Charles Jan Krems Fred K. Schott Chris Dickinson Jonathan Reem Refael Ackermann Ionică Bizău Eli Skeggs Andrius Bentkus Ed Umansky Maurice Butler John Albietz Andrew Oppenlander Julien Gilli Gabriel Wicke Jakob Gillich Lucio M. Tato Herman Lee Kevin Simper Thorsten Lorenz Ezequiel Rabinovich Cheng Zhao Tristan Berger Isaac Burns Jesús Leganés Combarro "piranna Majid Arif Siddiqui Trevor Livingston Mathias Schreck Adam Lippai Guilherme de Souza Mickael van der Beek Andrew Teich Kang-Hao Kenny Patrick Mooney Jicheng Li James Ferguson Julien Fontanet Steven R. Loomis gyson Steve Sharp Victor Widell Evan Rutledge Borden Johnny Ray Steve Mao Stiliyan Lazarov Wang Xinyong Ray Donnelly dead-horse Luis Reis Jackson Tian sudodoki Steven Loomis haoxin Artur Cistov MK Safi Rory Bradford Calvin Metcalf Nathan Woltman James Cowgill Jamund Ferguson Jonathan Johnson Martin Cozzi Carlos Campderrós Leonardo Balter Bryce Kahle The Gitter Badger Brendan Ashworth Jose Luis Rivas Evan Lucas Vincent Weevers Tyler Kellen Evan Torrie Juanjo brian m. carlson Kevin O'Hara Micleusanu Nicu Alejandro Oviedo Ben Burns Julian Duque teppeis Rudi Cilibrasi Tim Ruffles CGavrila Aleksey Smolenchuk Caitlin Potter Calvin Metcalf Eric Mill pkcs James M Snell Cydox Steven Rockarts Vladimir Guguiev Yosuke Furukawa Tiago Ribeiro Rui Marinho Jesse cogollo Chris Alley Michal Tehnik Aaron Bieber Phil Hughes Jongyeol Choi Brenard Cubacub Thomas Jensen Jay Jaeho Lee Roman Reiss Glen Keane Xiaowei Li <446240525@qq.com> toastynerd Todd Kennedy Icer Liang Stephen Belanger Jeremiah Senkpiel Brendan Ashworth Andres Suarez Jonathan Ong ttrfwork Johnny Ray Austin Mathias Küsel Qasim Zaidi Sam Newman Zach Bruggeman Michaël Zasso Haoliang Gao Rudolf Meijering Ryan Seys Omer Wazir Dan Dascalescu Jan Schär Debjeet Biswas Amir Saboury Charmander <~@charmander.me> Jimmy Hsu jigsaw Emily Rose Shinnosuke Watanabe Bruno Jouhier René Kooi Petka Antonov Ryan Scheel Benjamin Gruenbaum Pavel Medvedev Russell Dempsey &! (bitandbang) h7lin Michael Dawson Ruben Verborgh Ken Perkins Malte-Thorben Bruns Santiago Gimeno Ali Ijaz Sheikh FangDun Cai Alex Yursha Steven Vercruysse Aleksanteri Negru-Vode Mathieu Darse Connor Peet Mayhem Olov Lassus Phillip Lamplugh Kohei TAKATA Giovanny Andres Gongora Granada Jeffrey Jagoda Kelsey Breseman Peter Petrov Andrew Crites Marat Abdullin Dan Varga Nick Raienko Guilherme Souza Chris Yip Christopher Monsanto Alexander Gromnitsky Сковорода Никита Андреевич Sakthipriyan Vairamani AQNOUCH Mohammed Ivan Kozik Oleg Elifantiev Mike MacCana Josh Gummersall Sam Mikes Frederic Hemberger Sharat M R Rich Trott Felipe Batista Rebecca Turner Tyler Anton João Reis Kat Marchán Ryan Petschek Pierre Inglebert Ivan Yan Sangmin Yoon Mark Plomer Phillip Johnsen Matteo Collina jomo Gireesh Punathil Lucien Greathouse Chad Johnston Sam Stites Matthew Lye Matt Loring P.S.V.R Jacob Edelman Mike Atkins hackerjs <4141095@qq.com> Minwoo Jung Marcin Cieślak Anne-Gaelle Colom Oleksandr Chekhovskyi Tristian Flanagan Mike Tunnicliffe Ionică Bizău Danny Nemer Sven Slootweg Dmitry Vasilyev Malcolm Ahoy Imran Iqbal Stewart Addison Matt Harrison Christopher J. Brody Salman Aljammaz Thomas Reggi Laurent Fortin Fabio Oliveira Michał Gołębiowski Johann Hofmann Charles Rudolph Dave Eddy Justin Chase Jeremy Whitlock Rod Machen Martial James Jefferson Doug Shamoo Junliang Yan Dave Hodder Jason Karns Balázs Galambosi David Boivin Liang-Chi Hsieh Timothy Gu Fábio Santos Myles Borins Jonas Dohse Коренберг Марк Caleb Boyd Yuval Brik Claudio Rodriguez Ido Ben-Yair Kyle Smith Marti Martz Stefan Budeanu Emily Aviva Kapor-Mater Sam P Gallagher-Bishop David Woods Ashok Suthar Ömer Fadıl Usta Jerry Chin Hemanth.HM Hugues Malphettes Tyler Henkel Zheng Chaoping Ashley Williams Bryan English Devin Nakamura Vladimir Varankin Manuel B Jesse McCarthy Craig Cavalier Michael Cornacchia Markus Tzoe Martin Forsberg Carl Lei Lewis Cowper Bryon Leung Chunyang Dai Jonathan Persson Dave Luigi Pinca Peter A. Bigot Zirak Scott Buchanan Rebecca Turner Bryce Baril Super Zheng Rafał Pocztarski Michael Ruddy Andy Bettisworth # Generated by tools/update-authors.sh node-v4.2.6/benchmark/000755 000766 000024 00000000000 12650222322 014674 5ustar00iojsstaff000000 000000 node-v4.2.6/BSDmakefile000644 000766 000024 00000000407 12650222322 014774 0ustar00iojsstaff000000 000000 # pmake might add -J (private) FLAGS=${.MAKEFLAGS:C/\-J ([0-9]+,?)+//W} all: .DEFAULT .DEFAULT: @which gmake > /dev/null 2>&1 ||\ (echo "GMake is required for node.js to build.\ Install and try again" && exit 1) @gmake ${.FLAGS} ${.TARGETS} .PHONY: test node-v4.2.6/CHANGELOG.md000644 000766 000024 00002366176 12650222322 014600 0ustar00iojsstaff000000 000000 # Node.js ChangeLog ## 2016-01-21, Version 4.2.6 'Argon' (LTS), @TheAlphaNerd ### Notable changes * Fix regression in debugger and profiler functionality ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`1408f7abb1`](https://github.com/nodejs/node/commit/1408f7abb1)] - **module,src**: do not wrap modules with -1 lineOffset (cjihrig) [#4298](https://github.com/nodejs/node/pull/4298) * [[`1f8e1472cc`](https://github.com/nodejs/node/commit/1f8e1472cc)] - **test**: add test for debugging one line files (cjihrig) [#4298](https://github.com/nodejs/node/pull/4298) ## 2016-01-20, Version 4.2.5 'Argon' (LTS), @TheAlphaNerd Maintenance update. ### Notable changes * **assert** * accommodate ES6 classes that extend Error (Rich Trott) [#4166](https://github.com/nodejs/node/pull/4166) * **build** * add "--partly-static" build options (Super Zheng) [#4152](https://github.com/nodejs/node/pull/4152) * **deps** * backport 066747e from upstream V8 (Ali Ijaz Sheikh) [#4655](https://github.com/nodejs/node/pull/4655) * backport 200315c from V8 upstream (Vladimir Kurchatkin) [#4128](https://github.com/nodejs/node/pull/4128) * upgrade libuv to 1.8.0 (Saúl Ibarra Corretgé) * **docs** * various updates landed in 70 different commits! * **repl** * attach location info to syntax errors (cjihrig) [#4013](https://github.com/nodejs/node/pull/4013) * display error message when loading directory (Prince J Wesley) [#4170](https://github.com/nodejs/node/pull/4170) * **tests** * various updates landed in over 50 commits * **tools** * add tap output to cpplint (Johan Bergström) [#3448](https://github.com/nodejs/node/pull/3448) * **util** * allow lookup of hidden values (cjihrig) [#3988](https://github.com/nodejs/node/pull/3988) ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`87181cd74c`](https://github.com/nodejs/node/commit/87181cd74c)] - **assert**: accommodate ES6 classes that extend Error (Rich Trott) [#4166](https://github.com/nodejs/node/pull/4166) * [[`901172a783`](https://github.com/nodejs/node/commit/901172a783)] - **assert**: typed array deepequal performance fix (Claudio Rodriguez) [#4330](https://github.com/nodejs/node/pull/4330) * [[`55336810ee`](https://github.com/nodejs/node/commit/55336810ee)] - **async_wrap**: call callback in destructor (Trevor Norris) [#3461](https://github.com/nodejs/node/pull/3461) * [[`a8b45e9e96`](https://github.com/nodejs/node/commit/a8b45e9e96)] - **async_wrap**: new instances get uid (Trevor Norris) [#3461](https://github.com/nodejs/node/pull/3461) * [[`49f16d77c4`](https://github.com/nodejs/node/commit/49f16d77c4)] - **async_wrap**: allow some hooks to be optional (Trevor Norris) [#3461](https://github.com/nodejs/node/pull/3461) * [[`44ee33f945`](https://github.com/nodejs/node/commit/44ee33f945)] - **buffer**: refactor create buffer (Jackson Tian) [#4340](https://github.com/nodejs/node/pull/4340) * [[`138d004ac0`](https://github.com/nodejs/node/commit/138d004ac0)] - **buffer**: faster case for create Buffer from new Buffer(0) (Jackson Tian) [#4326](https://github.com/nodejs/node/pull/4326) * [[`c6dc2a1609`](https://github.com/nodejs/node/commit/c6dc2a1609)] - **buffer**: Prevent Buffer constructor deopt (Bryce Baril) [#4158](https://github.com/nodejs/node/pull/4158) * [[`a320045e68`](https://github.com/nodejs/node/commit/a320045e68)] - **buffer**: default to UTF8 in byteLength() (Tom Gallacher) [#4010](https://github.com/nodejs/node/pull/4010) * [[`c5f71ac771`](https://github.com/nodejs/node/commit/c5f71ac771)] - **build**: add "--partly-static" build options (Super Zheng) [#4152](https://github.com/nodejs/node/pull/4152) * [[`e6c25335ea`](https://github.com/nodejs/node/commit/e6c25335ea)] - **build**: omit -gline-tables-only for --enable-asan (Ben Noordhuis) [#3680](https://github.com/nodejs/node/pull/3680) * [[`80b4ba286c`](https://github.com/nodejs/node/commit/80b4ba286c)] - **build**: Updates for AIX npm support - part 1 (Michael Dawson) [#3114](https://github.com/nodejs/node/pull/3114) * [[`35e32985ca`](https://github.com/nodejs/node/commit/35e32985ca)] - **child_process**: guard against race condition (Rich Trott) [#4418](https://github.com/nodejs/node/pull/4418) * [[`48564204f0`](https://github.com/nodejs/node/commit/48564204f0)] - **child_process**: flush consuming streams (Dave) [#4071](https://github.com/nodejs/node/pull/4071) * [[`481d59a74c`](https://github.com/nodejs/node/commit/481d59a74c)] - **configure**: fix arm vfpv2 (Jörg Krause) [#4203](https://github.com/nodejs/node/pull/4203) * [[`d19da6638d`](https://github.com/nodejs/node/commit/d19da6638d)] - **crypto**: load PFX chain the same way as regular one (Fedor Indutny) [#4165](https://github.com/nodejs/node/pull/4165) * [[`b8e75de1f3`](https://github.com/nodejs/node/commit/b8e75de1f3)] - **crypto**: fix native module compilation with FIPS (Stefan Budeanu) [#4023](https://github.com/nodejs/node/pull/4023) * [[`b7c3fb7f75`](https://github.com/nodejs/node/commit/b7c3fb7f75)] - **crypto**: disable crypto.createCipher in FIPS mode (Stefan Budeanu) [#3754](https://github.com/nodejs/node/pull/3754) * [[`31b4091a1e`](https://github.com/nodejs/node/commit/31b4091a1e)] - **debugger**: also exit when the repl emits 'exit' (Felix Böhm) [#2369](https://github.com/nodejs/node/pull/2369) * [[`9baa5618f5`](https://github.com/nodejs/node/commit/9baa5618f5)] - **deps**: backport 066747e from upstream V8 (Ali Ijaz Sheikh) [#4655](https://github.com/nodejs/node/pull/4655) * [[`c3a9d8a62e`](https://github.com/nodejs/node/commit/c3a9d8a62e)] - **deps**: backport 200315c from V8 upstream (Vladimir Kurchatkin) [#4128](https://github.com/nodejs/node/pull/4128) * [[`1ebb0c0fdf`](https://github.com/nodejs/node/commit/1ebb0c0fdf)] - **deps**: upgrade libuv to 1.8.0 (Saúl Ibarra Corretgé) [#4276](https://github.com/nodejs/node/pull/4276) * [[`253fe3e7c8`](https://github.com/nodejs/node/commit/253fe3e7c8)] - **dns**: remove nonexistant exports.ADNAME (Roman Reiss) [#3051](https://github.com/nodejs/node/pull/3051) * [[`8c2b65ad82`](https://github.com/nodejs/node/commit/8c2b65ad82)] - **doc**: clarify protocol default in http.request() (cjihrig) [#4714](https://github.com/nodejs/node/pull/4714) * [[`33e72e135f`](https://github.com/nodejs/node/commit/33e72e135f)] - **doc**: update links to use https where possible (jpersson) [#4054](https://github.com/nodejs/node/pull/4054) * [[`5f4aa79410`](https://github.com/nodejs/node/commit/5f4aa79410)] - **doc**: clarify explanation of first stream section (Vitor Cortez) [#4234](https://github.com/nodejs/node/pull/4234) * [[`295ca5bfb2`](https://github.com/nodejs/node/commit/295ca5bfb2)] - **doc**: add branch-diff example to releases.md (Myles Borins) [#4636](https://github.com/nodejs/node/pull/4636) * [[`18f5cd8710`](https://github.com/nodejs/node/commit/18f5cd8710)] - **doc**: update stylesheet to match frontpage (Roman Reiss) [#4621](https://github.com/nodejs/node/pull/4621) * [[`2f40715f08`](https://github.com/nodejs/node/commit/2f40715f08)] - **doc**: adds usage of readline line-by-line parsing (Robert Jefe Lindstaedt) [#4609](https://github.com/nodejs/node/pull/4609) * [[`5b45a464ee`](https://github.com/nodejs/node/commit/5b45a464ee)] - **doc**: document http's server.listen return value (Sequoia McDowell) [#4590](https://github.com/nodejs/node/pull/4590) * [[`bd31740339`](https://github.com/nodejs/node/commit/bd31740339)] - **doc**: label http.IncomingMessage as a Class (Sequoia McDowell) [#4589](https://github.com/nodejs/node/pull/4589) * [[`bcd2cbbb93`](https://github.com/nodejs/node/commit/bcd2cbbb93)] - **doc**: fix description about the latest-codename (Minwoo Jung) [#4583](https://github.com/nodejs/node/pull/4583) * [[`0b12bcb35d`](https://github.com/nodejs/node/commit/0b12bcb35d)] - **doc**: add Evan Lucas to Release Team (Evan Lucas) [#4579](https://github.com/nodejs/node/pull/4579) * [[`e20b1f6f10`](https://github.com/nodejs/node/commit/e20b1f6f10)] - **doc**: add Myles Borins to Release Team (Myles Borins) [#4578](https://github.com/nodejs/node/pull/4578) * [[`54977e63eb`](https://github.com/nodejs/node/commit/54977e63eb)] - **doc**: add missing backtick for readline (Brian White) [#4549](https://github.com/nodejs/node/pull/4549) * [[`5d6bed895c`](https://github.com/nodejs/node/commit/5d6bed895c)] - **doc**: bring releases.md up to date (cjihrig) [#4540](https://github.com/nodejs/node/pull/4540) * [[`0cd2252e85`](https://github.com/nodejs/node/commit/0cd2252e85)] - **doc**: fix numbering in stream.markdown (Richard Sun) [#4538](https://github.com/nodejs/node/pull/4538) * [[`8574d91f27`](https://github.com/nodejs/node/commit/8574d91f27)] - **doc**: stronger suggestion for userland assert (Wyatt Preul) [#4535](https://github.com/nodejs/node/pull/4535) * [[`a7bcf8b84d`](https://github.com/nodejs/node/commit/a7bcf8b84d)] - **doc**: close backtick in process.title description (Dave) [#4534](https://github.com/nodejs/node/pull/4534) * [[`0ceb3148b0`](https://github.com/nodejs/node/commit/0ceb3148b0)] - **doc**: improvements to events.markdown copy (James M Snell) [#4468](https://github.com/nodejs/node/pull/4468) * [[`bf56d509b9`](https://github.com/nodejs/node/commit/bf56d509b9)] - **doc**: explain ClientRequest#setTimeout time unit (Ben Ripkens) [#4458](https://github.com/nodejs/node/pull/4458) * [[`d927c51be3`](https://github.com/nodejs/node/commit/d927c51be3)] - **doc**: improvements to errors.markdown copy (James M Snell) [#4454](https://github.com/nodejs/node/pull/4454) * [[`ceea6df581`](https://github.com/nodejs/node/commit/ceea6df581)] - **doc**: improvements to dns.markdown copy (James M Snell) [#4449](https://github.com/nodejs/node/pull/4449) * [[`506f2f8ed1`](https://github.com/nodejs/node/commit/506f2f8ed1)] - **doc**: add anchors for _transform _flush _writev in stream.markdown (iamchenxin) [#4448](https://github.com/nodejs/node/pull/4448) * [[`74bcad0b78`](https://github.com/nodejs/node/commit/74bcad0b78)] - **doc**: improvements to dgram.markdown copy (James M Snell) [#4437](https://github.com/nodejs/node/pull/4437) * [[`e244d560c9`](https://github.com/nodejs/node/commit/e244d560c9)] - **doc**: improvements to debugger.markdown copy (James M Snell) [#4436](https://github.com/nodejs/node/pull/4436) * [[`df7e1281a5`](https://github.com/nodejs/node/commit/df7e1281a5)] - **doc**: improvements to console.markdown copy (James M Snell) [#4428](https://github.com/nodejs/node/pull/4428) * [[`abb17cc6c1`](https://github.com/nodejs/node/commit/abb17cc6c1)] - **doc**: fix spelling error in lib/url.js comment (Nik Nyby) [#4390](https://github.com/nodejs/node/pull/4390) * [[`823269db2d`](https://github.com/nodejs/node/commit/823269db2d)] - **doc**: improve assert.markdown copy (James M Snell) [#4360](https://github.com/nodejs/node/pull/4360) * [[`2b1804f6cb`](https://github.com/nodejs/node/commit/2b1804f6cb)] - **doc**: copyedit releases.md (Rich Trott) [#4384](https://github.com/nodejs/node/pull/4384) * [[`2b142fd876`](https://github.com/nodejs/node/commit/2b142fd876)] - **doc**: catch the WORKING_GROUPS.md bootstrap docs up to date (James M Snell) [#4367](https://github.com/nodejs/node/pull/4367) * [[`ed87873de3`](https://github.com/nodejs/node/commit/ed87873de3)] - **doc**: fix link in addons.markdown (Nicholas Young) [#4331](https://github.com/nodejs/node/pull/4331) * [[`fe693b7a4f`](https://github.com/nodejs/node/commit/fe693b7a4f)] - **doc**: Typo in buffer.markdown referencing buf.write() (chrisjohn404) [#4324](https://github.com/nodejs/node/pull/4324) * [[`764df2166e`](https://github.com/nodejs/node/commit/764df2166e)] - **doc**: document the cache parameter for fs.realpathSync (Jackson Tian) [#4285](https://github.com/nodejs/node/pull/4285) * [[`61f91b2f29`](https://github.com/nodejs/node/commit/61f91b2f29)] - **doc**: fix, modernize examples in docs (James M Snell) [#4282](https://github.com/nodejs/node/pull/4282) * [[`d87ad302ce`](https://github.com/nodejs/node/commit/d87ad302ce)] - **doc**: clarify error events in HTTP module documentation (Lenny Markus) [#4275](https://github.com/nodejs/node/pull/4275) * [[`7983577e41`](https://github.com/nodejs/node/commit/7983577e41)] - **doc**: fix improper http.get sample code (Hideki Yamamura) [#4263](https://github.com/nodejs/node/pull/4263) * [[`6c30d087e5`](https://github.com/nodejs/node/commit/6c30d087e5)] - **doc**: Fixing broken links to the v8 wiki (Tom Gallacher) [#4241](https://github.com/nodejs/node/pull/4241) * [[`cf214e56e4`](https://github.com/nodejs/node/commit/cf214e56e4)] - **doc**: move description of 'equals' method to right place (janriemer) [#4227](https://github.com/nodejs/node/pull/4227) * [[`fb8e8dbb92`](https://github.com/nodejs/node/commit/fb8e8dbb92)] - **doc**: copyedit console doc (Rich Trott) [#4225](https://github.com/nodejs/node/pull/4225) * [[`4ccf04c229`](https://github.com/nodejs/node/commit/4ccf04c229)] - **doc**: add mcollina to collaborators (Matteo Collina) [#4220](https://github.com/nodejs/node/pull/4220) * [[`59654c21d4`](https://github.com/nodejs/node/commit/59654c21d4)] - **doc**: add rmg to collaborators (Ryan Graham) [#4219](https://github.com/nodejs/node/pull/4219) * [[`bfe1a6bd2b`](https://github.com/nodejs/node/commit/bfe1a6bd2b)] - **doc**: add calvinmetcalf to collaborators (Calvin Metcalf) [#4218](https://github.com/nodejs/node/pull/4218) * [[`5140c404ae`](https://github.com/nodejs/node/commit/5140c404ae)] - **doc**: harmonize description of `ca` argument (Ben Noordhuis) [#4213](https://github.com/nodejs/node/pull/4213) * [[`2e642051cf`](https://github.com/nodejs/node/commit/2e642051cf)] - **doc**: copyedit child_process doc (Rich Trott) [#4188](https://github.com/nodejs/node/pull/4188) * [[`7920f8dbde`](https://github.com/nodejs/node/commit/7920f8dbde)] - **doc**: copyedit buffer doc (Rich Trott) [#4187](https://github.com/nodejs/node/pull/4187) * [[`c35a409cbe`](https://github.com/nodejs/node/commit/c35a409cbe)] - **doc**: clarify assert.fail doc (Rich Trott) [#4186](https://github.com/nodejs/node/pull/4186) * [[`6235fdf72e`](https://github.com/nodejs/node/commit/6235fdf72e)] - **doc**: copyedit addons doc (Rich Trott) [#4185](https://github.com/nodejs/node/pull/4185) * [[`990e7ff93e`](https://github.com/nodejs/node/commit/990e7ff93e)] - **doc**: update AUTHORS list (Rod Vagg) [#4183](https://github.com/nodejs/node/pull/4183) * [[`8d676ef55e`](https://github.com/nodejs/node/commit/8d676ef55e)] - **doc**: change references from node to Node.js (Roman Klauke) [#4177](https://github.com/nodejs/node/pull/4177) * [[`1c34b139a2`](https://github.com/nodejs/node/commit/1c34b139a2)] - **doc**: add brief Node.js overview to README (wurde) [#4174](https://github.com/nodejs/node/pull/4174) * [[`27b9b72ab0`](https://github.com/nodejs/node/commit/27b9b72ab0)] - **doc**: add iarna to collaborators (Rebecca Turner) [#4144](https://github.com/nodejs/node/pull/4144) * [[`683d8dd564`](https://github.com/nodejs/node/commit/683d8dd564)] - **doc**: add JungMinu to collaborators (Minwoo Jung) [#4143](https://github.com/nodejs/node/pull/4143) * [[`17b06dfa94`](https://github.com/nodejs/node/commit/17b06dfa94)] - **doc**: add zkat to collaborators (Kat Marchán) [#4142](https://github.com/nodejs/node/pull/4142) * [[`39364c4c72`](https://github.com/nodejs/node/commit/39364c4c72)] - **doc**: improve child_process.markdown wording (yorkie) [#4138](https://github.com/nodejs/node/pull/4138) * [[`abe452835f`](https://github.com/nodejs/node/commit/abe452835f)] - **doc**: url.format - true slash postfix behaviour (fansworld-claudio) [#4119](https://github.com/nodejs/node/pull/4119) * [[`6dd375cfe2`](https://github.com/nodejs/node/commit/6dd375cfe2)] - **doc**: document backlog for server.listen() variants (Jan Schär) [#4025](https://github.com/nodejs/node/pull/4025) * [[`b71a3b363a`](https://github.com/nodejs/node/commit/b71a3b363a)] - **doc**: fixup socket.remoteAddress (Arthur Gautier) [#4198](https://github.com/nodejs/node/pull/4198) * [[`e2fe214857`](https://github.com/nodejs/node/commit/e2fe214857)] - **doc**: add links and backticks around names (jpersson) [#4054](https://github.com/nodejs/node/pull/4054) * [[`bb158f8aed`](https://github.com/nodejs/node/commit/bb158f8aed)] - **doc**: s/node.js/Node.js in readme (Rod Vagg) [#3998](https://github.com/nodejs/node/pull/3998) * [[`f55491ad47`](https://github.com/nodejs/node/commit/f55491ad47)] - **doc**: move fs.existsSync() deprecation message (Martin Forsberg) [#3942](https://github.com/nodejs/node/pull/3942) * [[`8c5b847f5b`](https://github.com/nodejs/node/commit/8c5b847f5b)] - **doc**: Describe FIPSDIR environment variable (Stefan Budeanu) [#3752](https://github.com/nodejs/node/pull/3752) * [[`70c95ea0e5`](https://github.com/nodejs/node/commit/70c95ea0e5)] - **doc**: add warning about Windows process groups (Roman Klauke) [#3681](https://github.com/nodejs/node/pull/3681) * [[`46c59b7256`](https://github.com/nodejs/node/commit/46c59b7256)] - **doc**: add CTC meeting minutes 2015-10-28 (Rod Vagg) [#3661](https://github.com/nodejs/node/pull/3661) * [[`7ffd299a1d`](https://github.com/nodejs/node/commit/7ffd299a1d)] - **doc**: add final full stop in CONTRIBUTING.md (Emily Aviva Kapor-Mater) [#3576](https://github.com/nodejs/node/pull/3576) * [[`1f78bff7ce`](https://github.com/nodejs/node/commit/1f78bff7ce)] - **doc**: add TSC meeting minutes 2015-10-21 (Rod Vagg) [#3480](https://github.com/nodejs/node/pull/3480) * [[`2e623ff024`](https://github.com/nodejs/node/commit/2e623ff024)] - **doc**: add TSC meeting minutes 2015-10-14 (Rod Vagg) [#3463](https://github.com/nodejs/node/pull/3463) * [[`b9c69964bb`](https://github.com/nodejs/node/commit/b9c69964bb)] - **doc**: add TSC meeting minutes 2015-10-07 (Rod Vagg) [#3364](https://github.com/nodejs/node/pull/3364) * [[`f31d23c724`](https://github.com/nodejs/node/commit/f31d23c724)] - **doc**: add TSC meeting minutes 2015-09-30 (Rod Vagg) [#3235](https://github.com/nodejs/node/pull/3235) * [[`ae8e3af178`](https://github.com/nodejs/node/commit/ae8e3af178)] - **doc**: update irc channels: #node.js and #node-dev (Nelson Pecora) [#2743](https://github.com/nodejs/node/pull/2743) * [[`830caeb1bd`](https://github.com/nodejs/node/commit/830caeb1bd)] - **doc, test**: symbols as event names (Bryan English) [#4151](https://github.com/nodejs/node/pull/4151) * [[`82cbfcdcbe`](https://github.com/nodejs/node/commit/82cbfcdcbe)] - **docs**: update gpg key for Myles Borins (Myles Borins) [#4657](https://github.com/nodejs/node/pull/4657) * [[`50b72aa5a3`](https://github.com/nodejs/node/commit/50b72aa5a3)] - **docs**: fix npm command in releases.md (Myles Borins) [#4656](https://github.com/nodejs/node/pull/4656) * [[`5bf56882e1`](https://github.com/nodejs/node/commit/5bf56882e1)] - **fs,doc**: use `target` instead of `destination` (yorkie) [#3912](https://github.com/nodejs/node/pull/3912) * [[`41fcda840c`](https://github.com/nodejs/node/commit/41fcda840c)] - **http**: use `self.keepAlive` instead of `self.options.keepAlive` (Damian Schenkelman) [#4407](https://github.com/nodejs/node/pull/4407) * [[`3ff237333d`](https://github.com/nodejs/node/commit/3ff237333d)] - **http**: Remove an unnecessary assignment (Bo Borgerson) [#4323](https://github.com/nodejs/node/pull/4323) * [[`39dc054572`](https://github.com/nodejs/node/commit/39dc054572)] - **http**: remove excess calls to removeSocket (Dave) [#4172](https://github.com/nodejs/node/pull/4172) * [[`751fbd84dd`](https://github.com/nodejs/node/commit/751fbd84dd)] - **https**: use `servername` in agent key (Fedor Indutny) [#4389](https://github.com/nodejs/node/pull/4389) * [[`7a1a0a0055`](https://github.com/nodejs/node/commit/7a1a0a0055)] - **lib**: remove unused modules (Rich Trott) [#4683](https://github.com/nodejs/node/pull/4683) * [[`3d81ea99bb`](https://github.com/nodejs/node/commit/3d81ea99bb)] - **lib,test**: update let to const where applicable (Sakthipriyan Vairamani) [#3152](https://github.com/nodejs/node/pull/3152) * [[`8a9869eeab`](https://github.com/nodejs/node/commit/8a9869eeab)] - **module**: fix column offsets in errors (Tristian Flanagan) [#2867](https://github.com/nodejs/node/pull/2867) * [[`0ae90ecd3d`](https://github.com/nodejs/node/commit/0ae90ecd3d)] - **module,repl**: remove repl require() hack (Ben Noordhuis) [#4026](https://github.com/nodejs/node/pull/4026) * [[`a7367fdc1e`](https://github.com/nodejs/node/commit/a7367fdc1e)] - **net**: small code cleanup (Jan Schär) [#3943](https://github.com/nodejs/node/pull/3943) * [[`03e9495cc2`](https://github.com/nodejs/node/commit/03e9495cc2)] - **node**: remove unused variables in AppendExceptionLine (Yazhong Liu) [#4264](https://github.com/nodejs/node/pull/4264) * [[`06113b8711`](https://github.com/nodejs/node/commit/06113b8711)] - **node**: s/doNTCallbackX/nextTickCallbackWithXArgs/ (Rod Vagg) [#4167](https://github.com/nodejs/node/pull/4167) * [[`8ce6843fe4`](https://github.com/nodejs/node/commit/8ce6843fe4)] - **os**: fix crash in GetInterfaceAddresses (Martin Bark) [#4272](https://github.com/nodejs/node/pull/4272) * [[`53dcbb6aa4`](https://github.com/nodejs/node/commit/53dcbb6aa4)] - **repl**: remove unused function (Rich Trott) * [[`db0e906fc1`](https://github.com/nodejs/node/commit/db0e906fc1)] - **repl**: Fixed node repl history edge case. (Mudit Ameta) [#4108](https://github.com/nodejs/node/pull/4108) * [[`9855fab05f`](https://github.com/nodejs/node/commit/9855fab05f)] - **repl**: use String#repeat instead of Array#join (Evan Lucas) [#3900](https://github.com/nodejs/node/pull/3900) * [[`41882e4077`](https://github.com/nodejs/node/commit/41882e4077)] - **repl**: fix require('3rdparty') regression (Ben Noordhuis) [#4215](https://github.com/nodejs/node/pull/4215) * [[`93afc39d4a`](https://github.com/nodejs/node/commit/93afc39d4a)] - **repl**: attach location info to syntax errors (cjihrig) [#4013](https://github.com/nodejs/node/pull/4013) * [[`d4806675a6`](https://github.com/nodejs/node/commit/d4806675a6)] - **repl**: display error message when loading directory (Prince J Wesley) [#4170](https://github.com/nodejs/node/pull/4170) * [[`3080bdc7d7`](https://github.com/nodejs/node/commit/3080bdc7d7)] - **src**: define Is* util functions with macros (cjihrig) [#4118](https://github.com/nodejs/node/pull/4118) * [[`2b8a32a13b`](https://github.com/nodejs/node/commit/2b8a32a13b)] - **src**: refactor vcbuild configure args creation (Rod Vagg) [#3399](https://github.com/nodejs/node/pull/3399) * [[`d47f6ba768`](https://github.com/nodejs/node/commit/d47f6ba768)] - **src**: fix deprecation message for ErrnoException (Martin von Gagern) [#4269](https://github.com/nodejs/node/pull/4269) * [[`5ba08fbf76`](https://github.com/nodejs/node/commit/5ba08fbf76)] - **src**: fix line numbers on core errors (cjihrig) [#4254](https://github.com/nodejs/node/pull/4254) * [[`70974e9362`](https://github.com/nodejs/node/commit/70974e9362)] - **src**: use GetCurrentProcessId() for process.pid (Ben Noordhuis) [#4163](https://github.com/nodejs/node/pull/4163) * [[`c96eca164f`](https://github.com/nodejs/node/commit/c96eca164f)] - **src**: don't print garbage errors (cjihrig) [#4112](https://github.com/nodejs/node/pull/4112) * [[`f61412c753`](https://github.com/nodejs/node/commit/f61412c753)] - **test**: mark test-debug-no-context is flaky (Rich Trott) [#4421](https://github.com/nodejs/node/pull/4421) * [[`46d8c93ed2`](https://github.com/nodejs/node/commit/46d8c93ed2)] - **test**: don't use cwd for relative path (Johan Bergström) [#4477](https://github.com/nodejs/node/pull/4477) * [[`b6124ea39c`](https://github.com/nodejs/node/commit/b6124ea39c)] - **test**: write to tmp dir rather than fixture dir (Rich Trott) [#4489](https://github.com/nodejs/node/pull/4489) * [[`350fa664bb`](https://github.com/nodejs/node/commit/350fa664bb)] - **test**: don't assume a certain folder structure (Johan Bergström) [#3325](https://github.com/nodejs/node/pull/3325) * [[`6b2ef0efac`](https://github.com/nodejs/node/commit/6b2ef0efac)] - **test**: make temp path customizable (Johan Bergström) [#3325](https://github.com/nodejs/node/pull/3325) * [[`f1837703a9`](https://github.com/nodejs/node/commit/f1837703a9)] - **test**: remove unused vars from parallel tests (Rich Trott) [#4511](https://github.com/nodejs/node/pull/4511) * [[`b4964b099a`](https://github.com/nodejs/node/commit/b4964b099a)] - **test**: remove unused variables form http tests (Rich Trott) [#4422](https://github.com/nodejs/node/pull/4422) * [[`0d5a508dfb`](https://github.com/nodejs/node/commit/0d5a508dfb)] - **test**: extend timeout in Debug mode (Rich Trott) [#4431](https://github.com/nodejs/node/pull/4431) * [[`6e4598d5da`](https://github.com/nodejs/node/commit/6e4598d5da)] - **test**: remove unused variables from TLS tests (Rich Trott) [#4424](https://github.com/nodejs/node/pull/4424) * [[`7b1aa045a0`](https://github.com/nodejs/node/commit/7b1aa045a0)] - **test**: remove unused variables from HTTPS tests (Rich Trott) [#4426](https://github.com/nodejs/node/pull/4426) * [[`da9e5c1b01`](https://github.com/nodejs/node/commit/da9e5c1b01)] - **test**: remove unused variables from net tests (Rich Trott) [#4430](https://github.com/nodejs/node/pull/4430) * [[`13241bd24b`](https://github.com/nodejs/node/commit/13241bd24b)] - **test**: remove unused vars in ChildProcess tests (Rich Trott) [#4425](https://github.com/nodejs/node/pull/4425) * [[`2f4538ddda`](https://github.com/nodejs/node/commit/2f4538ddda)] - **test**: remove unused vars (Rich Trott) [#4536](https://github.com/nodejs/node/pull/4536) * [[`dffe83ccd6`](https://github.com/nodejs/node/commit/dffe83ccd6)] - **test**: remove unused modules (Rich Trott) [#4684](https://github.com/nodejs/node/pull/4684) * [[`c4eeb88ba1`](https://github.com/nodejs/node/commit/c4eeb88ba1)] - **test**: fix flaky cluster-disconnect-race (Brian White) [#4457](https://github.com/nodejs/node/pull/4457) * [[`7caf87bf6c`](https://github.com/nodejs/node/commit/7caf87bf6c)] - **test**: fix flaky test-http-agent-keepalive (Rich Trott) [#4524](https://github.com/nodejs/node/pull/4524) * [[`25c41d084d`](https://github.com/nodejs/node/commit/25c41d084d)] - **test**: remove flaky designations for tests (Rich Trott) [#4519](https://github.com/nodejs/node/pull/4519) * [[`b8f097ece2`](https://github.com/nodejs/node/commit/b8f097ece2)] - **test**: fix flaky streams test (Rich Trott) [#4516](https://github.com/nodejs/node/pull/4516) * [[`c24fa1437c`](https://github.com/nodejs/node/commit/c24fa1437c)] - **test**: inherit JOBS from environment (Johan Bergström) [#4495](https://github.com/nodejs/node/pull/4495) * [[`7dc90e9e7f`](https://github.com/nodejs/node/commit/7dc90e9e7f)] - **test**: remove time check (Rich Trott) [#4494](https://github.com/nodejs/node/pull/4494) * [[`7ca3c6c388`](https://github.com/nodejs/node/commit/7ca3c6c388)] - **test**: refactor test-fs-empty-readStream (Rich Trott) [#4490](https://github.com/nodejs/node/pull/4490) * [[`610727dea7`](https://github.com/nodejs/node/commit/610727dea7)] - **test**: clarify role of domains in test (Rich Trott) [#4474](https://github.com/nodejs/node/pull/4474) * [[`1ae0e355b9`](https://github.com/nodejs/node/commit/1ae0e355b9)] - **test**: improve assert message (Rich Trott) [#4461](https://github.com/nodejs/node/pull/4461) * [[`e70c88df56`](https://github.com/nodejs/node/commit/e70c88df56)] - **test**: remove unused assert module imports (Rich Trott) [#4438](https://github.com/nodejs/node/pull/4438) * [[`c77fc71f9b`](https://github.com/nodejs/node/commit/c77fc71f9b)] - **test**: remove unused var from test-assert.js (Rich Trott) [#4405](https://github.com/nodejs/node/pull/4405) * [[`f613b3033f`](https://github.com/nodejs/node/commit/f613b3033f)] - **test**: add test-domain-exit-dispose-again back (Julien Gilli) [#4256](https://github.com/nodejs/node/pull/4256) * [[`f5bfacd858`](https://github.com/nodejs/node/commit/f5bfacd858)] - **test**: remove unused `util` imports (Rich Trott) [#4562](https://github.com/nodejs/node/pull/4562) * [[`d795301025`](https://github.com/nodejs/node/commit/d795301025)] - **test**: remove unnecessary assignments (Rich Trott) [#4563](https://github.com/nodejs/node/pull/4563) * [[`acc3d66934`](https://github.com/nodejs/node/commit/acc3d66934)] - **test**: move ArrayStream to common (cjihrig) [#4027](https://github.com/nodejs/node/pull/4027) * [[`6c0021361c`](https://github.com/nodejs/node/commit/6c0021361c)] - **test**: refactor test-net-connect-options-ipv6 (Rich Trott) [#4395](https://github.com/nodejs/node/pull/4395) * [[`29804e00ad`](https://github.com/nodejs/node/commit/29804e00ad)] - **test**: use platformTimeout() in more places (Brian White) [#4387](https://github.com/nodejs/node/pull/4387) * [[`761af37d0e`](https://github.com/nodejs/node/commit/761af37d0e)] - **test**: fix race condition in test-http-client-onerror (Devin Nakamura) [#4346](https://github.com/nodejs/node/pull/4346) * [[`980852165f`](https://github.com/nodejs/node/commit/980852165f)] - **test**: fix flaky test-net-error-twice (Brian White) [#4342](https://github.com/nodejs/node/pull/4342) * [[`1bc44e79d3`](https://github.com/nodejs/node/commit/1bc44e79d3)] - **test**: try other ipv6 localhost alternatives (Brian White) [#4325](https://github.com/nodejs/node/pull/4325) * [[`44dbe15640`](https://github.com/nodejs/node/commit/44dbe15640)] - **test**: fix debug-port-cluster flakiness (Ben Noordhuis) [#4310](https://github.com/nodejs/node/pull/4310) * [[`73e781172b`](https://github.com/nodejs/node/commit/73e781172b)] - **test**: add test for tls.parseCertString (Evan Lucas) [#4283](https://github.com/nodejs/node/pull/4283) * [[`15c295a21b`](https://github.com/nodejs/node/commit/15c295a21b)] - **test**: use regular timeout times for ARMv8 (Jeremiah Senkpiel) [#4248](https://github.com/nodejs/node/pull/4248) * [[`fd250b8fab`](https://github.com/nodejs/node/commit/fd250b8fab)] - **test**: parallelize test-repl-persistent-history (Jeremiah Senkpiel) [#4247](https://github.com/nodejs/node/pull/4247) * [[`9a0f156e5a`](https://github.com/nodejs/node/commit/9a0f156e5a)] - **test**: fix domain-top-level-error-handler-throw (Santiago Gimeno) [#4364](https://github.com/nodejs/node/pull/4364) * [[`6bc1b1c259`](https://github.com/nodejs/node/commit/6bc1b1c259)] - **test**: don't assume openssl s_client supports -ssl3 (Ben Noordhuis) [#4204](https://github.com/nodejs/node/pull/4204) * [[`d00b9fc66f`](https://github.com/nodejs/node/commit/d00b9fc66f)] - **test**: fix tls-inception flakiness (Santiago Gimeno) [#4195](https://github.com/nodejs/node/pull/4195) * [[`c41b280a2b`](https://github.com/nodejs/node/commit/c41b280a2b)] - **test**: fix tls-inception (Santiago Gimeno) [#4195](https://github.com/nodejs/node/pull/4195) * [[`6f4ab1d1ab`](https://github.com/nodejs/node/commit/6f4ab1d1ab)] - **test**: mark test-cluster-shared-leak flaky (Rich Trott) [#4162](https://github.com/nodejs/node/pull/4162) * [[`90498e2a68`](https://github.com/nodejs/node/commit/90498e2a68)] - **test**: skip long path tests on non-Windows (Rafał Pocztarski) [#4116](https://github.com/nodejs/node/pull/4116) * [[`c9100d78f3`](https://github.com/nodejs/node/commit/c9100d78f3)] - **test**: fix flaky test-net-socket-local-address (Rich Trott) [#4109](https://github.com/nodejs/node/pull/4109) * [[`ac939d51d9`](https://github.com/nodejs/node/commit/ac939d51d9)] - **test**: improve cluster-disconnect-handles test (Brian White) [#4084](https://github.com/nodejs/node/pull/4084) * [[`22ba1b4115`](https://github.com/nodejs/node/commit/22ba1b4115)] - **test**: eliminate multicast test FreeBSD flakiness (Rich Trott) [#4042](https://github.com/nodejs/node/pull/4042) * [[`2ee7853bb7`](https://github.com/nodejs/node/commit/2ee7853bb7)] - **test**: fix http-many-ended-pipelines flakiness (Santiago Gimeno) [#4041](https://github.com/nodejs/node/pull/4041) * [[`a77dcfec06`](https://github.com/nodejs/node/commit/a77dcfec06)] - **test**: use platform-based timeout for reliability (Rich Trott) [#4015](https://github.com/nodejs/node/pull/4015) * [[`3f0ff879cf`](https://github.com/nodejs/node/commit/3f0ff879cf)] - **test**: fix time resolution constraint (Gireesh Punathil) [#3981](https://github.com/nodejs/node/pull/3981) * [[`22b88e1c48`](https://github.com/nodejs/node/commit/22b88e1c48)] - **test**: add TAP diagnostic message for retried tests (Rich Trott) [#3960](https://github.com/nodejs/node/pull/3960) * [[`22d2887b1c`](https://github.com/nodejs/node/commit/22d2887b1c)] - **test**: add OS X to module loading error test (Evan Lucas) [#3901](https://github.com/nodejs/node/pull/3901) * [[`e2141cb75e`](https://github.com/nodejs/node/commit/e2141cb75e)] - **test**: skip instead of fail when mem constrained (Michael Cornacchia) [#3697](https://github.com/nodejs/node/pull/3697) * [[`166523d0ed`](https://github.com/nodejs/node/commit/166523d0ed)] - **test**: fix race condition in unrefd interval test (Michael Cornacchia) [#3550](https://github.com/nodejs/node/pull/3550) * [[`86b47e8dc0`](https://github.com/nodejs/node/commit/86b47e8dc0)] - **timers**: optimize callback call: bind -> arrow (Andrei Sedoi) [#4038](https://github.com/nodejs/node/pull/4038) * [[`4d37472ea7`](https://github.com/nodejs/node/commit/4d37472ea7)] - **tls_wrap**: clear errors on return (Fedor Indutny) [#4709](https://github.com/nodejs/node/pull/4709) * [[`5b695d0343`](https://github.com/nodejs/node/commit/5b695d0343)] - **tls_wrap**: inherit from the `AsyncWrap` first (Fedor Indutny) [#4268](https://github.com/nodejs/node/pull/4268) * [[`0efc35e6d8`](https://github.com/nodejs/node/commit/0efc35e6d8)] - **tls_wrap**: slice buffer properly in `ClearOut` (Fedor Indutny) [#4184](https://github.com/nodejs/node/pull/4184) * [[`628cb8657c`](https://github.com/nodejs/node/commit/628cb8657c)] - **tools**: add .editorconfig (ronkorving) [#2993](https://github.com/nodejs/node/pull/2993) * [[`69fef19624`](https://github.com/nodejs/node/commit/69fef19624)] - **tools**: implement no-unused-vars for eslint (Rich Trott) [#4536](https://github.com/nodejs/node/pull/4536) * [[`3ee16706f2`](https://github.com/nodejs/node/commit/3ee16706f2)] - **tools**: enforce `throw new Error()` with lint rule (Rich Trott) [#3714](https://github.com/nodejs/node/pull/3714) * [[`32801de4ef`](https://github.com/nodejs/node/commit/32801de4ef)] - **tools**: Use `throw new Error()` consistently (Rich Trott) [#3714](https://github.com/nodejs/node/pull/3714) * [[`f413fae0cd`](https://github.com/nodejs/node/commit/f413fae0cd)] - **tools**: add tap output to cpplint (Johan Bergström) [#3448](https://github.com/nodejs/node/pull/3448) * [[`efa30dd2f0`](https://github.com/nodejs/node/commit/efa30dd2f0)] - **tools**: enable prefer-const eslint rule (Sakthipriyan Vairamani) [#3152](https://github.com/nodejs/node/pull/3152) * [[`dd0c925896`](https://github.com/nodejs/node/commit/dd0c925896)] - **udp**: remove a needless instanceof Buffer check (ronkorving) [#4301](https://github.com/nodejs/node/pull/4301) * [[`f4414102ed`](https://github.com/nodejs/node/commit/f4414102ed)] - **util**: faster arrayToHash (Jackson Tian) * [[`b421119984`](https://github.com/nodejs/node/commit/b421119984)] - **util**: determine object types in C++ (cjihrig) [#4100](https://github.com/nodejs/node/pull/4100) * [[`6a7c9d9293`](https://github.com/nodejs/node/commit/6a7c9d9293)] - **util**: move .decorateErrorStack to internal/util (Ben Noordhuis) [#4026](https://github.com/nodejs/node/pull/4026) * [[`422a865d46`](https://github.com/nodejs/node/commit/422a865d46)] - **util**: add decorateErrorStack() (cjihrig) [#4013](https://github.com/nodejs/node/pull/4013) * [[`2d5380ea25`](https://github.com/nodejs/node/commit/2d5380ea25)] - **util**: fix constructor/instanceof checks (Brian White) [#3385](https://github.com/nodejs/node/pull/3385) * [[`1bf84b9d41`](https://github.com/nodejs/node/commit/1bf84b9d41)] - **util,src**: allow lookup of hidden values (cjihrig) [#3988](https://github.com/nodejs/node/pull/3988) ## 2015-12-23, Version 4.2.4 'Argon' (LTS), @jasnell Maintenance update. ### Notable changes * Roughly 78% of the commits are documentation and test improvements * **domains**: ** Fix handling of uncaught exceptions (Julien Gilli) [#3884](https://github.com/nodejs/node/pull/3884) * **deps**: ** Upgrade to npm 2.14.12 (Kat Marchán) [#4110](https://github.com/nodejs/node/pull/4110) ** Backport 819b40a from V8 upstream (Michaël Zasso) [#3938](https://github.com/nodejs/node/pull/3938) ** Updated node LICENSE file with new npm license (Kat Marchán) [#4110](https://github.com/nodejs/node/pull/4110) ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`907a13a07f`](https://github.com/nodejs/node/commit/907a13a07f)] - Add missing va_end before return (Ömer Fadıl Usta) [#3565](https://github.com/nodejs/node/pull/3565) * [[`7ffc01756f`](https://github.com/nodejs/node/commit/7ffc01756f)] - **buffer**: fix writeInt{B,L}E for some neg values (Peter A. Bigot) [#3994](https://github.com/nodejs/node/pull/3994) * [[`db0186e435`](https://github.com/nodejs/node/commit/db0186e435)] - **buffer**: let WriteFloatGeneric silently drop values (P.S.V.R) * [[`5c6740865a`](https://github.com/nodejs/node/commit/5c6740865a)] - **build**: update signtool description, add url (Rod Vagg) [#4011](https://github.com/nodejs/node/pull/4011) * [[`60dda70f89`](https://github.com/nodejs/node/commit/60dda70f89)] - **build**: fix --with-intl=system-icu for x-compile (Steven R. Loomis) [#3808](https://github.com/nodejs/node/pull/3808) * [[`22208b067c`](https://github.com/nodejs/node/commit/22208b067c)] - **build**: fix configuring with prebuilt libraries (Markus Tzoe) [#3135](https://github.com/nodejs/node/pull/3135) * [[`914caf9c69`](https://github.com/nodejs/node/commit/914caf9c69)] - **child_process**: add safety checks on stdio access (cjihrig) [#3799](https://github.com/nodejs/node/pull/3799) * [[`236ad90a84`](https://github.com/nodejs/node/commit/236ad90a84)] - **child_process**: don't fork bomb ourselves from -e (Ben Noordhuis) [#3575](https://github.com/nodejs/node/pull/3575) * [[`f28f69dac4`](https://github.com/nodejs/node/commit/f28f69dac4)] - **cluster**: remove handles when disconnecting worker (Ben Noordhuis) [#3677](https://github.com/nodejs/node/pull/3677) * [[`f5c5e8bf91`](https://github.com/nodejs/node/commit/f5c5e8bf91)] - **cluster**: send suicide message on disconnect (cjihrig) [#3720](https://github.com/nodejs/node/pull/3720) * [[`629d5d18d7`](https://github.com/nodejs/node/commit/629d5d18d7)] - **configure**: `v8_use_snapshot` should be `true` (Fedor Indutny) [#3962](https://github.com/nodejs/node/pull/3962) * [[`3094464871`](https://github.com/nodejs/node/commit/3094464871)] - **configure**: use __ARM_ARCH to determine arm version (João Reis) [#4123](https://github.com/nodejs/node/pull/4123) * [[`1e1173fc5c`](https://github.com/nodejs/node/commit/1e1173fc5c)] - **configure**: respect CC_host in host arch detection (João Reis) [#4117](https://github.com/nodejs/node/pull/4117) * [[`2e9b886fbf`](https://github.com/nodejs/node/commit/2e9b886fbf)] - **crypto**: DSA parameter validation in FIPS mode (Stefan Budeanu) [#3756](https://github.com/nodejs/node/pull/3756) * [[`00b77d9e84`](https://github.com/nodejs/node/commit/00b77d9e84)] - **crypto**: Improve error checking and reporting (Stefan Budeanu) [#3753](https://github.com/nodejs/node/pull/3753) * [[`3dd90ddc73`](https://github.com/nodejs/node/commit/3dd90ddc73)] - **deps**: upgrade to npm 2.14.12 (Kat Marchán) [#4110](https://github.com/nodejs/node/pull/4110) * [[`51ae8d10b3`](https://github.com/nodejs/node/commit/51ae8d10b3)] - **deps**: Updated node LICENSE file with new npm license (Kat Marchán) [#4110](https://github.com/nodejs/node/pull/4110) * [[`9e1edead22`](https://github.com/nodejs/node/commit/9e1edead22)] - **deps**: backport 819b40a from V8 upstream (Michaël Zasso) [#3938](https://github.com/nodejs/node/pull/3938) * [[`a2ce3843cc`](https://github.com/nodejs/node/commit/a2ce3843cc)] - **deps**: upgrade npm to 2.14.9 (Forrest L Norvell) [#3686](https://github.com/nodejs/node/pull/3686) * [[`b140cb29f4`](https://github.com/nodejs/node/commit/b140cb29f4)] - **dns**: prevent undefined values in results (Junliang Yan) [#3696](https://github.com/nodejs/node/pull/3696) * [[`8aafa2ecc0`](https://github.com/nodejs/node/commit/8aafa2ecc0)] - **doc**: standardize references to node.js in docs (Scott Buchanan) [#4136](https://github.com/nodejs/node/pull/4136) * [[`72f43a263a`](https://github.com/nodejs/node/commit/72f43a263a)] - **doc**: fix internal link to child.send() (Luigi Pinca) [#4089](https://github.com/nodejs/node/pull/4089) * [[`dcfdbac457`](https://github.com/nodejs/node/commit/dcfdbac457)] - **doc**: reword https.Agent example text (Jan Krems) [#4075](https://github.com/nodejs/node/pull/4075) * [[`f93d268dec`](https://github.com/nodejs/node/commit/f93d268dec)] - **doc**: add HTTP working group (James M Snell) [#3919](https://github.com/nodejs/node/pull/3919) * [[`beee0553ca`](https://github.com/nodejs/node/commit/beee0553ca)] - **doc**: update WORKING_GROUPS.md - add missing groups (Michael Dawson) [#3450](https://github.com/nodejs/node/pull/3450) * [[`3327415fc4`](https://github.com/nodejs/node/commit/3327415fc4)] - **doc**: fix the exception description (yorkie) [#3658](https://github.com/nodejs/node/pull/3658) * [[`da8d012c88`](https://github.com/nodejs/node/commit/da8d012c88)] - **doc**: clarify v4.2.3 notable items (Rod Vagg) [#4155](https://github.com/nodejs/node/pull/4155) * [[`44a2d8ca24`](https://github.com/nodejs/node/commit/44a2d8ca24)] - **doc**: fix color of linked code blocks (jpersson) [#4068](https://github.com/nodejs/node/pull/4068) * [[`bebde48ebc`](https://github.com/nodejs/node/commit/bebde48ebc)] - **doc**: fix typo in README (Rich Trott) [#4000](https://github.com/nodejs/node/pull/4000) * [[`b48d5ec301`](https://github.com/nodejs/node/commit/b48d5ec301)] - **doc**: message.header duplication correction (Bryan English) [#3997](https://github.com/nodejs/node/pull/3997) * [[`6ef3625456`](https://github.com/nodejs/node/commit/6ef3625456)] - **doc**: replace sane with reasonable (Lewis Cowper) [#3980](https://github.com/nodejs/node/pull/3980) * [[`c5be3c63f0`](https://github.com/nodejs/node/commit/c5be3c63f0)] - **doc**: fix rare case of misaligned columns (Roman Reiss) [#3948](https://github.com/nodejs/node/pull/3948) * [[`bd82fb06ff`](https://github.com/nodejs/node/commit/bd82fb06ff)] - **doc**: fix broken references (Alexander Gromnitsky) [#3944](https://github.com/nodejs/node/pull/3944) * [[`8eb28c3d50`](https://github.com/nodejs/node/commit/8eb28c3d50)] - **doc**: add reference for buffer.inspect() (cjihrig) [#3921](https://github.com/nodejs/node/pull/3921) * [[`4bc71e0078`](https://github.com/nodejs/node/commit/4bc71e0078)] - **doc**: clarify module loading behavior (cjihrig) [#3920](https://github.com/nodejs/node/pull/3920) * [[`4c382e7aaa`](https://github.com/nodejs/node/commit/4c382e7aaa)] - **doc**: numeric flags to fs.open (Carl Lei) [#3641](https://github.com/nodejs/node/pull/3641) * [[`5207099dc9`](https://github.com/nodejs/node/commit/5207099dc9)] - **doc**: clarify that fs streams expect blocking fd (Carl Lei) [#3641](https://github.com/nodejs/node/pull/3641) * [[`753c5071ea`](https://github.com/nodejs/node/commit/753c5071ea)] - **doc**: Adding best practises for crypto.pbkdf2 (Tom Gallacher) [#3290](https://github.com/nodejs/node/pull/3290) * [[`8f0291beba`](https://github.com/nodejs/node/commit/8f0291beba)] - **doc**: update WORKING_GROUPS.md to include Intl (Steven R. Loomis) [#3251](https://github.com/nodejs/node/pull/3251) * [[`c31d472487`](https://github.com/nodejs/node/commit/c31d472487)] - **doc**: sort repl alphabetically (Tristian Flanagan) [#3859](https://github.com/nodejs/node/pull/3859) * [[`6b172d9fe8`](https://github.com/nodejs/node/commit/6b172d9fe8)] - **doc**: consistent reference-style links (Bryan English) [#3845](https://github.com/nodejs/node/pull/3845) * [[`ffd3335e29`](https://github.com/nodejs/node/commit/ffd3335e29)] - **doc**: address use of profanity in code of conduct (James M Snell) [#3827](https://github.com/nodejs/node/pull/3827) * [[`a36a5b63cf`](https://github.com/nodejs/node/commit/a36a5b63cf)] - **doc**: reword message.headers to indicate they are not read-only (Tristian Flanagan) [#3814](https://github.com/nodejs/node/pull/3814) * [[`6de77cd320`](https://github.com/nodejs/node/commit/6de77cd320)] - **doc**: clarify duplicate header handling (Bryan English) [#3810](https://github.com/nodejs/node/pull/3810) * [[`b22973af81`](https://github.com/nodejs/node/commit/b22973af81)] - **doc**: replace head of readme with updated text (Rod Vagg) [#3482](https://github.com/nodejs/node/pull/3482) * [[`eab0d56ea9`](https://github.com/nodejs/node/commit/eab0d56ea9)] - **doc**: repl: add defineComand and displayPrompt (Bryan English) [#3765](https://github.com/nodejs/node/pull/3765) * [[`15fb02985f`](https://github.com/nodejs/node/commit/15fb02985f)] - **doc**: document release types in readme (Rod Vagg) [#3482](https://github.com/nodejs/node/pull/3482) * [[`29f26b882f`](https://github.com/nodejs/node/commit/29f26b882f)] - **doc**: add link to \[customizing util.inspect colors\]. (Jesse McCarthy) [#3749](https://github.com/nodejs/node/pull/3749) * [[`90fdb4f7b3`](https://github.com/nodejs/node/commit/90fdb4f7b3)] - **doc**: sort tls alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`39fa9fa85c`](https://github.com/nodejs/node/commit/39fa9fa85c)] - **doc**: sort stream alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`e98e8afb2b`](https://github.com/nodejs/node/commit/e98e8afb2b)] - **doc**: sort net alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`6de887483d`](https://github.com/nodejs/node/commit/6de887483d)] - **doc**: sort process alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`37033dcb71`](https://github.com/nodejs/node/commit/37033dcb71)] - **doc**: sort zlib alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`9878034567`](https://github.com/nodejs/node/commit/9878034567)] - **doc**: sort util alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`48fc765eb6`](https://github.com/nodejs/node/commit/48fc765eb6)] - **doc**: sort https alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`3546eb4f40`](https://github.com/nodejs/node/commit/3546eb4f40)] - **doc**: sort http alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`dedfb1156a`](https://github.com/nodejs/node/commit/dedfb1156a)] - **doc**: sort modules alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`71722fe1a1`](https://github.com/nodejs/node/commit/71722fe1a1)] - **doc**: sort readline alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`660062bf9e`](https://github.com/nodejs/node/commit/660062bf9e)] - **doc**: sort repl alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`34b8d28725`](https://github.com/nodejs/node/commit/34b8d28725)] - **doc**: sort string_decoder alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`3f3b9ed7d7`](https://github.com/nodejs/node/commit/3f3b9ed7d7)] - **doc**: sort timers alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`af876ddc64`](https://github.com/nodejs/node/commit/af876ddc64)] - **doc**: sort tty alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`3c2068704a`](https://github.com/nodejs/node/commit/3c2068704a)] - **doc**: sort url alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`363692fd0c`](https://github.com/nodejs/node/commit/363692fd0c)] - **doc**: sort vm alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`ca41b55166`](https://github.com/nodejs/node/commit/ca41b55166)] - **doc**: sort querystring alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`f37ff22b9f`](https://github.com/nodejs/node/commit/f37ff22b9f)] - **doc**: sort punycode alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`4d569607af`](https://github.com/nodejs/node/commit/4d569607af)] - **doc**: sort path alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`daa62447d1`](https://github.com/nodejs/node/commit/daa62447d1)] - **doc**: sort os alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`0906f9a8bb`](https://github.com/nodejs/node/commit/0906f9a8bb)] - **doc**: sort globals alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`6cd06c1319`](https://github.com/nodejs/node/commit/6cd06c1319)] - **doc**: sort fs alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`5b310f8d9e`](https://github.com/nodejs/node/commit/5b310f8d9e)] - **doc**: sort events alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`782cb7d15b`](https://github.com/nodejs/node/commit/782cb7d15b)] - **doc**: sort errors alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`c39eabbec4`](https://github.com/nodejs/node/commit/c39eabbec4)] - **doc**: sort dgram alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`261e0f3a21`](https://github.com/nodejs/node/commit/261e0f3a21)] - **doc**: sort crypto alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`0e6121d04d`](https://github.com/nodejs/node/commit/0e6121d04d)] - **doc**: sort dns alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`435ffb79f7`](https://github.com/nodejs/node/commit/435ffb79f7)] - **doc**: sort console alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`28935a10d6`](https://github.com/nodejs/node/commit/28935a10d6)] - **doc**: sort cluster alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`5e79dc4406`](https://github.com/nodejs/node/commit/5e79dc4406)] - **doc**: sort child_process alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`af0bf1a72c`](https://github.com/nodejs/node/commit/af0bf1a72c)] - **doc**: sort buffer alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`f43a0330aa`](https://github.com/nodejs/node/commit/f43a0330aa)] - **doc**: sort assert alphabetically (Tristian Flanagan) [#3662](https://github.com/nodejs/node/pull/3662) * [[`1bbc3b3ff8`](https://github.com/nodejs/node/commit/1bbc3b3ff8)] - **doc**: add note on tls connection meta data methods (Tyler Henkel) [#3746](https://github.com/nodejs/node/pull/3746) * [[`3c415bbb12`](https://github.com/nodejs/node/commit/3c415bbb12)] - **doc**: add note to util.isBuffer (Evan Lucas) [#3790](https://github.com/nodejs/node/pull/3790) * [[`7b5e4574fd`](https://github.com/nodejs/node/commit/7b5e4574fd)] - **doc**: add romankl to collaborators (Roman Klauke) [#3725](https://github.com/nodejs/node/pull/3725) * [[`4f7c638a7a`](https://github.com/nodejs/node/commit/4f7c638a7a)] - **doc**: add saghul as a collaborator (Saúl Ibarra Corretgé) * [[`523251270a`](https://github.com/nodejs/node/commit/523251270a)] - **doc**: add thealphanerd to collaborators (Myles Borins) [#3723](https://github.com/nodejs/node/pull/3723) * [[`488e74f27d`](https://github.com/nodejs/node/commit/488e74f27d)] - **doc**: update lts description in the collaborator guide (James M Snell) [#3668](https://github.com/nodejs/node/pull/3668) * [[`fe3ae3cea4`](https://github.com/nodejs/node/commit/fe3ae3cea4)] - **doc**: add LTS info to COLLABORATOR_GUIDE.md (Myles Borins) [#3442](https://github.com/nodejs/node/pull/3442) * [[`daa10a345e`](https://github.com/nodejs/node/commit/daa10a345e)] - **doc**: typo fix in readme.md (Sam P Gallagher-Bishop) [#3649](https://github.com/nodejs/node/pull/3649) * [[`eca5720761`](https://github.com/nodejs/node/commit/eca5720761)] - **doc**: fix wrong date and known issue in changelog.md (James M Snell) [#3650](https://github.com/nodejs/node/pull/3650) * [[`83494f8f3e`](https://github.com/nodejs/node/commit/83494f8f3e)] - **doc**: rename iojs-* groups to nodejs-* (Steven R. Loomis) [#3634](https://github.com/nodejs/node/pull/3634) * [[`347fb65aee`](https://github.com/nodejs/node/commit/347fb65aee)] - **doc**: fix crypto spkac function descriptions (Jason Gerfen) [#3614](https://github.com/nodejs/node/pull/3614) * [[`11d2050d63`](https://github.com/nodejs/node/commit/11d2050d63)] - **doc**: Updated streams simplified constructor API (Tom Gallacher) [#3602](https://github.com/nodejs/node/pull/3602) * [[`6db4392bfb`](https://github.com/nodejs/node/commit/6db4392bfb)] - **doc**: made code spans more visible in the API docs (phijohns) [#3573](https://github.com/nodejs/node/pull/3573) * [[`8a7dd73af1`](https://github.com/nodejs/node/commit/8a7dd73af1)] - **doc**: added what buf.copy returns (Manuel B) [#3555](https://github.com/nodejs/node/pull/3555) * [[`cf4b65c2d6`](https://github.com/nodejs/node/commit/cf4b65c2d6)] - **doc**: fix function param order in assert doc (David Woods) [#3533](https://github.com/nodejs/node/pull/3533) * [[`a2efe4c72b`](https://github.com/nodejs/node/commit/a2efe4c72b)] - **doc**: add note about timeout delay > TIMEOUT_MAX (Guilherme Souza) [#3512](https://github.com/nodejs/node/pull/3512) * [[`d1b5833476`](https://github.com/nodejs/node/commit/d1b5833476)] - **doc**: add caveats of algs and key size in crypto (Shigeki Ohtsu) [#3479](https://github.com/nodejs/node/pull/3479) * [[`12cdf6fcf3`](https://github.com/nodejs/node/commit/12cdf6fcf3)] - **doc**: add method links in events.markdown (Alejandro Oviedo) [#3187](https://github.com/nodejs/node/pull/3187) * [[`f50f19e384`](https://github.com/nodejs/node/commit/f50f19e384)] - **doc**: stdout/stderr can block when directed to file (Ben Noordhuis) [#3170](https://github.com/nodejs/node/pull/3170) * [[`b2cc1302e0`](https://github.com/nodejs/node/commit/b2cc1302e0)] - **docs**: improve discoverability of Code of Conduct (Ashley Williams) [#3774](https://github.com/nodejs/node/pull/3774) * [[`fa1ab497f1`](https://github.com/nodejs/node/commit/fa1ab497f1)] - **docs**: fs - change links to buffer encoding to Buffer class anchor (fansworld-claudio) [#2796](https://github.com/nodejs/node/pull/2796) * [[`34e64e5390`](https://github.com/nodejs/node/commit/34e64e5390)] - **domains**: fix handling of uncaught exceptions (Julien Gilli) [#3884](https://github.com/nodejs/node/pull/3884) * [[`0311836e7a`](https://github.com/nodejs/node/commit/0311836e7a)] - **meta**: remove use of profanity in source (Myles Borins) [#4122](https://github.com/nodejs/node/pull/4122) * [[`971762ada9`](https://github.com/nodejs/node/commit/971762ada9)] - **module**: cache regular expressions (Evan Lucas) [#3869](https://github.com/nodejs/node/pull/3869) * [[`d80fa2c77c`](https://github.com/nodejs/node/commit/d80fa2c77c)] - **module**: remove unnecessary JSON.stringify (Andres Suarez) [#3578](https://github.com/nodejs/node/pull/3578) * [[`aa85d62f09`](https://github.com/nodejs/node/commit/aa85d62f09)] - **net**: add local address/port for better errors (Jan Schär) [#3946](https://github.com/nodejs/node/pull/3946) * [[`803a56de52`](https://github.com/nodejs/node/commit/803a56de52)] - **querystring**: Parse multiple separator characters (Yosuke Furukawa) [#3807](https://github.com/nodejs/node/pull/3807) * [[`ff02b295fc`](https://github.com/nodejs/node/commit/ff02b295fc)] - **repl**: don't crash if cannot open history file (Evan Lucas) [#3630](https://github.com/nodejs/node/pull/3630) * [[`329e88e545`](https://github.com/nodejs/node/commit/329e88e545)] - **repl**: To exit, press ^C again or type .exit. (Hemanth.HM) [#3368](https://github.com/nodejs/node/pull/3368) * [[`9b05905361`](https://github.com/nodejs/node/commit/9b05905361)] - **src**: Revert "nix stdin _readableState.reading" (Roman Reiss) [#3490](https://github.com/nodejs/node/pull/3490) * [[`957c1f2543`](https://github.com/nodejs/node/commit/957c1f2543)] - **stream_wrap**: error if stream has StringDecoder (Fedor Indutny) [#4031](https://github.com/nodejs/node/pull/4031) * [[`43e3b69dae`](https://github.com/nodejs/node/commit/43e3b69dae)] - **test**: refactor test-http-exit-delay (Rich Trott) [#4055](https://github.com/nodejs/node/pull/4055) * [[`541d0d21be`](https://github.com/nodejs/node/commit/541d0d21be)] - **test**: fix cluster-disconnect-handles flakiness (Santiago Gimeno) [#4009](https://github.com/nodejs/node/pull/4009) * [[`5f66d66e84`](https://github.com/nodejs/node/commit/5f66d66e84)] - **test**: don't check the # of chunks in test-http-1.0 (Santiago Gimeno) [#3961](https://github.com/nodejs/node/pull/3961) * [[`355edf585b`](https://github.com/nodejs/node/commit/355edf585b)] - **test**: fix cluster-worker-isdead (Santiago Gimeno) [#3954](https://github.com/nodejs/node/pull/3954) * [[`4e46e04002`](https://github.com/nodejs/node/commit/4e46e04002)] - **test**: add test for repl.defineCommand() (Bryan English) [#3908](https://github.com/nodejs/node/pull/3908) * [[`4ea1a69c53`](https://github.com/nodejs/node/commit/4ea1a69c53)] - **test**: mark test flaky on FreeBSD (Rich Trott) [#4016](https://github.com/nodejs/node/pull/4016) * [[`05b64c11f5`](https://github.com/nodejs/node/commit/05b64c11f5)] - **test**: mark cluster-net-send test flaky on windows (Rich Trott) [#4006](https://github.com/nodejs/node/pull/4006) * [[`695015579b`](https://github.com/nodejs/node/commit/695015579b)] - **test**: remove flaky designation from ls-no-sslv3 (Rich Trott) [#3620](https://github.com/nodejs/node/pull/3620) * [[`abbd87b273`](https://github.com/nodejs/node/commit/abbd87b273)] - **test**: mark fork regression test flaky on windows (Rich Trott) [#4005](https://github.com/nodejs/node/pull/4005) * [[`38ba152a7a`](https://github.com/nodejs/node/commit/38ba152a7a)] - **test**: skip test if in FreeBSD jail (Rich Trott) [#3995](https://github.com/nodejs/node/pull/3995) * [[`cc24f0ea58`](https://github.com/nodejs/node/commit/cc24f0ea58)] - **test**: fix test-domain-exit-dispose-again (Julien Gilli) [#3990](https://github.com/nodejs/node/pull/3990) * [[`b2f1014d26`](https://github.com/nodejs/node/commit/b2f1014d26)] - **test**: remove flaky status for cluster test (Rich Trott) [#3975](https://github.com/nodejs/node/pull/3975) * [[`e66794fd30`](https://github.com/nodejs/node/commit/e66794fd30)] - **test**: address flaky test-http-client-timeout-event (Rich Trott) [#3968](https://github.com/nodejs/node/pull/3968) * [[`5a2727421a`](https://github.com/nodejs/node/commit/5a2727421a)] - **test**: retry on smartos if ECONNREFUSED (Rich Trott) [#3941](https://github.com/nodejs/node/pull/3941) * [[`dbc85a275c`](https://github.com/nodejs/node/commit/dbc85a275c)] - **test**: avoid test timeouts on rpi (Stefan Budeanu) [#3902](https://github.com/nodejs/node/pull/3902) * [[`b9d7378d20`](https://github.com/nodejs/node/commit/b9d7378d20)] - **test**: fix flaky test-child-process-spawnsync-input (Rich Trott) [#3889](https://github.com/nodejs/node/pull/3889) * [[`cca216a034`](https://github.com/nodejs/node/commit/cca216a034)] - **test**: move test-specific function out of common (Rich Trott) [#3871](https://github.com/nodejs/node/pull/3871) * [[`fb8df8d6c2`](https://github.com/nodejs/node/commit/fb8df8d6c2)] - **test**: module loading error fix solaris #3798 (fansworld-claudio) [#3855](https://github.com/nodejs/node/pull/3855) * [[`9ea6bc1e0f`](https://github.com/nodejs/node/commit/9ea6bc1e0f)] - **test**: skip test if FreeBSD jail will break it (Rich Trott) [#3839](https://github.com/nodejs/node/pull/3839) * [[`150f126618`](https://github.com/nodejs/node/commit/150f126618)] - **test**: fix flaky SmartOS test (Rich Trott) [#3830](https://github.com/nodejs/node/pull/3830) * [[`603a6f5405`](https://github.com/nodejs/node/commit/603a6f5405)] - **test**: run pipeline flood test in parallel (Rich Trott) [#3811](https://github.com/nodejs/node/pull/3811) * [[`4a26f74ee3`](https://github.com/nodejs/node/commit/4a26f74ee3)] - **test**: skip/replace weak crypto tests in FIPS mode (Stefan Budeanu) [#3757](https://github.com/nodejs/node/pull/3757) * [[`3f9562b6bd`](https://github.com/nodejs/node/commit/3f9562b6bd)] - **test**: stronger crypto in test fixtures (Stefan Budeanu) [#3759](https://github.com/nodejs/node/pull/3759) * [[`1f83eebec5`](https://github.com/nodejs/node/commit/1f83eebec5)] - **test**: increase crypto strength for FIPS standard (Stefan Budeanu) [#3758](https://github.com/nodejs/node/pull/3758) * [[`7c5fbf7850`](https://github.com/nodejs/node/commit/7c5fbf7850)] - **test**: add hasFipsCrypto to test/common.js (Stefan Budeanu) [#3756](https://github.com/nodejs/node/pull/3756) * [[`f30214f135`](https://github.com/nodejs/node/commit/f30214f135)] - **test**: add test for invalid DSA key size (Stefan Budeanu) [#3756](https://github.com/nodejs/node/pull/3756) * [[`9a6c9faafb`](https://github.com/nodejs/node/commit/9a6c9faafb)] - **test**: numeric flags to fs.open (Carl Lei) [#3641](https://github.com/nodejs/node/pull/3641) * [[`93d1d3cfcd`](https://github.com/nodejs/node/commit/93d1d3cfcd)] - **test**: refactor test-http-pipeline-flood (Rich Trott) [#3636](https://github.com/nodejs/node/pull/3636) * [[`6c23f67504`](https://github.com/nodejs/node/commit/6c23f67504)] - **test**: fix flaky test test-http-pipeline-flood (Devin Nakamura) [#3636](https://github.com/nodejs/node/pull/3636) * [[`4e5cae4360`](https://github.com/nodejs/node/commit/4e5cae4360)] - **test**: use really invalid hostname (Sakthipriyan Vairamani) [#3711](https://github.com/nodejs/node/pull/3711) * [[`da189f793b`](https://github.com/nodejs/node/commit/da189f793b)] - **test**: Fix test-cluster-worker-exit.js for AIX (Imran Iqbal) [#3666](https://github.com/nodejs/node/pull/3666) * [[`7b4194a863`](https://github.com/nodejs/node/commit/7b4194a863)] - **test**: fix test-module-loading-error for musl (Hugues Malphettes) [#3657](https://github.com/nodejs/node/pull/3657) * [[`3dc52e99df`](https://github.com/nodejs/node/commit/3dc52e99df)] - **test**: fix test-net-persistent-keepalive for AIX (Imran Iqbal) [#3646](https://github.com/nodejs/node/pull/3646) * [[`0e8eb66a78`](https://github.com/nodejs/node/commit/0e8eb66a78)] - **test**: fix path to module for repl test on Windows (Michael Cornacchia) [#3608](https://github.com/nodejs/node/pull/3608) * [[`3aecbc86d2`](https://github.com/nodejs/node/commit/3aecbc86d2)] - **test**: add test-zlib-flush-drain (Myles Borins) [#3534](https://github.com/nodejs/node/pull/3534) * [[`542d05cbe1`](https://github.com/nodejs/node/commit/542d05cbe1)] - **test**: enhance fs-watch-recursive test (Sakthipriyan Vairamani) [#2599](https://github.com/nodejs/node/pull/2599) * [[`0eb0119d64`](https://github.com/nodejs/node/commit/0eb0119d64)] - **tls**: Use SHA1 for sessionIdContext in FIPS mode (Stefan Budeanu) [#3755](https://github.com/nodejs/node/pull/3755) * [[`c10c08604c`](https://github.com/nodejs/node/commit/c10c08604c)] - **tls**: remove util and calls to util.format (Myles Borins) [#3456](https://github.com/nodejs/node/pull/3456) * [[`a558a570c0`](https://github.com/nodejs/node/commit/a558a570c0)] - **util**: use regexp instead of str.replace().join() (qinjia) [#3689](https://github.com/nodejs/node/pull/3689) * [[`47bb94a0c3`](https://github.com/nodejs/node/commit/47bb94a0c3)] - **zlib**: only apply drain listener if given callback (Craig Cavalier) [#3534](https://github.com/nodejs/node/pull/3534) * [[`4733a60158`](https://github.com/nodejs/node/commit/4733a60158)] - **zlib**: pass kind to recursive calls to flush (Myles Borins) [#3534](https://github.com/nodejs/node/pull/3534) ## 2015-12-04, Version 4.2.3 'Argon' (LTS), @rvagg Security Update ### Notable changes * **http**: Fix CVE-2015-8027, a bug whereby an HTTP socket may no longer have a parser associated with it but a pipelined request attempts to trigger a pause or resume on the non-existent parser, a potential denial-of-service vulnerability. (Fedor Indutny) * **openssl**: Upgrade to 1.0.2e, containing fixes for: - CVE-2015-3193 "BN_mod_exp may produce incorrect results on x86_64", an attack may be possible against a Node.js TLS server using DHE key exchange. Details are available at . - CVE-2015-3194 "Certificate verify crash with missing PSS parameter", a potential denial-of-service vector for Node.js TLS servers using client certificate authentication; TLS clients are also impacted. Details are available at . (Shigeki Ohtsu) [#4134](https://github.com/nodejs/node/pull/4134) * **v8**: Backport fix for CVE-2015-6764, a bug in `JSON.stringify()` that can result in out-of-bounds reads for arrays. (Ben Noordhuis) ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`49bbd563be`](https://github.com/nodejs/node/commit/49bbd563be)] - **deps**: upgrade openssl sources to 1.0.2e (Shigeki Ohtsu) [#4134](https://github.com/nodejs/node/pull/4134) * [[`9a063fd492`](https://github.com/nodejs/node/commit/9a063fd492)] - **deps**: backport a7e50a5 from upstream v8 (Ben Noordhuis) * [[`07233206e9`](https://github.com/nodejs/node/commit/07233206e9)] - **deps**: backport 6df9a1d from upstream v8 (Ben Noordhuis) * [[`1c8e6de78e`](https://github.com/nodejs/node/commit/1c8e6de78e)] - **http**: fix pipeline regression (Fedor Indutny) ## 2015-11-03, Version 4.2.2 'Argon' (LTS), @jasnell ### Notable changes This is an LTS maintenance release that addresses a number of issues: * [[`1d0f2cbf87`](https://github.com/nodejs/node/commit/1d0f2cbf87)] - **buffer**: fix value check for writeUInt{B,L}E (Trevor Norris) [#3500](https://github.com/nodejs/node/pull/3500) * [[`2a45b72b4a`](https://github.com/nodejs/node/commit/2a45b72b4a)] - **buffer**: don't CHECK on zero-sized realloc (Ben Noordhuis) [#3499](https://github.com/nodejs/node/pull/3499) * [[`a6469e901a`](https://github.com/nodejs/node/commit/a6469e901a)] - **deps**: backport 010897c from V8 upstream (Ali Ijaz Sheikh) [#3520](https://github.com/nodejs/node/pull/3520) * [[`cadee67c25`](https://github.com/nodejs/node/commit/cadee67c25)] - **deps**: backport 8d6a228 from the v8's upstream (Fedor Indutny) [#3549](https://github.com/nodejs/node/pull/3549) * [[`46c8c94055`](https://github.com/nodejs/node/commit/46c8c94055)] - **fs**: reduced duplicate code in fs.write() (ronkorving) [#2947](https://github.com/nodejs/node/pull/2947) * [[`0427cdf094`](https://github.com/nodejs/node/commit/0427cdf094)] - **http**: fix stalled pipeline bug (Fedor Indutny) [#3342](https://github.com/nodejs/node/pull/3342) * [[`2109708186`](https://github.com/nodejs/node/commit/2109708186)] - **lib**: fix cluster handle leak (Rich Trott) [#3510](https://github.com/nodejs/node/pull/3510) * [[`f49c7c6955`](https://github.com/nodejs/node/commit/f49c7c6955)] - **lib**: avoid REPL exit on completion error (Rich Trott) [#3358](https://github.com/nodejs/node/pull/3358) * [[`8a2c4aeeaa`](https://github.com/nodejs/node/commit/8a2c4aeeaa)] - **repl**: handle comments properly (Sakthipriyan Vairamani) [#3515](https://github.com/nodejs/node/pull/3515) * [[`a04408acce`](https://github.com/nodejs/node/commit/a04408acce)] - **repl**: limit persistent history correctly on load (Jeremiah Senkpiel) [#2356](https://github.com/nodejs/node/pull/2356) * [[`3bafe1a59b`](https://github.com/nodejs/node/commit/3bafe1a59b)] - **src**: fix race condition in debug signal on exit (Ben Noordhuis) [#3528](https://github.com/nodejs/node/pull/3528) * [[`fe01d0df7a`](https://github.com/nodejs/node/commit/fe01d0df7a)] - **src**: fix exception message encoding on Windows (Brian White) [#3288](https://github.com/nodejs/node/pull/3288) * [[`4bac5d9ddf`](https://github.com/nodejs/node/commit/4bac5d9ddf)] - **stream**: avoid unnecessary concat of a single buffer. (Calvin Metcalf) [#3300](https://github.com/nodejs/node/pull/3300) * [[`8d78d687d5`](https://github.com/nodejs/node/commit/8d78d687d5)] - **timers**: reuse timer in `setTimeout().unref()` (Fedor Indutny) [#3407](https://github.com/nodejs/node/pull/3407) * [[`e69c869399`](https://github.com/nodejs/node/commit/e69c869399)] - **tls**: TLSSocket options default isServer false (Yuval Brik) [#2614](https://github.com/nodejs/node/pull/2614) ### Known issues * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`1d0f2cbf87`](https://github.com/nodejs/node/commit/1d0f2cbf87)] - **buffer**: fix value check for writeUInt{B,L}E (Trevor Norris) [#3500](https://github.com/nodejs/node/pull/3500) * [[`2a45b72b4a`](https://github.com/nodejs/node/commit/2a45b72b4a)] - **buffer**: don't CHECK on zero-sized realloc (Ben Noordhuis) [#3499](https://github.com/nodejs/node/pull/3499) * [[`dc655e1dd2`](https://github.com/nodejs/node/commit/dc655e1dd2)] - **build**: rectify --link-module help text (P.S.V.R) [#3379](https://github.com/nodejs/node/pull/3379) * [[`a6469e901a`](https://github.com/nodejs/node/commit/a6469e901a)] - **deps**: backport 010897c from V8 upstream (Ali Ijaz Sheikh) [#3520](https://github.com/nodejs/node/pull/3520) * [[`cadee67c25`](https://github.com/nodejs/node/commit/cadee67c25)] - **deps**: backport 8d6a228 from the v8's upstream (Fedor Indutny) [#3549](https://github.com/nodejs/node/pull/3549) * [[`1ebd35550b`](https://github.com/nodejs/node/commit/1ebd35550b)] - **doc**: fix typos in changelog (reggi) [#3291](https://github.com/nodejs/node/pull/3291) * [[`fbd93d4c1c`](https://github.com/nodejs/node/commit/fbd93d4c1c)] - **doc**: more use-cases for promise events (Domenic Denicola) [#3438](https://github.com/nodejs/node/pull/3438) * [[`6ceb9af407`](https://github.com/nodejs/node/commit/6ceb9af407)] - **doc**: remove old note, 'cluster' is marked stable (Balázs Galambosi) [#3314](https://github.com/nodejs/node/pull/3314) * [[`a5f0d64ddc`](https://github.com/nodejs/node/commit/a5f0d64ddc)] - **doc**: createServer's key option can be an array (Sakthipriyan Vairamani) [#3123](https://github.com/nodejs/node/pull/3123) * [[`317e0ec6b3`](https://github.com/nodejs/node/commit/317e0ec6b3)] - **doc**: binary encoding is not deprecated (Trevor Norris) [#3441](https://github.com/nodejs/node/pull/3441) * [[`b422f6ee1a`](https://github.com/nodejs/node/commit/b422f6ee1a)] - **doc**: mention the behaviour if URL is invalid (Sakthipriyan Vairamani) [#2966](https://github.com/nodejs/node/pull/2966) * [[`bc29aad22b`](https://github.com/nodejs/node/commit/bc29aad22b)] - **doc**: fix indent in tls resumption example (Roman Reiss) [#3372](https://github.com/nodejs/node/pull/3372) * [[`313877bd8f`](https://github.com/nodejs/node/commit/313877bd8f)] - **doc**: fix typo in changelog (Timothy Gu) [#3353](https://github.com/nodejs/node/pull/3353) * [[`4be432862a`](https://github.com/nodejs/node/commit/4be432862a)] - **doc**: show keylen in pbkdf2 as a byte length (calebboyd) [#3334](https://github.com/nodejs/node/pull/3334) * [[`23a1140ddb`](https://github.com/nodejs/node/commit/23a1140ddb)] - **doc**: add information about Assert behavior and maintenance (Rich Trott) [#3330](https://github.com/nodejs/node/pull/3330) * [[`e04cb1e1fc`](https://github.com/nodejs/node/commit/e04cb1e1fc)] - **doc**: clarify API buffer.concat (Martii) [#3255](https://github.com/nodejs/node/pull/3255) * [[`eae714c370`](https://github.com/nodejs/node/commit/eae714c370)] - **doc**: clarify the use of `option.detached` (Kyle Smith) [#3250](https://github.com/nodejs/node/pull/3250) * [[`b884899e67`](https://github.com/nodejs/node/commit/b884899e67)] - **doc**: label v4.2.1 as LTS in changelog heading (Phillip Johnsen) [#3360](https://github.com/nodejs/node/pull/3360) * [[`9120a04981`](https://github.com/nodejs/node/commit/9120a04981)] - **docs**: add missing shell option to execSync (fansworld-claudio) [#3440](https://github.com/nodejs/node/pull/3440) * [[`46c8c94055`](https://github.com/nodejs/node/commit/46c8c94055)] - **fs**: reduced duplicate code in fs.write() (ronkorving) [#2947](https://github.com/nodejs/node/pull/2947) * [[`0427cdf094`](https://github.com/nodejs/node/commit/0427cdf094)] - **http**: fix stalled pipeline bug (Fedor Indutny) [#3342](https://github.com/nodejs/node/pull/3342) * [[`2109708186`](https://github.com/nodejs/node/commit/2109708186)] - **lib**: fix cluster handle leak (Rich Trott) [#3510](https://github.com/nodejs/node/pull/3510) * [[`f49c7c6955`](https://github.com/nodejs/node/commit/f49c7c6955)] - **lib**: avoid REPL exit on completion error (Rich Trott) [#3358](https://github.com/nodejs/node/pull/3358) * [[`8a2c4aeeaa`](https://github.com/nodejs/node/commit/8a2c4aeeaa)] - **repl**: handle comments properly (Sakthipriyan Vairamani) [#3515](https://github.com/nodejs/node/pull/3515) * [[`a04408acce`](https://github.com/nodejs/node/commit/a04408acce)] - **repl**: limit persistent history correctly on load (Jeremiah Senkpiel) [#2356](https://github.com/nodejs/node/pull/2356) * [[`5d1f1c5fa8`](https://github.com/nodejs/node/commit/5d1f1c5fa8)] - **src**: wrap source before doing syntax check (Evan Lucas) [#3587](https://github.com/nodejs/node/pull/3587) * [[`3bafe1a59b`](https://github.com/nodejs/node/commit/3bafe1a59b)] - **src**: fix race condition in debug signal on exit (Ben Noordhuis) [#3528](https://github.com/nodejs/node/pull/3528) * [[`fe01d0df7a`](https://github.com/nodejs/node/commit/fe01d0df7a)] - **src**: fix exception message encoding on Windows (Brian White) [#3288](https://github.com/nodejs/node/pull/3288) * [[`4bac5d9ddf`](https://github.com/nodejs/node/commit/4bac5d9ddf)] - **stream**: avoid unnecessary concat of a single buffer. (Calvin Metcalf) [#3300](https://github.com/nodejs/node/pull/3300) * [[`117fb47a16`](https://github.com/nodejs/node/commit/117fb47a16)] - **stream**: fix signature of _write() in a comment (Fábio Santos) [#3248](https://github.com/nodejs/node/pull/3248) * [[`c563a34427`](https://github.com/nodejs/node/commit/c563a34427)] - **test**: split independent tests into separate files (Rich Trott) [#3548](https://github.com/nodejs/node/pull/3548) * [[`3f62952d42`](https://github.com/nodejs/node/commit/3f62952d42)] - **test**: add node::MakeCallback() test coverage (Ben Noordhuis) [#3478](https://github.com/nodejs/node/pull/3478) * [[`6b75f10d8a`](https://github.com/nodejs/node/commit/6b75f10d8a)] - **test**: use port number from env in tls socket test (Stefan Budeanu) [#3557](https://github.com/nodejs/node/pull/3557) * [[`39ff44e94f`](https://github.com/nodejs/node/commit/39ff44e94f)] - **test**: fix heap-profiler link error LNK1194 on win (Junliang Yan) [#3572](https://github.com/nodejs/node/pull/3572) * [[`a2786dd408`](https://github.com/nodejs/node/commit/a2786dd408)] - **test**: fix missing unistd.h on windows (Junliang Yan) [#3532](https://github.com/nodejs/node/pull/3532) * [[`5e6f7c9a23`](https://github.com/nodejs/node/commit/5e6f7c9a23)] - **test**: add regression test for --debug-brk -e 0 (Ben Noordhuis) [#3585](https://github.com/nodejs/node/pull/3585) * [[`7cad182cb6`](https://github.com/nodejs/node/commit/7cad182cb6)] - **test**: port domains regression test from v0.10 (Jonas Dohse) [#3356](https://github.com/nodejs/node/pull/3356) * [[`78d854c6ce`](https://github.com/nodejs/node/commit/78d854c6ce)] - **test**: remove util from common (Rich Trott) [#3324](https://github.com/nodejs/node/pull/3324) * [[`c566c8b8c0`](https://github.com/nodejs/node/commit/c566c8b8c0)] - **test**: remove util properties from common (Rich Trott) [#3304](https://github.com/nodejs/node/pull/3304) * [[`eb7c3fb2f4`](https://github.com/nodejs/node/commit/eb7c3fb2f4)] - **test**: split up buffer tests for reliability (Rich Trott) [#3323](https://github.com/nodejs/node/pull/3323) * [[`b398a85e19`](https://github.com/nodejs/node/commit/b398a85e19)] - **test**: parallelize long-running test (Rich Trott) [#3287](https://github.com/nodejs/node/pull/3287) * [[`b5f3b4956b`](https://github.com/nodejs/node/commit/b5f3b4956b)] - **test**: change call to deprecated util.isError() (Rich Trott) [#3084](https://github.com/nodejs/node/pull/3084) * [[`32149cacb5`](https://github.com/nodejs/node/commit/32149cacb5)] - **test**: improve tests for util.inherits (Michaël Zasso) [#3507](https://github.com/nodejs/node/pull/3507) * [[`5be686fab8`](https://github.com/nodejs/node/commit/5be686fab8)] - **test**: print helpful err msg on test-dns-ipv6.js (Junliang Yan) [#3501](https://github.com/nodejs/node/pull/3501) * [[`0429131e32`](https://github.com/nodejs/node/commit/0429131e32)] - **test**: fix domain with abort-on-uncaught on PPC (Julien Gilli) [#3354](https://github.com/nodejs/node/pull/3354) * [[`788106eee9`](https://github.com/nodejs/node/commit/788106eee9)] - **test**: cleanup, improve repl-persistent-history (Jeremiah Senkpiel) [#2356](https://github.com/nodejs/node/pull/2356) * [[`ea58fa0bac`](https://github.com/nodejs/node/commit/ea58fa0bac)] - **test**: add Symbol test for assert.deepEqual() (Rich Trott) [#3327](https://github.com/nodejs/node/pull/3327) * [[`d409ac473b`](https://github.com/nodejs/node/commit/d409ac473b)] - **test**: disable test-tick-processor - aix and be ppc (Michael Dawson) [#3491](https://github.com/nodejs/node/pull/3491) * [[`c1623039dd`](https://github.com/nodejs/node/commit/c1623039dd)] - **test**: harden test-child-process-fork-regr-gh-2847 (Michael Dawson) [#3459](https://github.com/nodejs/node/pull/3459) * [[`3bb4437abb`](https://github.com/nodejs/node/commit/3bb4437abb)] - **test**: fix test-net-keepalive for AIX (Imran Iqbal) [#3458](https://github.com/nodejs/node/pull/3458) * [[`af55641a69`](https://github.com/nodejs/node/commit/af55641a69)] - **test**: wrap assert.fail when passed to callback (Myles Borins) [#3453](https://github.com/nodejs/node/pull/3453) * [[`7c7ef01e65`](https://github.com/nodejs/node/commit/7c7ef01e65)] - **test**: skip test-dns-ipv6.js if ipv6 is unavailable (Junliang Yan) [#3444](https://github.com/nodejs/node/pull/3444) * [[`a4d1510ba4`](https://github.com/nodejs/node/commit/a4d1510ba4)] - **test**: repl-persistent-history is no longer flaky (Jeremiah Senkpiel) [#3437](https://github.com/nodejs/node/pull/3437) * [[`a5d968b8a2`](https://github.com/nodejs/node/commit/a5d968b8a2)] - **test**: fix flaky test-child-process-emfile (Rich Trott) [#3430](https://github.com/nodejs/node/pull/3430) * [[`eac2acca76`](https://github.com/nodejs/node/commit/eac2acca76)] - **test**: remove flaky status from eval_messages test (Rich Trott) [#3420](https://github.com/nodejs/node/pull/3420) * [[`155c778584`](https://github.com/nodejs/node/commit/155c778584)] - **test**: fix flaky test for symlinks (Rich Trott) [#3418](https://github.com/nodejs/node/pull/3418) * [[`74eb632483`](https://github.com/nodejs/node/commit/74eb632483)] - **test**: apply correct assert.fail() arguments (Rich Trott) [#3378](https://github.com/nodejs/node/pull/3378) * [[`0a4323dd82`](https://github.com/nodejs/node/commit/0a4323dd82)] - **test**: replace util with backtick strings (Myles Borins) [#3359](https://github.com/nodejs/node/pull/3359) * [[`93847694ec`](https://github.com/nodejs/node/commit/93847694ec)] - **test**: add test-child-process-emfile fail message (Rich Trott) [#3335](https://github.com/nodejs/node/pull/3335) * [[`8d78d687d5`](https://github.com/nodejs/node/commit/8d78d687d5)] - **timers**: reuse timer in `setTimeout().unref()` (Fedor Indutny) [#3407](https://github.com/nodejs/node/pull/3407) * [[`e69c869399`](https://github.com/nodejs/node/commit/e69c869399)] - **tls**: TLSSocket options default isServer false (Yuval Brik) [#2614](https://github.com/nodejs/node/pull/2614) * [[`0b32bbbf69`](https://github.com/nodejs/node/commit/0b32bbbf69)] - **v8**: pull fix for builtin code size on PPC (Michael Dawson) [#3474](https://github.com/nodejs/node/pull/3474) ## 2015-10-13, Version 4.2.1 'Argon' (LTS), @jasnell ### Notable changes * Includes fixes for two regressions - Assertion error in WeakCallback - see [#3329](https://github.com/nodejs/node/pull/3329) - Undefined timeout regression - see [#3331](https://github.com/nodejs/node/pull/3331) ### Known issues * When a server queues a large amount of data to send to a client over a pipelined HTTP connection, the underlying socket may be destroyed. See [#3332](https://github.com/nodejs/node/issues/3332) and [#3342](https://github.com/nodejs/node/pull/3342). * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`b3cbd13340`](https://github.com/nodejs/node/commit/b3cbd13340)] - **buffer**: fix assertion error in WeakCallback (Fedor Indutny) [#3329](https://github.com/nodejs/node/pull/3329) * [[`102cb7288c`](https://github.com/nodejs/node/commit/102cb7288c)] - **doc**: label v4.2.0 as LTS in changelog heading (Rod Vagg) [#3343](https://github.com/nodejs/node/pull/3343) * [[`c245a199a7`](https://github.com/nodejs/node/commit/c245a199a7)] - **lib**: fix undefined timeout regression (Ryan Graham) [#3331](https://github.com/nodejs/node/pull/3331) ## 2015-10-07, Version 4.2.0 'Argon' (LTS), @jasnell ### Notable changes The first Node.js LTS release! See https://github.com/nodejs/LTS/ for details of the LTS process. * **icu**: Updated to version 56 with significant performance improvements (Steven R. Loomis) [#3281](https://github.com/nodejs/node/pull/3281) * **node**: - Added new `-c` (or `--check`) command line argument for checking script syntax without executing the code (Dave Eddy) [#2411](https://github.com/nodejs/node/pull/2411) - Added `process.versions.icu` to hold the current ICU library version (Evan Lucas) [#3102](https://github.com/nodejs/node/pull/3102) - Added `process.release.lts` to hold the current LTS codename when the binary is from an active LTS release line (Rod Vagg) [#3212](https://github.com/nodejs/node/pull/3212) * **npm**: Upgraded to npm 2.14.7 from 2.14.4, see [release notes](https://github.com/npm/npm/releases/tag/v2.14.7) for full details (Kat Marchán) [#3299](https://github.com/nodejs/node/pull/3299) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`8383c4fe00`](https://github.com/nodejs/node/commit/8383c4fe00)] - **assert**: support arrow functions in .throws() (Ben Noordhuis) [#3276](https://github.com/nodejs/node/pull/3276) * [[`3eaa593a32`](https://github.com/nodejs/node/commit/3eaa593a32)] - **async_wrap**: correctly pass parent to init callback (Trevor Norris) [#3216](https://github.com/nodejs/node/pull/3216) * [[`54795620f6`](https://github.com/nodejs/node/commit/54795620f6)] - **buffer**: don't abort on prototype getters (Trevor Norris) [#3302](https://github.com/nodejs/node/pull/3302) * [[`660f7591c8`](https://github.com/nodejs/node/commit/660f7591c8)] - **buffer**: FreeCallback should be tied to ArrayBuffer (Fedor Indutny) [#3198](https://github.com/nodejs/node/pull/3198) * [[`651a5b51eb`](https://github.com/nodejs/node/commit/651a5b51eb)] - **buffer**: only check if instance is Uint8Array (Trevor Norris) [#3080](https://github.com/nodejs/node/pull/3080) * [[`d5a1b1ad7c`](https://github.com/nodejs/node/commit/d5a1b1ad7c)] - **buffer**: clean up usage of __proto__ (Trevor Norris) [#3080](https://github.com/nodejs/node/pull/3080) * [[`af24376e18`](https://github.com/nodejs/node/commit/af24376e18)] - **build**: Intl: deps: bump ICU to 56.1 (GA) (Steven R. Loomis) [#3281](https://github.com/nodejs/node/pull/3281) * [[`9136359d57`](https://github.com/nodejs/node/commit/9136359d57)] - **build**: make icu download path customizable (Johan Bergström) [#3200](https://github.com/nodejs/node/pull/3200) * [[`b3c5ad10a8`](https://github.com/nodejs/node/commit/b3c5ad10a8)] - **build**: add --with-arm-fpu option (Jérémy Lal) [#3228](https://github.com/nodejs/node/pull/3228) * [[`f00f3268e4`](https://github.com/nodejs/node/commit/f00f3268e4)] - **build**: intl: avoid 'duplicate main()' on ICU 56 (Steven R. Loomis) [#3066](https://github.com/nodejs/node/pull/3066) * [[`071c72a6a3`](https://github.com/nodejs/node/commit/071c72a6a3)] - **deps**: upgrade to npm 2.14.7 (Kat Marchán) [#3299](https://github.com/nodejs/node/pull/3299) * [[`8b50e95f06`](https://github.com/nodejs/node/commit/8b50e95f06)] - **(SEMVER-MINOR)** **deps**: backport 1ee712a from V8 upstream (Julien Gilli) [#3036](https://github.com/nodejs/node/pull/3036) * [[`747271372f`](https://github.com/nodejs/node/commit/747271372f)] - **doc**: update the assert module summary (David Boivin) [#2799](https://github.com/nodejs/node/pull/2799) * [[`0d506556b0`](https://github.com/nodejs/node/commit/0d506556b0)] - **doc**: replace node-gyp link with nodejs/node-gyp (Roman Klauke) [#3320](https://github.com/nodejs/node/pull/3320) * [[`40a159e4f4`](https://github.com/nodejs/node/commit/40a159e4f4)] - **doc**: Amend capitalization of word JavaScript (Dave Hodder) [#3285](https://github.com/nodejs/node/pull/3285) * [[`6dd34761fd`](https://github.com/nodejs/node/commit/6dd34761fd)] - **doc**: add method links in dns.markdown (Alejandro Oviedo) [#3196](https://github.com/nodejs/node/pull/3196) * [[`333e8336be`](https://github.com/nodejs/node/commit/333e8336be)] - **doc**: add method links in child_process.markdown (Alejandro Oviedo) [#3186](https://github.com/nodejs/node/pull/3186) * [[`0cfc6d39ca`](https://github.com/nodejs/node/commit/0cfc6d39ca)] - **doc**: recommend Infinity on emitter.setMaxListeners (Jason Karns) [#2559](https://github.com/nodejs/node/pull/2559) * [[`d4fc6d93ef`](https://github.com/nodejs/node/commit/d4fc6d93ef)] - **doc**: add help repo link to CONTRIBUTING.md (Doug Shamoo) [#3233](https://github.com/nodejs/node/pull/3233) * [[`28aac7f19d`](https://github.com/nodejs/node/commit/28aac7f19d)] - **doc**: add TLS session resumption example (Roman Reiss) [#3147](https://github.com/nodejs/node/pull/3147) * [[`365cf22cce`](https://github.com/nodejs/node/commit/365cf22cce)] - **doc**: update AUTHORS list (Rod Vagg) [#3211](https://github.com/nodejs/node/pull/3211) * [[`d4399613b7`](https://github.com/nodejs/node/commit/d4399613b7)] - **doc**: standardize references to userland (Martial) [#3192](https://github.com/nodejs/node/pull/3192) * [[`75de258376`](https://github.com/nodejs/node/commit/75de258376)] - **doc**: fix spelling in Buffer documentation (Rod Machen) [#3226](https://github.com/nodejs/node/pull/3226) * [[`725c7276dd`](https://github.com/nodejs/node/commit/725c7276dd)] - **doc**: fix README.md link to joyent/node intl wiki (Steven R. Loomis) [#3067](https://github.com/nodejs/node/pull/3067) * [[`4a35ba4966`](https://github.com/nodejs/node/commit/4a35ba4966)] - **(SEMVER-MINOR)** **fs**: include filename in watch errors (charlierudolph) [#2748](https://github.com/nodejs/node/pull/2748) * [[`2ddbbfd164`](https://github.com/nodejs/node/commit/2ddbbfd164)] - **http**: cork/uncork before flushing pipelined res (Fedor Indutny) [#3172](https://github.com/nodejs/node/pull/3172) * [[`f638402e2f`](https://github.com/nodejs/node/commit/f638402e2f)] - **http**: add comment about `outputSize` in res/server (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) * [[`1850879b0e`](https://github.com/nodejs/node/commit/1850879b0e)] - **js_stream**: prevent abort if isalive doesn't exist (Trevor Norris) [#3282](https://github.com/nodejs/node/pull/3282) * [[`63644dd1cd`](https://github.com/nodejs/node/commit/63644dd1cd)] - **lib**: remove redundant code, add tests in timers.js (Rich Trott) [#3143](https://github.com/nodejs/node/pull/3143) * [[`74f443583c`](https://github.com/nodejs/node/commit/74f443583c)] - **module**: use UNC paths when loading native addons (Justin Chase) [#2965](https://github.com/nodejs/node/pull/2965) * [[`01cb3fc36b`](https://github.com/nodejs/node/commit/01cb3fc36b)] - **net**: don't throw on bytesWritten access (Trevor Norris) [#3305](https://github.com/nodejs/node/pull/3305) * [[`9d65528b01`](https://github.com/nodejs/node/commit/9d65528b01)] - **(SEMVER-MINOR)** **node**: add -c|--check CLI arg to syntax check script (Dave Eddy) [#2411](https://github.com/nodejs/node/pull/2411) * [[`42b936e78d`](https://github.com/nodejs/node/commit/42b936e78d)] - **(SEMVER-MINOR)** **src**: add process.release.lts property (Rod Vagg) [#3212](https://github.com/nodejs/node/pull/3212) * [[`589287b2e3`](https://github.com/nodejs/node/commit/589287b2e3)] - **src**: convert BE-utf16-string to LE before search (Karl Skomski) [#3295](https://github.com/nodejs/node/pull/3295) * [[`2314378f06`](https://github.com/nodejs/node/commit/2314378f06)] - **src**: fix u-a-free if uv returns err in ASYNC_CALL (Karl Skomski) [#3049](https://github.com/nodejs/node/pull/3049) * [[`d99336a391`](https://github.com/nodejs/node/commit/d99336a391)] - **(SEMVER-MINOR)** **src**: replace naive search in Buffer::IndexOf (Karl Skomski) [#2539](https://github.com/nodejs/node/pull/2539) * [[`546e8333ba`](https://github.com/nodejs/node/commit/546e8333ba)] - **(SEMVER-MINOR)** **src**: fix --abort-on-uncaught-exception (Jeremy Whitlock) [#3036](https://github.com/nodejs/node/pull/3036) * [[`7271cb047c`](https://github.com/nodejs/node/commit/7271cb047c)] - **(SEMVER-MINOR)** **src**: add process.versions.icu (Evan Lucas) [#3102](https://github.com/nodejs/node/pull/3102) * [[`7b9f78acb2`](https://github.com/nodejs/node/commit/7b9f78acb2)] - **stream**: avoid pause with unpipe in buffered write (Brian White) [#2325](https://github.com/nodejs/node/pull/2325) * [[`f0f8afd879`](https://github.com/nodejs/node/commit/f0f8afd879)] - **test**: remove common.inspect() (Rich Trott) [#3257](https://github.com/nodejs/node/pull/3257) * [[`5ca4f6f8bd`](https://github.com/nodejs/node/commit/5ca4f6f8bd)] - **test**: test `util` rather than `common` (Rich Trott) [#3256](https://github.com/nodejs/node/pull/3256) * [[`7a5ae34345`](https://github.com/nodejs/node/commit/7a5ae34345)] - **test**: refresh temp directory when using pipe (Rich Trott) [#3231](https://github.com/nodejs/node/pull/3231) * [[`7c85557ef0`](https://github.com/nodejs/node/commit/7c85557ef0)] - **test**: Fix test-fs-read-stream-fd-leak race cond (Junliang Yan) [#3218](https://github.com/nodejs/node/pull/3218) * [[`26a7ec6960`](https://github.com/nodejs/node/commit/26a7ec6960)] - **test**: fix losing original env vars issue (Junliang Yan) [#3190](https://github.com/nodejs/node/pull/3190) * [[`e922716192`](https://github.com/nodejs/node/commit/e922716192)] - **test**: remove deprecated error logging (Rich Trott) [#3079](https://github.com/nodejs/node/pull/3079) * [[`8f29d95a8c`](https://github.com/nodejs/node/commit/8f29d95a8c)] - **test**: report timeout in TapReporter (Karl Skomski) [#2647](https://github.com/nodejs/node/pull/2647) * [[`2d0fe4c657`](https://github.com/nodejs/node/commit/2d0fe4c657)] - **test**: linting for buffer-free-callback test (Rich Trott) [#3230](https://github.com/nodejs/node/pull/3230) * [[`70c9e4337e`](https://github.com/nodejs/node/commit/70c9e4337e)] - **test**: make common.js mandatory via linting rule (Rich Trott) [#3157](https://github.com/nodejs/node/pull/3157) * [[`b7179562aa`](https://github.com/nodejs/node/commit/b7179562aa)] - **test**: load common.js in all tests (Rich Trott) [#3157](https://github.com/nodejs/node/pull/3157) * [[`bab555a1c1`](https://github.com/nodejs/node/commit/bab555a1c1)] - **test**: speed up stringbytes-external test (Evan Lucas) [#3005](https://github.com/nodejs/node/pull/3005) * [[`ddf258376d`](https://github.com/nodejs/node/commit/ddf258376d)] - **test**: use normalize() for unicode paths (Roman Reiss) [#3007](https://github.com/nodejs/node/pull/3007) * [[`46876d519c`](https://github.com/nodejs/node/commit/46876d519c)] - **test**: remove arguments.callee usage (Roman Reiss) [#3167](https://github.com/nodejs/node/pull/3167) * [[`af10df6108`](https://github.com/nodejs/node/commit/af10df6108)] - **tls**: use parent handle's close callback (Fedor Indutny) [#2991](https://github.com/nodejs/node/pull/2991) * [[`9c2748bad1`](https://github.com/nodejs/node/commit/9c2748bad1)] - **tools**: remove leftover license boilerplate (Nathan Rajlich) [#3225](https://github.com/nodejs/node/pull/3225) * [[`5d9f83ff2a`](https://github.com/nodejs/node/commit/5d9f83ff2a)] - **tools**: apply linting to custom rules code (Rich Trott) [#3195](https://github.com/nodejs/node/pull/3195) * [[`18a8b2ec73`](https://github.com/nodejs/node/commit/18a8b2ec73)] - **tools**: remove unused gflags module (Ben Noordhuis) [#3220](https://github.com/nodejs/node/pull/3220) * [[`e0fffca836`](https://github.com/nodejs/node/commit/e0fffca836)] - **util**: fix for inspecting promises (Evan Lucas) [#3221](https://github.com/nodejs/node/pull/3221) * [[`8dfdee3733`](https://github.com/nodejs/node/commit/8dfdee3733)] - **util**: correctly inspect Map/Set Iterators (Evan Lucas) [#3119](https://github.com/nodejs/node/pull/3119) * [[`b5c51fdba0`](https://github.com/nodejs/node/commit/b5c51fdba0)] - **util**: fix check for Array constructor (Evan Lucas) [#3119](https://github.com/nodejs/node/pull/3119) ## 2015-10-05, Version 4.1.2 (Stable), @rvagg ### Notable changes * **http**: - Fix out-of-order 'finish' event bug in pipelining that can abort execution, fixes DoS vulnerability [CVE-2015-7384](https://github.com/nodejs/node/issues/3138) (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) - Account for pending response data instead of just the data on the current request to decide whether pause the socket or not (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) * **libuv**: Upgraded from v1.7.4 to v1.7.5, see [release notes](https://github.com/libuv/libuv/releases/tag/v1.7.5) for details (Saúl Ibarra Corretgé) [#3010](https://github.com/nodejs/node/pull/3010) - A better rwlock implementation for all Windows versions - Improved AIX support * **v8**: - Upgraded from v4.5.103.33 to v4.5.103.35 (Ali Ijaz Sheikh) [#3117](https://github.com/nodejs/node/pull/3117) - Backported [f782159](https://codereview.chromium.org/1367123003) from v8's upstream to help speed up Promise introspection (Ben Noordhuis) [#3130](https://github.com/nodejs/node/pull/3130) - Backported [c281c15](https://codereview.chromium.org/1363683002) from v8's upstream to add JSTypedArray length in post-mortem metadata (Julien Gilli) [#3031](https://github.com/nodejs/node/pull/3031) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`39b8730e8b`](https://github.com/nodejs/node/commit/39b8730e8b)] - **async_wrap**: ensure all objects have internal field (Trevor Norris) [#3139](https://github.com/nodejs/node/pull/3139) * [[`99e66074d7`](https://github.com/nodejs/node/commit/99e66074d7)] - **async_wrap**: update providers and add test (Trevor Norris) [#3139](https://github.com/nodejs/node/pull/3139) * [[`7a58157d4e`](https://github.com/nodejs/node/commit/7a58157d4e)] - **benchmark**: update comment in common.js (Minwoo Jung) [#2399](https://github.com/nodejs/node/pull/2399) * [[`9e9bfa4dc0`](https://github.com/nodejs/node/commit/9e9bfa4dc0)] - **build**: iojs -> nodejs of release-urlbase (P.S.V.R) [#3015](https://github.com/nodejs/node/pull/3015) * [[`8335ec7191`](https://github.com/nodejs/node/commit/8335ec7191)] - **build**: fix some typos inside the configure script (P.S.V.R) [#3016](https://github.com/nodejs/node/pull/3016) * [[`d6ac547d5d`](https://github.com/nodejs/node/commit/d6ac547d5d)] - **build,win**: fix node.exe resource version (João Reis) [#3053](https://github.com/nodejs/node/pull/3053) * [[`798dad24f4`](https://github.com/nodejs/node/commit/798dad24f4)] - **child_process**: `null` channel handle on close (Fedor Indutny) [#3041](https://github.com/nodejs/node/pull/3041) * [[`e5615854ea`](https://github.com/nodejs/node/commit/e5615854ea)] - **contextify**: use CHECK instead of `if` (Oguz Bastemur) [#3125](https://github.com/nodejs/node/pull/3125) * [[`f055a66a38`](https://github.com/nodejs/node/commit/f055a66a38)] - **crypto**: enable FIPS only when configured with it (Fedor Indutny) [#3153](https://github.com/nodejs/node/pull/3153) * [[`4c8d96bc30`](https://github.com/nodejs/node/commit/4c8d96bc30)] - **crypto**: add more keylen sanity checks in pbkdf2 (Johann) [#3029](https://github.com/nodejs/node/pull/3029) * [[`4c5940776c`](https://github.com/nodejs/node/commit/4c5940776c)] - **deps**: upgrade libuv to 1.7.5 (Saúl Ibarra Corretgé) [#3010](https://github.com/nodejs/node/pull/3010) * [[`5a9e795577`](https://github.com/nodejs/node/commit/5a9e795577)] - **deps**: upgrade V8 to 4.5.103.35 (Ali Ijaz Sheikh) [#3117](https://github.com/nodejs/node/pull/3117) * [[`925b29f959`](https://github.com/nodejs/node/commit/925b29f959)] - **deps**: backport f782159 from v8's upstream (Ben Noordhuis) [#3130](https://github.com/nodejs/node/pull/3130) * [[`039f73fa83`](https://github.com/nodejs/node/commit/039f73fa83)] - **deps**: remove and gitignore .bin directory (Ben Noordhuis) [#3004](https://github.com/nodejs/node/pull/3004) * [[`5fbb24812d`](https://github.com/nodejs/node/commit/5fbb24812d)] - **deps**: backport c281c15 from V8's upstream (Julien Gilli) [#3031](https://github.com/nodejs/node/pull/3031) * [[`6ee5d0f69f`](https://github.com/nodejs/node/commit/6ee5d0f69f)] - **dns**: add missing exports.BADNAME (Roman Reiss) [#3051](https://github.com/nodejs/node/pull/3051) * [[`f92aee7170`](https://github.com/nodejs/node/commit/f92aee7170)] - **doc**: fix outdated 'try/catch' statement in sync (Minwoo Jung) [#3087](https://github.com/nodejs/node/pull/3087) * [[`c7161f39e8`](https://github.com/nodejs/node/commit/c7161f39e8)] - **doc**: add TSC meeting minutes 2015-09-16 (Rod Vagg) [#3023](https://github.com/nodejs/node/pull/3023) * [[`928166c4a8`](https://github.com/nodejs/node/commit/928166c4a8)] - **doc**: copyedit fs.watch() information (Rich Trott) [#3097](https://github.com/nodejs/node/pull/3097) * [[`75d5dcea76`](https://github.com/nodejs/node/commit/75d5dcea76)] - **doc**: jenkins-iojs.nodesource.com -> ci.nodejs.org (Michał Gołębiowski) [#2886](https://github.com/nodejs/node/pull/2886) * [[`5c3f50b21d`](https://github.com/nodejs/node/commit/5c3f50b21d)] - **doc**: rearrange execSync and execFileSync (Laurent Fortin) [#2940](https://github.com/nodejs/node/pull/2940) * [[`4fc33ac11a`](https://github.com/nodejs/node/commit/4fc33ac11a)] - **doc**: make execFileSync in line with execFile (Laurent Fortin) [#2940](https://github.com/nodejs/node/pull/2940) * [[`a366e84b17`](https://github.com/nodejs/node/commit/a366e84b17)] - **doc**: fix typos in cluster & errors (reggi) [#3011](https://github.com/nodejs/node/pull/3011) * [[`52031e1bf1`](https://github.com/nodejs/node/commit/52031e1bf1)] - **doc**: switch LICENSE from closure-linter to eslint (P.S.V.R) [#3018](https://github.com/nodejs/node/pull/3018) * [[`b28f6a53bc`](https://github.com/nodejs/node/commit/b28f6a53bc)] - **docs**: Clarify assert.doesNotThrow behavior (Fabio Oliveira) [#2807](https://github.com/nodejs/node/pull/2807) * [[`99943e189d`](https://github.com/nodejs/node/commit/99943e189d)] - **http**: fix out-of-order 'finish' bug in pipelining (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) * [[`fb7a491d1c`](https://github.com/nodejs/node/commit/fb7a491d1c)] - **http_server**: pause socket properly (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) * [[`a0b35bfcf3`](https://github.com/nodejs/node/commit/a0b35bfcf3)] - **i18n**: add caller to removal list for bidi in ICU55 (Michael Dawson) [#3115](https://github.com/nodejs/node/pull/3115) * [[`ac2bce0b0c`](https://github.com/nodejs/node/commit/ac2bce0b0c)] - **path**: improve posixSplitPath performance (Evan Lucas) [#3034](https://github.com/nodejs/node/pull/3034) * [[`37cdeafa2f`](https://github.com/nodejs/node/commit/37cdeafa2f)] - **smalloc**: remove module (Brendan Ashworth) [#3099](https://github.com/nodejs/node/pull/3099) * [[`5ec5d0aa8b`](https://github.com/nodejs/node/commit/5ec5d0aa8b)] - **src**: internalize binding function property names (Ben Noordhuis) [#3060](https://github.com/nodejs/node/pull/3060) * [[`c8175fc2af`](https://github.com/nodejs/node/commit/c8175fc2af)] - **src**: internalize per-isolate string properties (Ben Noordhuis) [#3060](https://github.com/nodejs/node/pull/3060) * [[`9a593abc47`](https://github.com/nodejs/node/commit/9a593abc47)] - **src**: include signal.h in util.h (Cheng Zhao) [#3058](https://github.com/nodejs/node/pull/3058) * [[`fde0c6f321`](https://github.com/nodejs/node/commit/fde0c6f321)] - **src**: fix function and variable names in comments (Sakthipriyan Vairamani) [#3039](https://github.com/nodejs/node/pull/3039) * [[`1cc7b41ba4`](https://github.com/nodejs/node/commit/1cc7b41ba4)] - **stream_wrap**: support empty `TryWrite`s (Fedor Indutny) [#3128](https://github.com/nodejs/node/pull/3128) * [[`9faf4c6fcf`](https://github.com/nodejs/node/commit/9faf4c6fcf)] - **test**: load common.js to test for global leaks (Rich Trott) [#3095](https://github.com/nodejs/node/pull/3095) * [[`0858c86374`](https://github.com/nodejs/node/commit/0858c86374)] - **test**: fix invalid variable name (Sakthipriyan Vairamani) [#3150](https://github.com/nodejs/node/pull/3150) * [[`1167171004`](https://github.com/nodejs/node/commit/1167171004)] - **test**: change calls to deprecated util.print() (Rich Trott) [#3083](https://github.com/nodejs/node/pull/3083) * [[`5ada45bf28`](https://github.com/nodejs/node/commit/5ada45bf28)] - **test**: replace deprecated util.debug() calls (Rich Trott) [#3082](https://github.com/nodejs/node/pull/3082) * [[`d8ab4e185d`](https://github.com/nodejs/node/commit/d8ab4e185d)] - **util**: optimize promise introspection (Ben Noordhuis) [#3130](https://github.com/nodejs/node/pull/3130) ## 2015-09-22, Version 4.1.1 (Stable), @rvagg ### Notable changes * **buffer**: Fixed a bug introduced in v4.1.0 where allocating a new zero-length buffer can result in the _next_ allocation of a TypedArray in JavaScript not being zero-filled. In certain circumstances this could result in data leakage via reuse of memory space in TypedArrays, breaking the normally safe assumption that TypedArrays should be always zero-filled. (Trevor Norris) [#2931](https://github.com/nodejs/node/pull/2931). * **http**: Guard against response-splitting of HTTP trailing headers added via [`response.addTrailers()`](https://nodejs.org/api/http.html#http_response_addtrailers_headers) by removing new-line (`[\r\n]`) characters from values. Note that standard header values are already stripped of new-line characters. The expected security impact is low because trailing headers are rarely used. (Ben Noordhuis) [#2945](https://github.com/nodejs/node/pull/2945). * **npm**: Upgrade to npm 2.14.4 from 2.14.3, see [release notes](https://github.com/npm/npm/releases/tag/v2.14.4) for full details (Kat Marchán) [#2958](https://github.com/nodejs/node/pull/2958) - Upgrades `graceful-fs` on multiple dependencies to no longer rely on monkey-patching `fs` - Fix `npm link` for pre-release / RC builds of Node * **v8**: Update post-mortem metadata to allow post-mortem debugging tools to find and inspect: - JavaScript objects that use dictionary properties (Julien Gilli) [#2959](https://github.com/nodejs/node/pull/2959) - ScopeInfo and thus closures (Julien Gilli) [#2974](https://github.com/nodejs/node/pull/2974) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`d63e02e08d`](https://github.com/nodejs/node/commit/d63e02e08d)] - **buffer**: don't set zero fill for zero-length buffer (Trevor Norris) [#2931](https://github.com/nodejs/node/pull/2931) * [[`5905b14bff`](https://github.com/nodejs/node/commit/5905b14bff)] - **build**: fix icutrim when building small-icu on BE (Stewart Addison) [#2602](https://github.com/nodejs/node/pull/2602) * [[`f010cb5d96`](https://github.com/nodejs/node/commit/f010cb5d96)] - **configure**: detect mipsel host (Jérémy Lal) [#2971](https://github.com/nodejs/node/pull/2971) * [[`b93ad5abbd`](https://github.com/nodejs/node/commit/b93ad5abbd)] - **deps**: backport 357e6b9 from V8's upstream (Julien Gilli) [#2974](https://github.com/nodejs/node/pull/2974) * [[`8da3da4d41`](https://github.com/nodejs/node/commit/8da3da4d41)] - **deps**: backport ff7d70b from V8's upstream (Julien Gilli) [#2959](https://github.com/nodejs/node/pull/2959) * [[`2600fb8ae6`](https://github.com/nodejs/node/commit/2600fb8ae6)] - **deps**: upgraded to node-gyp@3.0.3 in npm (Kat Marchán) [#2958](https://github.com/nodejs/node/pull/2958) * [[`793aad2d7a`](https://github.com/nodejs/node/commit/793aad2d7a)] - **deps**: upgrade to npm 2.14.4 (Kat Marchán) [#2958](https://github.com/nodejs/node/pull/2958) * [[`43e2b7f836`](https://github.com/nodejs/node/commit/43e2b7f836)] - **doc**: remove usage of events.EventEmitter (Sakthipriyan Vairamani) [#2921](https://github.com/nodejs/node/pull/2921) * [[`9c59d2f16a`](https://github.com/nodejs/node/commit/9c59d2f16a)] - **doc**: remove extra using v8::HandleScope statement (Christopher J. Brody) [#2983](https://github.com/nodejs/node/pull/2983) * [[`f7edbab367`](https://github.com/nodejs/node/commit/f7edbab367)] - **doc**: clarify description of assert.ifError() (Rich Trott) [#2941](https://github.com/nodejs/node/pull/2941) * [[`b2ddf0f9a2`](https://github.com/nodejs/node/commit/b2ddf0f9a2)] - **doc**: refine process.kill() and exit explanations (Rich Trott) [#2918](https://github.com/nodejs/node/pull/2918) * [[`f68fed2e6f`](https://github.com/nodejs/node/commit/f68fed2e6f)] - **http**: remove redundant code in _deferToConnect (Malcolm Ahoy) [#2769](https://github.com/nodejs/node/pull/2769) * [[`f542e74c93`](https://github.com/nodejs/node/commit/f542e74c93)] - **http**: guard against response splitting in trailers (Ben Noordhuis) [#2945](https://github.com/nodejs/node/pull/2945) * [[`bc9f629387`](https://github.com/nodejs/node/commit/bc9f629387)] - **http_parser**: do not dealloc during kOnExecute (Fedor Indutny) [#2956](https://github.com/nodejs/node/pull/2956) * [[`1860e0cebd`](https://github.com/nodejs/node/commit/1860e0cebd)] - **lib,src**: remove usage of events.EventEmitter (Sakthipriyan Vairamani) [#2921](https://github.com/nodejs/node/pull/2921) * [[`d4cd5ac407`](https://github.com/nodejs/node/commit/d4cd5ac407)] - **readline**: fix tab completion bug (Matt Harrison) [#2816](https://github.com/nodejs/node/pull/2816) * [[`9760e04839`](https://github.com/nodejs/node/commit/9760e04839)] - **repl**: don't use tty control codes when $TERM is set to "dumb" (Salman Aljammaz) [#2712](https://github.com/nodejs/node/pull/2712) * [[`cb971cc97d`](https://github.com/nodejs/node/commit/cb971cc97d)] - **repl**: backslash bug fix (Sakthipriyan Vairamani) [#2968](https://github.com/nodejs/node/pull/2968) * [[`2034f68668`](https://github.com/nodejs/node/commit/2034f68668)] - **src**: honor --abort_on_uncaught_exception flag (Evan Lucas) [#2776](https://github.com/nodejs/node/pull/2776) * [[`0b1ca4a9ef`](https://github.com/nodejs/node/commit/0b1ca4a9ef)] - **src**: Add ABORT macro (Evan Lucas) [#2776](https://github.com/nodejs/node/pull/2776) * [[`4519dd00f9`](https://github.com/nodejs/node/commit/4519dd00f9)] - **test**: test sync version of mkdir & rmdir (Sakthipriyan Vairamani) [#2588](https://github.com/nodejs/node/pull/2588) * [[`816f609c8b`](https://github.com/nodejs/node/commit/816f609c8b)] - **test**: use tmpDir instead of fixtures in readdir (Sakthipriyan Vairamani) [#2587](https://github.com/nodejs/node/pull/2587) * [[`2084f52585`](https://github.com/nodejs/node/commit/2084f52585)] - **test**: test more http response splitting scenarios (Ben Noordhuis) [#2945](https://github.com/nodejs/node/pull/2945) * [[`fa08d1d8a1`](https://github.com/nodejs/node/commit/fa08d1d8a1)] - **test**: add test-spawn-cmd-named-pipe (Alexis Campailla) [#2770](https://github.com/nodejs/node/pull/2770) * [[`71b5d80682`](https://github.com/nodejs/node/commit/71b5d80682)] - **test**: make cluster tests more time tolerant (Michael Dawson) [#2891](https://github.com/nodejs/node/pull/2891) * [[`3e09dcfc32`](https://github.com/nodejs/node/commit/3e09dcfc32)] - **test**: update cwd-enoent tests for AIX (Imran Iqbal) [#2909](https://github.com/nodejs/node/pull/2909) * [[`6ea8ec1c59`](https://github.com/nodejs/node/commit/6ea8ec1c59)] - **tools**: single, cross-platform tick processor (Matt Loring) [#2868](https://github.com/nodejs/node/pull/2868) ## 2015-09-17, Version 4.1.0 (Stable), @Fishrock123 ### Notable changes * **buffer**: - Buffers are now created in JavaScript, rather than C++. This increases the speed of buffer creation (Trevor Norris) [#2866](https://github.com/nodejs/node/pull/2866). - `Buffer#slice()` now uses `Uint8Array#subarray()` internally, increasing `slice()` performance (Karl Skomski) [#2777](https://github.com/nodejs/node/pull/2777). * **fs**: - `fs.utimes()` now properly converts numeric strings, `NaN`, and `Infinity` (Yazhong Liu) [#2387](https://github.com/nodejs/node/pull/2387). - `fs.WriteStream` now implements `_writev`, allowing for super-fast bulk writes (Ron Korving) [#2167](https://github.com/nodejs/node/pull/2167). * **http**: Fixed an issue with certain `write()` sizes causing errors when using `http.request()` (Fedor Indutny) [#2824](https://github.com/nodejs/node/pull/2824). * **npm**: Upgrade to version 2.14.3, see https://github.com/npm/npm/releases/tag/v2.14.3 for more details (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822). * **src**: V8 cpu profiling no longer erroneously shows idle time (Oleksandr Chekhovskyi) [#2324](https://github.com/nodejs/node/pull/2324). * **timers**: `#ref()` and `#unref()` now return the timer they belong to (Sam Roberts) [#2905](https://github.com/nodejs/node/pull/2905). * **v8**: Lateral upgrade to 4.5.103.33 from 4.5.103.30, contains minor fixes (Ali Ijaz Sheikh) [#2870](https://github.com/nodejs/node/pull/2870). - This fixes a previously known bug where some computed object shorthand properties did not work correctly ([#2507](https://github.com/nodejs/node/issues/2507)). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`b1abe812cd`](https://github.com/nodejs/node/commit/b1abe812cd)] - Working on 4.0.1 (Rod Vagg) * [[`f9f8378853`](https://github.com/nodejs/node/commit/f9f8378853)] - 2015-09-08, Version 4.0.0 (Stable) Release (Rod Vagg) * [[`9683e5df51`](https://github.com/nodejs/node/commit/9683e5df51)] - **bindings**: close after reading module struct (Fedor Indutny) [#2792](https://github.com/nodejs/node/pull/2792) * [[`4b4cfa2d44`](https://github.com/nodejs/node/commit/4b4cfa2d44)] - **buffer**: always allocate typed arrays outside heap (Trevor Norris) [#2893](https://github.com/nodejs/node/pull/2893) * [[`7df018a29b`](https://github.com/nodejs/node/commit/7df018a29b)] - **buffer**: construct Uint8Array in JS (Trevor Norris) [#2866](https://github.com/nodejs/node/pull/2866) * [[`43397b204e`](https://github.com/nodejs/node/commit/43397b204e)] - **(SEMVER-MINOR)** **build**: Updates to enable AIX support (Michael Dawson) [#2364](https://github.com/nodejs/node/pull/2364) * [[`e35b1fd610`](https://github.com/nodejs/node/commit/e35b1fd610)] - **build**: clean up the generated tap file (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) * [[`96670ebe37`](https://github.com/nodejs/node/commit/96670ebe37)] - **deps**: backport 6d32be2 from v8's upstream (Michaël Zasso) [#2916](https://github.com/nodejs/node/pull/2916) * [[`94972d5b13`](https://github.com/nodejs/node/commit/94972d5b13)] - **deps**: backport 0d01728 from v8's upstream (Fedor Indutny) [#2912](https://github.com/nodejs/node/pull/2912) * [[`7ebd881c29`](https://github.com/nodejs/node/commit/7ebd881c29)] - **deps**: upgrade V8 to 4.5.103.33 (Ali Ijaz Sheikh) [#2870](https://github.com/nodejs/node/pull/2870) * [[`ed47ab6e44`](https://github.com/nodejs/node/commit/ed47ab6e44)] - **deps**: upgraded to node-gyp@3.0.3 in npm (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) * [[`f4641ae875`](https://github.com/nodejs/node/commit/f4641ae875)] - **deps**: upgrade to npm 2.14.3 (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) * [[`8119693a3d`](https://github.com/nodejs/node/commit/8119693a3d)] - **deps**: update libuv to version 1.7.4 (Saúl Ibarra Corretgé) [#2817](https://github.com/nodejs/node/pull/2817) * [[`6098504685`](https://github.com/nodejs/node/commit/6098504685)] - **deps**: cherry-pick 6da51b4 from v8's upstream (Fedor Indutny) [#2801](https://github.com/nodejs/node/pull/2801) * [[`bf42cc8dba`](https://github.com/nodejs/node/commit/bf42cc8dba)] - **doc**: process exit event is not guaranteed to fire (Rich Trott) [#2861](https://github.com/nodejs/node/pull/2861) * [[`bb0f869f67`](https://github.com/nodejs/node/commit/bb0f869f67)] - **doc**: remove incorrect reference to TCP in net docs (Sam Roberts) [#2903](https://github.com/nodejs/node/pull/2903) * [[`302d59dce8`](https://github.com/nodejs/node/commit/302d59dce8)] - **doc**: correct buffer.slice arg syntax (Sam Roberts) [#2903](https://github.com/nodejs/node/pull/2903) * [[`74db9637b7`](https://github.com/nodejs/node/commit/74db9637b7)] - **doc**: describe spawn option.detached (Sam Roberts) [#2903](https://github.com/nodejs/node/pull/2903) * [[`a7bd897273`](https://github.com/nodejs/node/commit/a7bd897273)] - **doc**: rename from iojs(1) to node(1) in benchmarks (Dmitry Vasilyev) [#2884](https://github.com/nodejs/node/pull/2884) * [[`cd643d7c37`](https://github.com/nodejs/node/commit/cd643d7c37)] - **doc**: add missing backtick in buffer.markdown (Sven Slootweg) [#2881](https://github.com/nodejs/node/pull/2881) * [[`e8a206e802`](https://github.com/nodejs/node/commit/e8a206e802)] - **doc**: fix broken link in repl.markdown (Danny Nemer) [#2827](https://github.com/nodejs/node/pull/2827) * [[`7ee36d61f7`](https://github.com/nodejs/node/commit/7ee36d61f7)] - **doc**: fix typos in README (Ionică Bizău) [#2852](https://github.com/nodejs/node/pull/2852) * [[`4d1ae26196`](https://github.com/nodejs/node/commit/4d1ae26196)] - **doc**: add tunniclm as a collaborator (Mike Tunnicliffe) [#2826](https://github.com/nodejs/node/pull/2826) * [[`2d77d03643`](https://github.com/nodejs/node/commit/2d77d03643)] - **doc**: fix two doc errors in stream and process (Jeremiah Senkpiel) [#2549](https://github.com/nodejs/node/pull/2549) * [[`55ac24f721`](https://github.com/nodejs/node/commit/55ac24f721)] - **doc**: fixed io.js references in process.markdown (Tristian Flanagan) [#2846](https://github.com/nodejs/node/pull/2846) * [[`cd1297fb57`](https://github.com/nodejs/node/commit/cd1297fb57)] - **doc**: use "Calls" over "Executes" for consistency (Minwoo Jung) [#2800](https://github.com/nodejs/node/pull/2800) * [[`d664b95581`](https://github.com/nodejs/node/commit/d664b95581)] - **doc**: use US English for consistency (Anne-Gaelle Colom) [#2784](https://github.com/nodejs/node/pull/2784) * [[`82ba1839fb`](https://github.com/nodejs/node/commit/82ba1839fb)] - **doc**: use 3rd person singular for consistency (Anne-Gaelle Colom) [#2765](https://github.com/nodejs/node/pull/2765) * [[`432cce6e95`](https://github.com/nodejs/node/commit/432cce6e95)] - **doc**: describe process API for IPC (Sam Roberts) [#1978](https://github.com/nodejs/node/pull/1978) * [[`1d75012b9d`](https://github.com/nodejs/node/commit/1d75012b9d)] - **doc**: fix comma splice in Assertion Testing doc (Rich Trott) [#2728](https://github.com/nodejs/node/pull/2728) * [[`6108ea9bb4`](https://github.com/nodejs/node/commit/6108ea9bb4)] - **fs**: consider NaN/Infinity in toUnixTimestamp (Yazhong Liu) [#2387](https://github.com/nodejs/node/pull/2387) * [[`2b6aa9415f`](https://github.com/nodejs/node/commit/2b6aa9415f)] - **(SEMVER-MINOR)** **fs**: implemented WriteStream#writev (Ron Korving) [#2167](https://github.com/nodejs/node/pull/2167) * [[`431bf74c55`](https://github.com/nodejs/node/commit/431bf74c55)] - **http**: default Agent.getName to 'localhost' (Malcolm Ahoy) [#2825](https://github.com/nodejs/node/pull/2825) * [[`ea15d71c16`](https://github.com/nodejs/node/commit/ea15d71c16)] - **http_server**: fix resume after socket close (Fedor Indutny) [#2824](https://github.com/nodejs/node/pull/2824) * [[`8e5843405b`](https://github.com/nodejs/node/commit/8e5843405b)] - **src**: null env_ field from constructor (Trevor Norris) [#2913](https://github.com/nodejs/node/pull/2913) * [[`0a5f80a11f`](https://github.com/nodejs/node/commit/0a5f80a11f)] - **src**: use subarray() in Buffer#slice() for speedup (Karl Skomski) [#2777](https://github.com/nodejs/node/pull/2777) * [[`57707e2490`](https://github.com/nodejs/node/commit/57707e2490)] - **src**: use ZCtxt as a source for v8::Isolates (Roman Klauke) [#2547](https://github.com/nodejs/node/pull/2547) * [[`b0df2273ab`](https://github.com/nodejs/node/commit/b0df2273ab)] - **src**: fix v8::CpuProfiler idle sampling (Oleksandr Chekhovskyi) [#2324](https://github.com/nodejs/node/pull/2324) * [[`eaa8e60b91`](https://github.com/nodejs/node/commit/eaa8e60b91)] - **streams**: refactor LazyTransform to internal/ (Brendan Ashworth) [#2566](https://github.com/nodejs/node/pull/2566) * [[`648c003e14`](https://github.com/nodejs/node/commit/648c003e14)] - **test**: use tmp directory in chdir test (Sakthipriyan Vairamani) [#2589](https://github.com/nodejs/node/pull/2589) * [[`079a2173d4`](https://github.com/nodejs/node/commit/079a2173d4)] - **test**: fix Buffer OOM error message (Trevor Norris) [#2915](https://github.com/nodejs/node/pull/2915) * [[`52019a1b21`](https://github.com/nodejs/node/commit/52019a1b21)] - **test**: fix default value for additional param (Sakthipriyan Vairamani) [#2553](https://github.com/nodejs/node/pull/2553) * [[`5df5d0423a`](https://github.com/nodejs/node/commit/5df5d0423a)] - **test**: remove disabled test (Rich Trott) [#2841](https://github.com/nodejs/node/pull/2841) * [[`9e5f0995bd`](https://github.com/nodejs/node/commit/9e5f0995bd)] - **test**: split up internet dns tests (Rich Trott) [#2802](https://github.com/nodejs/node/pull/2802) * [[`41f2dde51a`](https://github.com/nodejs/node/commit/41f2dde51a)] - **test**: increase dgram timeout for armv6 (Rich Trott) [#2808](https://github.com/nodejs/node/pull/2808) * [[`6e2fe1c21a`](https://github.com/nodejs/node/commit/6e2fe1c21a)] - **test**: remove valid hostname check in test-dns.js (Rich Trott) [#2785](https://github.com/nodejs/node/pull/2785) * [[`779e14f1a7`](https://github.com/nodejs/node/commit/779e14f1a7)] - **test**: expect error for test_lookup_ipv6_hint on FreeBSD (Rich Trott) [#2724](https://github.com/nodejs/node/pull/2724) * [[`f931b9dd95`](https://github.com/nodejs/node/commit/f931b9dd95)] - **(SEMVER-MINOR)** **timer**: ref/unref return self (Sam Roberts) [#2905](https://github.com/nodejs/node/pull/2905) * [[`59d03738cc`](https://github.com/nodejs/node/commit/59d03738cc)] - **tools**: enable arrow functions in .eslintrc (Sakthipriyan Vairamani) [#2840](https://github.com/nodejs/node/pull/2840) * [[`69e7b875a2`](https://github.com/nodejs/node/commit/69e7b875a2)] - **tools**: open `test.tap` file in write-binary mode (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) * [[`ff6d30d784`](https://github.com/nodejs/node/commit/ff6d30d784)] - **tools**: add missing tick processor polyfill (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) * [[`519caba021`](https://github.com/nodejs/node/commit/519caba021)] - **tools**: fix flakiness in test-tick-processor (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) * [[`ac004b8555`](https://github.com/nodejs/node/commit/ac004b8555)] - **tools**: remove hyphen in TAP result (Sakthipriyan Vairamani) [#2718](https://github.com/nodejs/node/pull/2718) * [[`ba47511976`](https://github.com/nodejs/node/commit/ba47511976)] - **tsc**: adjust TSC membership for IBM+StrongLoop (James M Snell) [#2858](https://github.com/nodejs/node/pull/2858) * [[`e035266805`](https://github.com/nodejs/node/commit/e035266805)] - **win,msi**: fix documentation shortcut url (Brian White) [#2781](https://github.com/nodejs/node/pull/2781) ## 2015-09-08, Version 4.0.0 (Stable), @rvagg ### Notable changes This list of changes is relative to the last io.js v3.x branch release, v3.3.0. Please see the list of notable changes in the v3.x, v2.x and v1.x releases for a more complete list of changes from 0.12.x. Note, that some changes in the v3.x series as well as major breaking changes in this release constitute changes required for full convergence of the Node.js and io.js projects. * **child_process**: `ChildProcess.prototype.send()` and `process.send()` operate asynchronously across all platforms so an optional callback parameter has been introduced that will be invoked once the message has been sent, i.e. `.send(message[, sendHandle][, callback])` (Ben Noordhuis) [#2620](https://github.com/nodejs/node/pull/2620). * **node**: Rename "io.js" code to "Node.js" (cjihrig) [#2367](https://github.com/nodejs/node/pull/2367). * **node-gyp**: This release bundles an updated version of node-gyp that works with all versions of Node.js and io.js including nightly and release candidate builds. From io.js v3 and Node.js v4 onward, it will only download a headers tarball when building addons rather than the entire source. (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) * **npm**: Upgrade to version 2.14.2 from 2.13.3, includes a security update, see https://github.com/npm/npm/releases/tag/v2.14.2 for more details, (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696). * **timers**: Improved timer performance from porting the 0.12 implementation, plus minor fixes (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540), (Julien Gilli) [nodejs/node-v0.x-archive#8751](https://github.com/nodejs/node-v0.x-archive/pull/8751) [nodejs/node-v0.x-archive#8905](https://github.com/nodejs/node-v0.x-archive/pull/8905) * **util**: The `util.is*()` functions have been deprecated, beginning with deprecation warnings in the documentation for this release, users are encouraged to seek more robust alternatives in the npm registry, (Sakthipriyan Vairamani) [#2447](https://github.com/nodejs/node/pull/2447). * **v8**: Upgrade to version 4.5.103.30 from 4.4.63.30 (Ali Ijaz Sheikh) [#2632](https://github.com/nodejs/node/pull/2632). - Implement new `TypedArray` prototype methods: `copyWithin()`, `every()`, `fill()`, `filter()`, `find()`, `findIndex()`, `forEach()`, `indexOf()`, `join()`, `lastIndexOf()`, `map()`, `reduce()`, `reduceRight()`, `reverse()`, `slice()`, `some()`, `sort()`. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray for further information. - Implement new `TypedArray.from()` and `TypedArray.of()` functions. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray for further information. - Implement arrow functions, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions for further information. - Full ChangeLog available at https://github.com/v8/v8-git-mirror/blob/4.5.103/ChangeLog ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`4f50d3fb90`](https://github.com/nodejs/node/commit/4f50d3fb90)] - **(SEMVER-MAJOR)** This commit sets the value of process.release.name to "node". (cjihrig) [#2367](https://github.com/nodejs/node/pull/2367) * [[`d3178d8b1b`](https://github.com/nodejs/node/commit/d3178d8b1b)] - **buffer**: SlowBuffer only accept valid numeric values (Michaël Zasso) [#2635](https://github.com/nodejs/node/pull/2635) * [[`0cb0f4a6e4`](https://github.com/nodejs/node/commit/0cb0f4a6e4)] - **build**: fix v8_enable_handle_zapping override (Karl Skomski) [#2731](https://github.com/nodejs/node/pull/2731) * [[`a7596d7efc`](https://github.com/nodejs/node/commit/a7596d7efc)] - **build**: remote commands on staging in single session (Rod Vagg) [#2717](https://github.com/nodejs/node/pull/2717) * [[`be427e9efa`](https://github.com/nodejs/node/commit/be427e9efa)] - **build**: make .msi install to "nodejs", not "node" (Rod Vagg) [#2701](https://github.com/nodejs/node/pull/2701) * [[`5652ce0dbc`](https://github.com/nodejs/node/commit/5652ce0dbc)] - **build**: fix .pkg creation tooling (Rod Vagg) [#2687](https://github.com/nodejs/node/pull/2687) * [[`101db80111`](https://github.com/nodejs/node/commit/101db80111)] - **build**: add --enable-asan with builtin leakcheck (Karl Skomski) [#2376](https://github.com/nodejs/node/pull/2376) * [[`2c3939c9c0`](https://github.com/nodejs/node/commit/2c3939c9c0)] - **child_process**: use stdio.fd even if it is 0 (Evan Lucas) [#2727](https://github.com/nodejs/node/pull/2727) * [[`609db5a1dd`](https://github.com/nodejs/node/commit/609db5a1dd)] - **child_process**: check execFile and fork args (James M Snell) [#2667](https://github.com/nodejs/node/pull/2667) * [[`d010568c23`](https://github.com/nodejs/node/commit/d010568c23)] - **(SEMVER-MAJOR)** **child_process**: add callback parameter to .send() (Ben Noordhuis) [#2620](https://github.com/nodejs/node/pull/2620) * [[`c60857a81a`](https://github.com/nodejs/node/commit/c60857a81a)] - **cluster**: allow shared reused dgram sockets (Fedor Indutny) [#2548](https://github.com/nodejs/node/pull/2548) * [[`b2ecbb6191`](https://github.com/nodejs/node/commit/b2ecbb6191)] - **contextify**: ignore getters during initialization (Fedor Indutny) [#2091](https://github.com/nodejs/node/pull/2091) * [[`3711934095`](https://github.com/nodejs/node/commit/3711934095)] - **cpplint**: make it possible to run outside git repo (Ben Noordhuis) [#2710](https://github.com/nodejs/node/pull/2710) * [[`03f900ab25`](https://github.com/nodejs/node/commit/03f900ab25)] - **crypto**: replace rwlocks with simple mutexes (Ben Noordhuis) [#2723](https://github.com/nodejs/node/pull/2723) * [[`847459c29b`](https://github.com/nodejs/node/commit/847459c29b)] - **(SEMVER-MAJOR)** **crypto**: show exponent in decimal and hex (Chad Johnston) [#2320](https://github.com/nodejs/node/pull/2320) * [[`e1c976184d`](https://github.com/nodejs/node/commit/e1c976184d)] - **deps**: improve ArrayBuffer performance in v8 (Fedor Indutny) [#2732](https://github.com/nodejs/node/pull/2732) * [[`cc0ab17a23`](https://github.com/nodejs/node/commit/cc0ab17a23)] - **deps**: float node-gyp v3.0.0 (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) * [[`b2c3c6d727`](https://github.com/nodejs/node/commit/b2c3c6d727)] - **deps**: create .npmrc during npm tests (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) * [[`babdbfdbd5`](https://github.com/nodejs/node/commit/babdbfdbd5)] - **deps**: upgrade to npm 2.14.2 (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) * [[`155783d876`](https://github.com/nodejs/node/commit/155783d876)] - **deps**: backport 75e43a6 from v8 upstream (again) (saper) [#2692](https://github.com/nodejs/node/pull/2692) * [[`5424d6fcf0`](https://github.com/nodejs/node/commit/5424d6fcf0)] - **deps**: upgrade V8 to 4.5.103.30 (Ali Ijaz Sheikh) [#2632](https://github.com/nodejs/node/pull/2632) * [[`c43172578e`](https://github.com/nodejs/node/commit/c43172578e)] - **(SEMVER-MAJOR)** **deps**: upgrade V8 to 4.5.103.24 (Ali Ijaz Sheikh) [#2509](https://github.com/nodejs/node/pull/2509) * [[`714e96e8b9`](https://github.com/nodejs/node/commit/714e96e8b9)] - **deps**: backport 75e43a6 from v8 upstream (saper) [#2636](https://github.com/nodejs/node/pull/2636) * [[`8637755cbf`](https://github.com/nodejs/node/commit/8637755cbf)] - **doc**: add TSC meeting minutes 2015-09-02 (Rod Vagg) [#2674](https://github.com/nodejs/node/pull/2674) * [[`d3d5b93214`](https://github.com/nodejs/node/commit/d3d5b93214)] - **doc**: update environment vars in manpage and --help (Roman Reiss) [#2690](https://github.com/nodejs/node/pull/2690) * [[`29f586ac0a`](https://github.com/nodejs/node/commit/29f586ac0a)] - **doc**: update url doc to account for escaping (Jeremiah Senkpiel) [#2605](https://github.com/nodejs/node/pull/2605) * [[`ba50cfebef`](https://github.com/nodejs/node/commit/ba50cfebef)] - **doc**: reorder collaborators by their usernames (Johan Bergström) [#2322](https://github.com/nodejs/node/pull/2322) * [[`8a9a3bf798`](https://github.com/nodejs/node/commit/8a9a3bf798)] - **doc**: update changelog for io.js v3.3.0 (Rod Vagg) [#2653](https://github.com/nodejs/node/pull/2653) * [[`6cd0e2664b`](https://github.com/nodejs/node/commit/6cd0e2664b)] - **doc**: update io.js reference (Ben Noordhuis) [#2580](https://github.com/nodejs/node/pull/2580) * [[`f9539c19e8`](https://github.com/nodejs/node/commit/f9539c19e8)] - **doc**: update changelog for io.js v3.2.0 (Rod Vagg) [#2512](https://github.com/nodejs/node/pull/2512) * [[`cded6e7993`](https://github.com/nodejs/node/commit/cded6e7993)] - **doc**: fix CHANGELOG.md on master (Roman Reiss) [#2513](https://github.com/nodejs/node/pull/2513) * [[`93e2830686`](https://github.com/nodejs/node/commit/93e2830686)] - **(SEMVER-MINOR)** **doc**: document deprecation of util.is* functions (Sakthipriyan Vairamani) [#2447](https://github.com/nodejs/node/pull/2447) * [[`7038388558`](https://github.com/nodejs/node/commit/7038388558)] - **doc,test**: enable recursive file watching in Windows (Sakthipriyan Vairamani) [#2649](https://github.com/nodejs/node/pull/2649) * [[`f3696f64a1`](https://github.com/nodejs/node/commit/f3696f64a1)] - **events,lib**: don't require EE#listenerCount() (Jeremiah Senkpiel) [#2661](https://github.com/nodejs/node/pull/2661) * [[`45a2046f5d`](https://github.com/nodejs/node/commit/45a2046f5d)] - **(SEMVER-MAJOR)** **installer**: fix installers for node.js rename (Frederic Hemberger) [#2367](https://github.com/nodejs/node/pull/2367) * [[`7a999a1376`](https://github.com/nodejs/node/commit/7a999a1376)] - **(SEMVER-MAJOR)** **lib**: add net.Socket#localFamily property (Ben Noordhuis) [#956](https://github.com/nodejs/node/pull/956) * [[`de88255b0f`](https://github.com/nodejs/node/commit/de88255b0f)] - ***Revert*** "**lib,src**: add unix socket getsockname/getpeername" (Ben Noordhuis) [#2584](https://github.com/nodejs/node/pull/2584) * [[`f337595441`](https://github.com/nodejs/node/commit/f337595441)] - **(SEMVER-MAJOR)** **lib,src**: add unix socket getsockname/getpeername (Ben Noordhuis) [#956](https://github.com/nodejs/node/pull/956) * [[`3b602527d1`](https://github.com/nodejs/node/commit/3b602527d1)] - **(SEMVER-MAJOR)** **node**: additional cleanup for node rename (cjihrig) [#2367](https://github.com/nodejs/node/pull/2367) * [[`a69ab27ab4`](https://github.com/nodejs/node/commit/a69ab27ab4)] - **(SEMVER-MAJOR)** **node**: rename from io.js to node (cjihrig) [#2367](https://github.com/nodejs/node/pull/2367) * [[`9358eee9dd`](https://github.com/nodejs/node/commit/9358eee9dd)] - **node-gyp**: float 3.0.1, minor fix for download url (Rod Vagg) [#2737](https://github.com/nodejs/node/pull/2737) * [[`d2d981252b`](https://github.com/nodejs/node/commit/d2d981252b)] - **src**: s/ia32/x86 for process.release.libUrl for win (Rod Vagg) [#2699](https://github.com/nodejs/node/pull/2699) * [[`eba3d3dccd`](https://github.com/nodejs/node/commit/eba3d3dccd)] - **src**: use standard conform snprintf on windows (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) * [[`cddbec231f`](https://github.com/nodejs/node/commit/cddbec231f)] - **src**: fix buffer overflow for long exception lines (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) * [[`dd3f3417c7`](https://github.com/nodejs/node/commit/dd3f3417c7)] - **src**: re-enable fast math on arm (Michaël Zasso) [#2592](https://github.com/nodejs/node/pull/2592) * [[`e137c1177c`](https://github.com/nodejs/node/commit/e137c1177c)] - **(SEMVER-MAJOR)** **src**: enable vector ics on arm again (Ali Ijaz Sheikh) [#2509](https://github.com/nodejs/node/pull/2509) * [[`7ce749d722`](https://github.com/nodejs/node/commit/7ce749d722)] - **src**: replace usage of v8::Handle with v8::Local (Michaël Zasso) [#2202](https://github.com/nodejs/node/pull/2202) * [[`b1a2d9509f`](https://github.com/nodejs/node/commit/b1a2d9509f)] - **src**: enable v8 deprecation warnings and fix them (Ben Noordhuis) [#2091](https://github.com/nodejs/node/pull/2091) * [[`808de0da03`](https://github.com/nodejs/node/commit/808de0da03)] - **(SEMVER-MAJOR)** **src**: apply debug force load fixups from 41e63fb (Ali Ijaz Sheikh) [#2509](https://github.com/nodejs/node/pull/2509) * [[`5201cb0ff1`](https://github.com/nodejs/node/commit/5201cb0ff1)] - **src**: fix memory leak in ExternString (Karl Skomski) [#2402](https://github.com/nodejs/node/pull/2402) * [[`2308a27c0a`](https://github.com/nodejs/node/commit/2308a27c0a)] - **src**: only set v8 flags if argc > 1 (Evan Lucas) [#2646](https://github.com/nodejs/node/pull/2646) * [[`384effed20`](https://github.com/nodejs/node/commit/384effed20)] - **test**: fix use of `common` before required (Rod Vagg) [#2685](https://github.com/nodejs/node/pull/2685) * [[`f146f686b7`](https://github.com/nodejs/node/commit/f146f686b7)] - **(SEMVER-MAJOR)** **test**: fix test-repl-tab-complete.js for V8 4.5 (Ali Ijaz Sheikh) [#2509](https://github.com/nodejs/node/pull/2509) * [[`fe4b309fd3`](https://github.com/nodejs/node/commit/fe4b309fd3)] - **test**: refactor to eliminate flaky test (Rich Trott) [#2609](https://github.com/nodejs/node/pull/2609) * [[`619721e6b8`](https://github.com/nodejs/node/commit/619721e6b8)] - **test**: mark eval_messages as flaky (Alexis Campailla) [#2648](https://github.com/nodejs/node/pull/2648) * [[`93ba585b66`](https://github.com/nodejs/node/commit/93ba585b66)] - **test**: mark test-vm-syntax-error-stderr as flaky (João Reis) [#2662](https://github.com/nodejs/node/pull/2662) * [[`367140bca0`](https://github.com/nodejs/node/commit/367140bca0)] - **test**: mark test-repl-persistent-history as flaky (João Reis) [#2659](https://github.com/nodejs/node/pull/2659) * [[`f6b093343d`](https://github.com/nodejs/node/commit/f6b093343d)] - **timers**: minor `_unrefActive` fixes and improvements (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540) * [[`403d7ee7d1`](https://github.com/nodejs/node/commit/403d7ee7d1)] - **timers**: don't mutate unref list while iterating it (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) * [[`7a8c3e08c3`](https://github.com/nodejs/node/commit/7a8c3e08c3)] - **timers**: Avoid linear scan in `_unrefActive`. (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) * [[`b630ebaf43`](https://github.com/nodejs/node/commit/b630ebaf43)] - **win,msi**: Upgrade from old upgrade code (João Reis) [#2439](https://github.com/nodejs/node/pull/2439) ## 2015-09-02, Version 3.3.0, @rvagg ### Notable changes * **build**: Add a `--link-module` option to `configure` that can be used to bundle additional JavaScript modules into a built binary (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) * **docs**: Merge outstanding doc updates from joyent/node (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * **http_parser**: Significant performance improvement by having `http.Server` consume all initial data from its `net.Socket` and parsing directly without having to enter JavaScript. Any `'data'` listeners on the `net.Socket` will result in the data being "unconsumed" into JavaScript, thereby undoing any performance gains. (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) * **libuv**: Upgrade to 1.7.3 (from 1.6.1), see [ChangeLog](https://github.com/libuv/libuv/blob/v1.x/ChangeLog) for details (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) * **V8**: Upgrade to 4.4.63.30 (from 4.4.63.26) (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) ### Known issues See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). ### Commits * [[`1a531b4e44`](https://github.com/nodejs/node/commit/1a531b4e44)] - **(SEMVER-MINOR)** Introduce --link-module to ./configure (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) * [[`d2f314c190`](https://github.com/nodejs/node/commit/d2f314c190)] - **build**: fix borked chmod call for release uploads (Rod Vagg) [#2645](https://github.com/nodejs/node/pull/2645) * [[`3172e9c541`](https://github.com/nodejs/node/commit/3172e9c541)] - **build**: set file permissions before uploading (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) * [[`a860d7fae1`](https://github.com/nodejs/node/commit/a860d7fae1)] - **build**: change staging directory on new server (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) * [[`50c0baa8d7`](https://github.com/nodejs/node/commit/50c0baa8d7)] - **build**: rename 'doc' directory to 'docs' for upload (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) * [[`0a0577cf5f`](https://github.com/nodejs/node/commit/0a0577cf5f)] - **build**: fix bad cherry-pick for vcbuild.bat build-release (Rod Vagg) [#2625](https://github.com/nodejs/node/pull/2625) * [[`34de90194b`](https://github.com/nodejs/node/commit/34de90194b)] - **build**: only define NODE_V8_OPTIONS if not empty (Evan Lucas) [#2532](https://github.com/nodejs/node/pull/2532) * [[`944174b189`](https://github.com/nodejs/node/commit/944174b189)] - **build**: make ci test addons in test/addons (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) * [[`e955f9a1b0`](https://github.com/nodejs/node/commit/e955f9a1b0)] - **crypto**: Use OPENSSL_cleanse to shred the data. (Сковорода Никита Андреевич) [#2575](https://github.com/nodejs/node/pull/2575) * [[`395d736b9d`](https://github.com/nodejs/node/commit/395d736b9d)] - **debugger**: use strict equality comparison (Minwoo Jung) [#2558](https://github.com/nodejs/node/pull/2558) * [[`1d0e5210a8`](https://github.com/nodejs/node/commit/1d0e5210a8)] - **deps**: upgrade libuv to 1.7.3 (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) * [[`34ef53364f`](https://github.com/nodejs/node/commit/34ef53364f)] - **deps**: update V8 to 4.4.63.30 (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) * [[`23579a5f4a`](https://github.com/nodejs/node/commit/23579a5f4a)] - **doc**: add TSC meeting minutes 2015-08-12 (Rod Vagg) [#2438](https://github.com/nodejs/node/pull/2438) * [[`0cc59299a4`](https://github.com/nodejs/node/commit/0cc59299a4)] - **doc**: add TSC meeting minutes 2015-08-26 (Rod Vagg) [#2591](https://github.com/nodejs/node/pull/2591) * [[`6efa96e33a`](https://github.com/nodejs/node/commit/6efa96e33a)] - **doc**: merge CHANGELOG.md with joyent/node ChangeLog (P.S.V.R) [#2536](https://github.com/nodejs/node/pull/2536) * [[`f75d54607b`](https://github.com/nodejs/node/commit/f75d54607b)] - **doc**: clarify cluster behaviour with no workers (Jeremiah Senkpiel) [#2606](https://github.com/nodejs/node/pull/2606) * [[`8936302121`](https://github.com/nodejs/node/commit/8936302121)] - **doc**: minor clarification in buffer.markdown (Сковорода Никита Андреевич) [#2574](https://github.com/nodejs/node/pull/2574) * [[`0db0e53753`](https://github.com/nodejs/node/commit/0db0e53753)] - **doc**: add @jasnell and @sam-github to release team (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) * [[`c16e100593`](https://github.com/nodejs/node/commit/c16e100593)] - **doc**: reorg release team to separate section (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) * [[`e3e00143fd`](https://github.com/nodejs/node/commit/e3e00143fd)] - **doc**: fix bad merge on modules.markdown (James M Snell) * [[`2f62455880`](https://github.com/nodejs/node/commit/2f62455880)] - **doc**: minor additional corrections and improvements (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`3bd08aac4b`](https://github.com/nodejs/node/commit/3bd08aac4b)] - **doc**: minor grammatical update in crypto.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`f707189370`](https://github.com/nodejs/node/commit/f707189370)] - **doc**: minor grammatical update (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`6c98cf0266`](https://github.com/nodejs/node/commit/6c98cf0266)] - **doc**: remove repeated statement in globals.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`48e6ccf8c2`](https://github.com/nodejs/node/commit/48e6ccf8c2)] - **doc**: remove 'dudes' from documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`b5d68f8076`](https://github.com/nodejs/node/commit/b5d68f8076)] - **doc**: update tense in child_process.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`242e3fe3ba`](https://github.com/nodejs/node/commit/242e3fe3ba)] - **doc**: fixed worker.id type (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`ea9ee15c21`](https://github.com/nodejs/node/commit/ea9ee15c21)] - **doc**: port is optional for socket.bind() (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`0ff6657a50`](https://github.com/nodejs/node/commit/0ff6657a50)] - **doc**: fix minor types and grammar in fs docs (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`94d83c04f2`](https://github.com/nodejs/node/commit/94d83c04f2)] - **doc**: update parameter name in net.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`04111ce40f`](https://github.com/nodejs/node/commit/04111ce40f)] - **doc**: small typo in domain.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`c9fdd1bbbf`](https://github.com/nodejs/node/commit/c9fdd1bbbf)] - **doc**: fixed typo in net.markdown (missing comma) (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`27c07b3f8e`](https://github.com/nodejs/node/commit/27c07b3f8e)] - **doc**: update description of fs.exists in fs.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`52018e73d9`](https://github.com/nodejs/node/commit/52018e73d9)] - **doc**: clarification on the 'close' event (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`f6d3b87a25`](https://github.com/nodejs/node/commit/f6d3b87a25)] - **doc**: improve working in stream.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`b5da89431a`](https://github.com/nodejs/node/commit/b5da89431a)] - **doc**: update path.extname documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`1d4ea609db`](https://github.com/nodejs/node/commit/1d4ea609db)] - **doc**: small clarifications to modules.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`c888985591`](https://github.com/nodejs/node/commit/c888985591)] - **doc**: code style cleanups in repl.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`105b493595`](https://github.com/nodejs/node/commit/105b493595)] - **doc**: correct grammar in cluster.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`51b86ccac7`](https://github.com/nodejs/node/commit/51b86ccac7)] - **doc**: Clarify the module.parent is set once (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) * [[`d2ffecba2d`](https://github.com/nodejs/node/commit/d2ffecba2d)] - **doc**: add internal modules notice (Jeremiah Senkpiel) [#2523](https://github.com/nodejs/node/pull/2523) * [[`b36debd5cb`](https://github.com/nodejs/node/commit/b36debd5cb)] - **env**: introduce `KickNextTick` (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) * [[`1bc446863f`](https://github.com/nodejs/node/commit/1bc446863f)] - **http_parser**: consume StreamBase instance (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) * [[`ce04b735cc`](https://github.com/nodejs/node/commit/ce04b735cc)] - **src**: only memcmp if length > 0 in Buffer::Compare (Karl Skomski) [#2544](https://github.com/nodejs/node/pull/2544) * [[`31823e37c7`](https://github.com/nodejs/node/commit/31823e37c7)] - **src**: DRY getsockname/getpeername code (Ben Noordhuis) [#956](https://github.com/nodejs/node/pull/956) * [[`13fd96dda3`](https://github.com/nodejs/node/commit/13fd96dda3)] - **src**: missing Exception::Error in node_http_parser (Jeremiah Senkpiel) [#2550](https://github.com/nodejs/node/pull/2550) * [[`42e075ae02`](https://github.com/nodejs/node/commit/42e075ae02)] - **test**: improve performance of stringbytes test (Trevor Norris) [#2544](https://github.com/nodejs/node/pull/2544) * [[`fc726399fd`](https://github.com/nodejs/node/commit/fc726399fd)] - **test**: unmark test-process-argv-0.js as flaky (Rich Trott) [#2613](https://github.com/nodejs/node/pull/2613) * [[`7727ba1394`](https://github.com/nodejs/node/commit/7727ba1394)] - **test**: lint and refactor to avoid autocrlf issue (Roman Reiss) [#2494](https://github.com/nodejs/node/pull/2494) * [[`c56aa829f0`](https://github.com/nodejs/node/commit/c56aa829f0)] - **test**: use tmpDir instead of fixturesDir (Sakthipriyan Vairamani) [#2583](https://github.com/nodejs/node/pull/2583) * [[`5e65181ea4`](https://github.com/nodejs/node/commit/5e65181ea4)] - **test**: handling failure cases properly (Sakthipriyan Vairamani) [#2206](https://github.com/nodejs/node/pull/2206) * [[`c48b95e847`](https://github.com/nodejs/node/commit/c48b95e847)] - **test**: initial list of flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`94e88498ba`](https://github.com/nodejs/node/commit/94e88498ba)] - **test**: pass args to test-ci via env variable (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`09987c7a1c`](https://github.com/nodejs/node/commit/09987c7a1c)] - **test**: support flaky tests in test-ci (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`08b83c8b45`](https://github.com/nodejs/node/commit/08b83c8b45)] - **test**: add test configuration templates (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`8f8ab6fa57`](https://github.com/nodejs/node/commit/8f8ab6fa57)] - **test**: runner should return 0 on flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`0cfd3be9c6`](https://github.com/nodejs/node/commit/0cfd3be9c6)] - **test**: runner support for flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) * [[`3492d2d4c6`](https://github.com/nodejs/node/commit/3492d2d4c6)] - **test**: make test-process-argv-0 robust (Rich Trott) [#2541](https://github.com/nodejs/node/pull/2541) * [[`a96cc31710`](https://github.com/nodejs/node/commit/a96cc31710)] - **test**: speed up test-child-process-spawnsync.js (Rich Trott) [#2542](https://github.com/nodejs/node/pull/2542) * [[`856baf4c67`](https://github.com/nodejs/node/commit/856baf4c67)] - **test**: make spawnSync() test robust (Rich Trott) [#2535](https://github.com/nodejs/node/pull/2535) * [[`3aa6bbb648`](https://github.com/nodejs/node/commit/3aa6bbb648)] - **tools**: update release.sh to work with new website (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) * [[`f2f0fe45ff`](https://github.com/nodejs/node/commit/f2f0fe45ff)] - **tools**: make add-on scraper print filenames (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) * [[`bb24c4a418`](https://github.com/nodejs/node/commit/bb24c4a418)] - **win,msi**: correct installation path registry keys (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) * [[`752977b888`](https://github.com/nodejs/node/commit/752977b888)] - **win,msi**: change InstallScope to perMachine (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) ## 2015-08-25, Version 3.2.0, @rvagg ### Notable changes * **events**: Added `EventEmitter#listenerCount(event)` as a replacement for `EventEmitter.listenerCount(emitter, event)`, which has now been marked as deprecated in the docs. (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) * **module**: Fixed an error with preloaded modules when the current working directory doesn't exist. (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) * **node**: Startup time is now about 5% faster when not passing V8 flags. (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) * **repl**: Tab-completion now works better with arrays. (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) * **string_bytes**: Fixed an unaligned write in the handling of UCS2 encoding. (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) * **tls**: Added a new `--tls-cipher-list` flag that can be used to override the built-in default cipher list. (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) _Note: it is suggested you use the built-in cipher list as it has been carefully selected to reflect current security best practices and risk mitigation._ ### Known issues See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). ### Commits * [[`1cd794f129`](https://github.com/nodejs/node/commit/1cd794f129)] - **buffer**: reapply 07c0667 (Fedor Indutny) [#2487](https://github.com/nodejs/node/pull/2487) * [[`156781dedd`](https://github.com/nodejs/node/commit/156781dedd)] - **build**: use required platform in android-configure (Evan Lucas) [#2501](https://github.com/nodejs/node/pull/2501) * [[`77075ec906`](https://github.com/nodejs/node/commit/77075ec906)] - **crypto**: fix mem {de}allocation in ExportChallenge (Karl Skomski) [#2359](https://github.com/nodejs/node/pull/2359) * [[`cb30414d9e`](https://github.com/nodejs/node/commit/cb30414d9e)] - **doc**: sync CHANGELOG.md from master (Roman Reiss) [#2524](https://github.com/nodejs/node/pull/2524) * [[`9330f5ef45`](https://github.com/nodejs/node/commit/9330f5ef45)] - **doc**: make the deprecations consistent (Sakthipriyan Vairamani) [#2450](https://github.com/nodejs/node/pull/2450) * [[`09437e0146`](https://github.com/nodejs/node/commit/09437e0146)] - **doc**: fix comments in tls_wrap.cc and _http_client.js (Minwoo Jung) [#2489](https://github.com/nodejs/node/pull/2489) * [[`c9867fed29`](https://github.com/nodejs/node/commit/c9867fed29)] - **doc**: document response.finished in http.markdown (hackerjs) [#2414](https://github.com/nodejs/node/pull/2414) * [[`7f23a83c42`](https://github.com/nodejs/node/commit/7f23a83c42)] - **doc**: update AUTHORS list (Rod Vagg) [#2505](https://github.com/nodejs/node/pull/2505) * [[`cd0c362f67`](https://github.com/nodejs/node/commit/cd0c362f67)] - **doc**: update AUTHORS list (Rod Vagg) [#2318](https://github.com/nodejs/node/pull/2318) * [[`2c7b9257ea`](https://github.com/nodejs/node/commit/2c7b9257ea)] - **doc**: add TSC meeting minutes 2015-07-29 (Rod Vagg) [#2437](https://github.com/nodejs/node/pull/2437) * [[`aaefde793e`](https://github.com/nodejs/node/commit/aaefde793e)] - **doc**: add TSC meeting minutes 2015-08-19 (Rod Vagg) [#2460](https://github.com/nodejs/node/pull/2460) * [[`51ef9106f5`](https://github.com/nodejs/node/commit/51ef9106f5)] - **doc**: add TSC meeting minutes 2015-06-03 (Rod Vagg) [#2453](https://github.com/nodejs/node/pull/2453) * [[`7130b4cf1d`](https://github.com/nodejs/node/commit/7130b4cf1d)] - **doc**: fix links to original converged repo (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) * [[`14f2aee1df`](https://github.com/nodejs/node/commit/14f2aee1df)] - **doc**: fix links to original gh issues for TSC meetings (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) * [[`87a9ef0a40`](https://github.com/nodejs/node/commit/87a9ef0a40)] - **doc**: add audio recording links to TSC meeting minutes (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) * [[`f5cf24afbc`](https://github.com/nodejs/node/commit/f5cf24afbc)] - **doc**: add TSC meeting minutes 2015-07-22 (Rod Vagg) [#2436](https://github.com/nodejs/node/pull/2436) * [[`3f821b96eb`](https://github.com/nodejs/node/commit/3f821b96eb)] - **doc**: fix spelling mistake in node.js comment (Jacob Edelman) [#2391](https://github.com/nodejs/node/pull/2391) * [[`3e6a6fcdd6`](https://github.com/nodejs/node/commit/3e6a6fcdd6)] - **(SEMVER-MINOR)** **events**: deprecate static listenerCount function (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) * [[`023386c852`](https://github.com/nodejs/node/commit/023386c852)] - **fs**: replace bad_args macro with concrete error msg (Roman Klauke) [#2495](https://github.com/nodejs/node/pull/2495) * [[`d1c27b2e29`](https://github.com/nodejs/node/commit/d1c27b2e29)] - **module**: fix module preloading when cwd is ENOENT (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) * [[`5d7486941b`](https://github.com/nodejs/node/commit/5d7486941b)] - **repl**: filter integer keys from repl tab complete list (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) * [[`7f02443a9a`](https://github.com/nodejs/node/commit/7f02443a9a)] - **repl**: dont throw ENOENT on NODE_REPL_HISTORY_FILE (Todd Kennedy) [#2451](https://github.com/nodejs/node/pull/2451) * [[`56a2ae9cef`](https://github.com/nodejs/node/commit/56a2ae9cef)] - **src**: improve startup time (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) * [[`14653c7429`](https://github.com/nodejs/node/commit/14653c7429)] - **stream**: rename poorly named function (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) * [[`1c6e014bfa`](https://github.com/nodejs/node/commit/1c6e014bfa)] - **stream**: micro-optimize high water mark calculation (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) * [[`f1f4b4c46d`](https://github.com/nodejs/node/commit/f1f4b4c46d)] - **stream**: fix off-by-factor-16 error in comment (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) * [[`2d3f09bd76`](https://github.com/nodejs/node/commit/2d3f09bd76)] - **stream_base**: various improvements (Fedor Indutny) [#2351](https://github.com/nodejs/node/pull/2351) * [[`c1ce423b35`](https://github.com/nodejs/node/commit/c1ce423b35)] - **string_bytes**: fix unaligned write in UCS2 (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) * [[`e4d0e86165`](https://github.com/nodejs/node/commit/e4d0e86165)] - **test**: refactor test-https-simple.js (Rich Trott) [#2433](https://github.com/nodejs/node/pull/2433) * [[`0ea5c8d737`](https://github.com/nodejs/node/commit/0ea5c8d737)] - **test**: remove test-timers-first-fire (João Reis) [#2458](https://github.com/nodejs/node/pull/2458) * [[`536c3d0537`](https://github.com/nodejs/node/commit/536c3d0537)] - **test**: use reserved IP in test-net-connect-timeout (Rich Trott) [#2257](https://github.com/nodejs/node/pull/2257) * [[`5df06fd8df`](https://github.com/nodejs/node/commit/5df06fd8df)] - **test**: add spaces after keywords (Brendan Ashworth) * [[`e714b5620e`](https://github.com/nodejs/node/commit/e714b5620e)] - **test**: remove unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) * [[`3579f3a2a4`](https://github.com/nodejs/node/commit/3579f3a2a4)] - **test**: disallow unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) * [[`3545e236fc`](https://github.com/nodejs/node/commit/3545e236fc)] - **test**: reduce timeouts in test-net-keepalive (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) * [[`b60e690023`](https://github.com/nodejs/node/commit/b60e690023)] - **test**: improve test-net-server-pause-on-connect (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) * [[`11d1b8fcaf`](https://github.com/nodejs/node/commit/11d1b8fcaf)] - **test**: improve test-net-pingpong (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) * [[`5fef5c6562`](https://github.com/nodejs/node/commit/5fef5c6562)] - **(SEMVER-MINOR)** **tls**: add --tls-cipher-list command line switch (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) * [[`d9b70f9cbf`](https://github.com/nodejs/node/commit/d9b70f9cbf)] - **tls**: handle empty cert in checkServerIndentity (Mike Atkins) [#2343](https://github.com/nodejs/node/pull/2343) * [[`4f8e34c202`](https://github.com/nodejs/node/commit/4f8e34c202)] - **tools**: add license boilerplate to check-imports.sh (James M Snell) [#2386](https://github.com/nodejs/node/pull/2386) * [[`b76b9197f9`](https://github.com/nodejs/node/commit/b76b9197f9)] - **tools**: enable space-after-keywords in eslint (Brendan Ashworth) * [[`64a8f30a70`](https://github.com/nodejs/node/commit/64a8f30a70)] - **tools**: fix anchors in generated documents (Sakthipriyan Vairamani) [#2491](https://github.com/nodejs/node/pull/2491) * [[`22e344ea10`](https://github.com/nodejs/node/commit/22e344ea10)] - **win**: fix custom actions for WiX older than 3.9 (João Reis) [#2365](https://github.com/nodejs/node/pull/2365) * [[`b5bd3ebfc8`](https://github.com/nodejs/node/commit/b5bd3ebfc8)] - **win**: fix custom actions on Visual Studio != 2013 (Julien Gilli) [#2365](https://github.com/nodejs/node/pull/2365) ## 2015-08-18, Version 3.1.0, @Fishrock123 ### Notable changes * **buffer**: Fixed a couple large memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352). * **crypto**: - Fixed a couple of minor memory leaks (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375). - Signing now checks for OpenSSL errors (P.S.V.R) [#2342](https://github.com/nodejs/node/pull/2342). **Note that this may expose previously hidden errors in user code.** * **intl**: Intl support using small-icu is now enabled by default in builds (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264). - [`String#normalize()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) can now be used for unicode normalization. - The [`Intl`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl) object and various `String` and `Number` methods are present, but only support the English locale. - For support of all locales, node must be built with [full-icu](https://github.com/nodejs/node#build-with-full-icu-support-all-locales-supported-by-icu). * **tls**: Fixed tls throughput being much lower after an incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381). * **tools**: The v8 tick processor now comes bundled with node (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090). - This can be used by producing performance profiling output by running node with `--perf`, then running your appropriate platform's script on the output as found in [tools/v8-prof](https://github.com/nodejs/node/tree/master/tools/v8-prof). * **util**: `util.inspect(obj)` now prints the constructor name of the object if there is one (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935). ### Known issues See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). ### Commits * [[`3645dc62ed`](https://github.com/nodejs/node/commit/3645dc62ed)] - **build**: work around VS2015 issue in ICU <56 (Steven R. Loomis) [#2283](https://github.com/nodejs/node/pull/2283) * [[`1f12e03266`](https://github.com/nodejs/node/commit/1f12e03266)] - **(SEMVER-MINOR)** **build**: intl: converge from joyent/node (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264) * [[`071640abdd`](https://github.com/nodejs/node/commit/071640abdd)] - **build**: Intl: bump ICU4C from 54 to 55 (Steven R. Loomis) [#2293](https://github.com/nodejs/node/pull/2293) * [[`07a88b0c8b`](https://github.com/nodejs/node/commit/07a88b0c8b)] - **build**: update manifest to include Windows 10 (Lucien Greathouse) [#2332](https://github.com/nodejs/io.js/pull/2332) * [[`0bb099f444`](https://github.com/nodejs/node/commit/0bb099f444)] - **build**: expand ~ in install prefix early (Ben Noordhuis) [#2307](https://github.com/nodejs/io.js/pull/2307) * [[`7fe6dd8f5d`](https://github.com/nodejs/node/commit/7fe6dd8f5d)] - **crypto**: check for OpenSSL errors when signing (P.S.V.R) [#2342](https://github.com/nodejs/node/pull/2342) * [[`605f6ee904`](https://github.com/nodejs/node/commit/605f6ee904)] - **crypto**: fix memory leak in PBKDF2Request (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`ba6eb8af12`](https://github.com/nodejs/node/commit/ba6eb8af12)] - **crypto**: fix memory leak in ECDH::SetPrivateKey (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`6a16368611`](https://github.com/nodejs/node/commit/6a16368611)] - **crypto**: fix memory leak in PublicKeyCipher::Cipher (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`a760a87803`](https://github.com/nodejs/node/commit/a760a87803)] - **crypto**: fix memory leak in SafeX509ExtPrint (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`f45487cd6e`](https://github.com/nodejs/node/commit/f45487cd6e)] - **crypto**: fix memory leak in SetDHParam (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`2ff183dd86`](https://github.com/nodejs/node/commit/2ff183dd86)] - **doc**: Update FIPS instructions in README.md (Michael Dawson) [#2278](https://github.com/nodejs/node/pull/2278) * [[`6483bc2e8f`](https://github.com/nodejs/node/commit/6483bc2e8f)] - **doc**: clarify options for fs.watchFile() (Rich Trott) [#2425](https://github.com/nodejs/node/pull/2425) * [[`e76822f454`](https://github.com/nodejs/node/commit/e76822f454)] - **doc**: multiple documentation updates cherry picked from v0.12 (James M Snell) [#2302](https://github.com/nodejs/io.js/pull/2302) * [[`1738c9680b`](https://github.com/nodejs/node/commit/1738c9680b)] - **net**: ensure Socket reported address is current (Ryan Graham) [#2095](https://github.com/nodejs/io.js/pull/2095) * [[`844d3f0e3e`](https://github.com/nodejs/node/commit/844d3f0e3e)] - **path**: use '===' instead of '==' for comparison (Sam Stites) [#2388](https://github.com/nodejs/node/pull/2388) * [[`7118b8a882`](https://github.com/nodejs/node/commit/7118b8a882)] - **path**: remove dead code in favor of unit tests (Nathan Woltman) [#2282](https://github.com/nodejs/io.js/pull/2282) * [[`34f2cfa806`](https://github.com/nodejs/node/commit/34f2cfa806)] - **src**: better error message on failed Buffer malloc (Karl Skomski) [#2422](https://github.com/nodejs/node/pull/2422) * [[`b196c1da3c`](https://github.com/nodejs/node/commit/b196c1da3c)] - **src**: fix memory leak in DLOpen (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) * [[`d1307b2995`](https://github.com/nodejs/node/commit/d1307b2995)] - **src**: don't use fopen() in require() fast path (Ben Noordhuis) [#2377](https://github.com/nodejs/node/pull/2377) * [[`455ec570d1`](https://github.com/nodejs/node/commit/455ec570d1)] - **src**: rename Buffer::Use() to Buffer::New() (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) * [[`fd63e1ce2b`](https://github.com/nodejs/node/commit/fd63e1ce2b)] - **src**: introduce internal Buffer::Copy() function (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) * [[`5586ceca13`](https://github.com/nodejs/node/commit/5586ceca13)] - **src**: move internal functions out of node_buffer.h (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) * [[`bff9bcddb6`](https://github.com/nodejs/node/commit/bff9bcddb6)] - **src**: plug memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) * [[`ccf12df4f3`](https://github.com/nodejs/node/commit/ccf12df4f3)] - **(SEMVER-MINOR)** **src**: add total_available_size to v8 statistics (Roman Klauke) [#2348](https://github.com/nodejs/io.js/pull/2348) * [[`194eeb841b`](https://github.com/nodejs/node/commit/194eeb841b)] - **test**: drop Isolate::GetCurrent() from addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) * [[`46cdb2f6e2`](https://github.com/nodejs/node/commit/46cdb2f6e2)] - **test**: lint addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) * [[`850c794882`](https://github.com/nodejs/node/commit/850c794882)] - **test**: refactor test-fs-watchfile.js (Rich Trott) [#2393](https://github.com/nodejs/node/pull/2393) * [[`a3160c0a33`](https://github.com/nodejs/node/commit/a3160c0a33)] - **test**: correct spelling of 'childProcess' (muddletoes) [#2389](https://github.com/nodejs/node/pull/2389) * [[`e51f90d747`](https://github.com/nodejs/node/commit/e51f90d747)] - **test**: option to run a subset of tests (João Reis) [#2260](https://github.com/nodejs/io.js/pull/2260) * [[`cc46d3bca3`](https://github.com/nodejs/node/commit/cc46d3bca3)] - **test**: clarify dropMembership() call (Rich Trott) [#2062](https://github.com/nodejs/io.js/pull/2062) * [[`0ee4df9c7a`](https://github.com/nodejs/node/commit/0ee4df9c7a)] - **test**: make listen-fd-cluster/server more robust (Sam Roberts) [#1944](https://github.com/nodejs/io.js/pull/1944) * [[`cf9ba81398`](https://github.com/nodejs/node/commit/cf9ba81398)] - **test**: address timing issues in simple http tests (Gireesh Punathil) [#2294](https://github.com/nodejs/io.js/pull/2294) * [[`cbb75c4f86`](https://github.com/nodejs/node/commit/cbb75c4f86)] - **tls**: fix throughput issues after incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381) * [[`94b765f409`](https://github.com/nodejs/node/commit/94b765f409)] - **tls**: fix check for reused session (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) * [[`e83a41ad65`](https://github.com/nodejs/node/commit/e83a41ad65)] - **tls**: introduce internal `onticketkeycallback` (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) * [[`fb0f5d733f`](https://github.com/nodejs/node/commit/fb0f5d733f)] - **(SEMVER-MINOR)** **tools**: run the tick processor without building v8 (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090) * [[`7606bdb897`](https://github.com/nodejs/node/commit/7606bdb897)] - **(SEMVER-MINOR)** **util**: display constructor when inspecting objects (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935) ## 2015-08-04, Version 3.0.0, @rvagg ### Notable changes * **buffer**: - Due to changes in V8, it has been necessary to reimplement `Buffer` on top of V8's `Uint8Array`. Every effort has been made to minimize the performance impact, however `Buffer` instantiation is measurably slower. Access operations may be faster in some circumstances but the exact performance profile and difference over previous versions will depend on how `Buffer` is used within applications. (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825). - `Buffer` can now take `ArrayBuffer`s as a constructor argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002). - When a single buffer is passed to `Buffer.concat()`, a new, copied `Buffer` object will be returned; previous behavior was to return the original `Buffer` object (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937). * **build**: PPC support has been added to core to allow compiling on pLinux BE and LE (AIX support coming soon) (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124). * **dgram**: If an error occurs within `socket.send()` and a callback has been provided, the error is only passed as the first argument to the callback and not emitted on the `socket` object; previous behavior was to do both (Matteo Collina & Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) * **freelist**: Deprecate the undocumented `freelist` core module (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176). * **http**: - Status codes now all use the official [IANA names](http://www.iana.org/assignments/http-status-codes) as per [RFC7231](https://tools.ietf.org/html/rfc7231), e.g. `http.STATUS_CODES[414]` now returns `'URI Too Long'` rather than `'Request-URI Too Large'` (jomo) [#1470](https://github.com/nodejs/node/pull/1470). - Calling .getName() on an HTTP agent no longer returns a trailing colon, HTTPS agents will no longer return an extra colon near the middle of the string (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617). * **node**: - `NODE_MODULE_VERSION` has been bumped to `45` to reflect the break in ABI (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096). - Introduce a new `process.release` object that contains a `name` property set to `'io.js'` and `sourceUrl`, `headersUrl` and `libUrl` (Windows only) properties containing URLs for the relevant resources; this is intended to be used by node-gyp (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154). - The version of node-gyp bundled with io.js now downloads and uses a tarball of header files from iojs.org rather than the full source for compiling native add-ons; it is hoped this is a temporary floating patch and the change will be upstreamed to node-gyp soon (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066). * **repl**: Persistent history is now enabled by default. The history file is located at ~/.node_repl_history, which can be overridden by the new environment variable `NODE_REPL_HISTORY`. This deprecates the previous `NODE_REPL_HISTORY_FILE` variable. Additionally, the format of the file has been changed to plain text to better handle file corruption. (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224). * **smalloc**: The `smalloc` module has been removed as it is no longer possible to provide the API due to changes in V8 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022). * **tls**: Add `server.getTicketKeys()` and `server.setTicketKeys()` methods for [TLS session key](https://www.ietf.org/rfc/rfc5077.txt) rotation (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227). * **v8**: Upgraded to 4.4.63.26 - ES6: Enabled [computed property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) - ES6: `Array` can now be subclassed in strict mode - ES6: Implement [rest parameters](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/rest_parameters) in staging, use the `--harmony-rest-parameters` command line flag - ES6: Implement the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) in staging, use the `--harmony-spreadcalls` command line flag - Removed `SetIndexedPropertiesToExternalArrayData` and related APIs, forcing a shift to `Buffer` to be reimplemented based on `Uint8Array` - Introduction of `Maybe` and `MaybeLocal` C++ API for objects which _may_ or _may not_ have a value. - Added support for PPC See also https://github.com/nodejs/node/wiki/Breaking-Changes#300-from-2x for a summary of the breaking changes (SEMVER-MAJOR). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`60a974d200`](https://github.com/nodejs/node/commit/60a974d200)] - **buffer**: fix missing null/undefined check (Trevor Norris) [#2195](https://github.com/nodejs/node/pull/2195) * [[`e6ab2d92bc`](https://github.com/nodejs/node/commit/e6ab2d92bc)] - **buffer**: fix not return on error (Trevor Norris) [#2225](https://github.com/nodejs/node/pull/2225) * [[`1057d1186b`](https://github.com/nodejs/node/commit/1057d1186b)] - **buffer**: rename internal/buffer_new.js to buffer.js (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) * [[`4643b8b667`](https://github.com/nodejs/node/commit/4643b8b667)] - **(SEMVER-MINOR)** **buffer**: allow ArrayBuffer as Buffer argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002) * [[`e5ada116cd`](https://github.com/nodejs/node/commit/e5ada116cd)] - **buffer**: minor cleanup from rebase (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) * [[`b625ab4242`](https://github.com/nodejs/node/commit/b625ab4242)] - **buffer**: fix usage of kMaxLength (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) * [[`eea66e2a7b`](https://github.com/nodejs/node/commit/eea66e2a7b)] - **(SEMVER-MAJOR)** **buffer**: fix case of one buffer passed to concat (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937) * [[`8664084166`](https://github.com/nodejs/node/commit/8664084166)] - **buffer**: make additional changes to native API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`36f78f4c1c`](https://github.com/nodejs/node/commit/36f78f4c1c)] - **buffer**: switch API to return MaybeLocal (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`571ec13841`](https://github.com/nodejs/node/commit/571ec13841)] - **buffer**: switch to using Maybe API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`d75f5c8d0e`](https://github.com/nodejs/node/commit/d75f5c8d0e)] - **buffer**: finish implementing FreeCallback (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`63da0dfd3a`](https://github.com/nodejs/node/commit/63da0dfd3a)] - **buffer**: implement Uint8Array backed Buffer (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`23be6ca189`](https://github.com/nodejs/node/commit/23be6ca189)] - **buffer**: allow ARGS_THIS to accept a name (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`971de5e417`](https://github.com/nodejs/node/commit/971de5e417)] - **build**: prepare Windows installer for i18n support (Frederic Hemberger) [#2247](https://github.com/nodejs/node/pull/2247) * [[`2ba8b23661`](https://github.com/nodejs/node/commit/2ba8b23661)] - **build**: add 'x86' option back in to configure (Rod Vagg) [#2233](https://github.com/nodejs/node/pull/2233) * [[`b4226e797a`](https://github.com/nodejs/node/commit/b4226e797a)] - **build**: first set of updates to enable PPC support (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124) * [[`24dd016deb`](https://github.com/nodejs/node/commit/24dd016deb)] - **build**: produce symbol map files on windows (Ali Ijaz Sheikh) [#2243](https://github.com/nodejs/node/pull/2243) * [[`423d8944ce`](https://github.com/nodejs/node/commit/423d8944ce)] - **cluster**: do not unconditionally set --debug-port (cjihrig) [#1949](https://github.com/nodejs/node/pull/1949) * [[`fa98b97171`](https://github.com/nodejs/node/commit/fa98b97171)] - **cluster**: add handle ref/unref stubs in rr mode (Ben Noordhuis) [#2274](https://github.com/nodejs/node/pull/2274) * [[`944f68046c`](https://github.com/nodejs/node/commit/944f68046c)] - **crypto**: remove kMaxLength on randomBytes() (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) * [[`3d3c687012`](https://github.com/nodejs/node/commit/3d3c687012)] - **deps**: update V8 to 4.4.63.26 (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) * [[`3aad4fa89a`](https://github.com/nodejs/node/commit/3aad4fa89a)] - **deps**: upgrade v8 to 4.4.63.12 (Ben Noordhuis) [#2092](https://github.com/nodejs/node/pull/2092) * [[`70d1f32f56`](https://github.com/nodejs/node/commit/70d1f32f56)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.4.63.9 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) * [[`deb7ee93a7`](https://github.com/nodejs/node/commit/deb7ee93a7)] - **deps**: backport 7b24219346 from v8 upstream (Rod Vagg) [#1805](https://github.com/nodejs/node/pull/1805) * [[`d58e780504`](https://github.com/nodejs/node/commit/d58e780504)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.3.61.21 (Chris Dickinson) [iojs/io.js#1632](https://github.com/iojs/io.js/pull/1632) * [[`2a63cf612b`](https://github.com/nodejs/node/commit/2a63cf612b)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`bf63266460`](https://github.com/nodejs/node/commit/bf63266460)] - **deps**: upgrade to npm 2.13.3 (Kat Marchán) [#2284](https://github.com/nodejs/node/pull/2284) * [[`ef2c8cd4ec`](https://github.com/nodejs/node/commit/ef2c8cd4ec)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Matteo Collina) [#1796](https://github.com/nodejs/node/pull/1796) * [[`3da057fef6`](https://github.com/nodejs/node/commit/3da057fef6)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) * [[`df1994fe53`](https://github.com/nodejs/node/commit/df1994fe53)] - ***Revert*** "**dns**: remove AI_V4MAPPED hint flag on FreeBSD" (cjihrig) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) * [[`1721968b22`](https://github.com/nodejs/node/commit/1721968b22)] - **doc**: document repl persistent history changes (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) * [[`d12df7f159`](https://github.com/nodejs/node/commit/d12df7f159)] - **doc**: update v8 flags in man page (Michaël Zasso) [iojs/io.js#1701](https://github.com/iojs/io.js/pull/1701) * [[`d168d01b04`](https://github.com/nodejs/node/commit/d168d01b04)] - **doc**: properly inheriting from EventEmitter (Sakthipriyan Vairamani) [#2168](https://github.com/nodejs/node/pull/2168) * [[`500f2538cc`](https://github.com/nodejs/node/commit/500f2538cc)] - **doc**: a listener, not "an" listener (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) * [[`54627a919d`](https://github.com/nodejs/node/commit/54627a919d)] - **doc**: server close event does not have an argument (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) * [[`ed85c95a9c`](https://github.com/nodejs/node/commit/ed85c95a9c)] - **doc,test**: documents behaviour of non-existent file (Sakthipriyan Vairamani) [#2169](https://github.com/nodejs/node/pull/2169) * [[`2965442308`](https://github.com/nodejs/node/commit/2965442308)] - **(SEMVER-MAJOR)** **http**: fix agent.getName() and add tests (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617) * [[`2d9456e3e6`](https://github.com/nodejs/node/commit/2d9456e3e6)] - **(SEMVER-MAJOR)** **http**: use official IANA Status Codes (jomo) [#1470](https://github.com/nodejs/node/pull/1470) * [[`11e4249227`](https://github.com/nodejs/node/commit/11e4249227)] - **(SEMVER-MAJOR)** **http_server**: `prefinish` vs `finish` (Fedor Indutny) [#1411](https://github.com/nodejs/node/pull/1411) * [[`9bc2e26720`](https://github.com/nodejs/node/commit/9bc2e26720)] - **net**: do not set V4MAPPED on FreeBSD (Julien Gilli) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) * [[`ba9ccf227e`](https://github.com/nodejs/node/commit/ba9ccf227e)] - **node**: remove redundant --use-old-buffer (Rod Vagg) [#2275](https://github.com/nodejs/node/pull/2275) * [[`ef65321083`](https://github.com/nodejs/node/commit/ef65321083)] - **(SEMVER-MAJOR)** **node**: do not override `message`/`stack` of error (Fedor Indutny) [#2108](https://github.com/nodejs/node/pull/2108) * [[`9f727f5e03`](https://github.com/nodejs/node/commit/9f727f5e03)] - **node-gyp**: detect RC build with x.y.z-rc.n format (Rod Vagg) [#2171](https://github.com/nodejs/node/pull/2171) * [[`e52f963632`](https://github.com/nodejs/node/commit/e52f963632)] - **node-gyp**: download header tarball for compile (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) * [[`902c9ca51d`](https://github.com/nodejs/node/commit/902c9ca51d)] - **node-gyp**: make aware of nightly, next-nightly & rc (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) * [[`4cffaa3f55`](https://github.com/nodejs/node/commit/4cffaa3f55)] - **(SEMVER-MINOR)** **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) * [[`ed6c249104`](https://github.com/nodejs/node/commit/ed6c249104)] - **(SEMVER-MAJOR)** **repl**: persist history in plain text (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) * [[`f7d5e4c618`](https://github.com/nodejs/node/commit/f7d5e4c618)] - **(SEMVER-MINOR)** **repl**: default persistence to ~/.node_repl_history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) * [[`ea05e760cd`](https://github.com/nodejs/node/commit/ea05e760cd)] - **repl**: don't clobber RegExp.$ properties (Sakthipriyan Vairamani) [#2137](https://github.com/nodejs/node/pull/2137) * [[`d20093246b`](https://github.com/nodejs/node/commit/d20093246b)] - **src**: disable vector ICs on arm (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) * [[`04fd4fad46`](https://github.com/nodejs/node/commit/04fd4fad46)] - **(SEMVER-MINOR)** **src**: introduce process.release object (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154) * [[`9d34bd1147`](https://github.com/nodejs/node/commit/9d34bd1147)] - **src**: increment NODE_MODULE_VERSION to 45 (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096) * [[`ceee8d2807`](https://github.com/nodejs/node/commit/ceee8d2807)] - **test**: add tests for persistent repl history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) * [[`8e1a8ffe24`](https://github.com/nodejs/node/commit/8e1a8ffe24)] - **test**: remove two obsolete pummel tests (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) * [[`ae731ec0fa`](https://github.com/nodejs/node/commit/ae731ec0fa)] - **test**: don't use arguments.callee (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) * [[`21d31c08e7`](https://github.com/nodejs/node/commit/21d31c08e7)] - **test**: remove obsolete harmony flags (Chris Dickinson) * [[`64cf71195c`](https://github.com/nodejs/node/commit/64cf71195c)] - **test**: change the hostname to an invalid name (Sakthipriyan Vairamani) [#2287](https://github.com/nodejs/node/pull/2287) * [[`80a1cf7425`](https://github.com/nodejs/node/commit/80a1cf7425)] - **test**: fix messages and use return to skip tests (Sakthipriyan Vairamani) [#2290](https://github.com/nodejs/node/pull/2290) * [[`d5ab92bcc1`](https://github.com/nodejs/node/commit/d5ab92bcc1)] - **test**: use common.isWindows consistently (Sakthipriyan Vairamani) [#2269](https://github.com/nodejs/node/pull/2269) * [[`bc733f7065`](https://github.com/nodejs/node/commit/bc733f7065)] - **test**: fix fs.readFile('/dev/stdin') tests (Ben Noordhuis) [#2265](https://github.com/nodejs/node/pull/2265) * [[`3cbb5870e5`](https://github.com/nodejs/node/commit/3cbb5870e5)] - **tools**: expose skip output to test runner (Johan Bergström) [#2130](https://github.com/nodejs/node/pull/2130) * [[`3b021efe11`](https://github.com/nodejs/node/commit/3b021efe11)] - **vm**: fix symbol access (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) * [[`7b81e4ba36`](https://github.com/nodejs/node/commit/7b81e4ba36)] - **vm**: remove unnecessary access checks (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) * [[`659dadd410`](https://github.com/nodejs/node/commit/659dadd410)] - **vm**: fix property descriptors of sandbox properties (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) * [[`9bac1dbae9`](https://github.com/nodejs/node/commit/9bac1dbae9)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) ## 2015-07-28, Version 2.5.0, @cjihrig ### Notable changes * **https**: TLS sessions in Agent are reused (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) * **src**: base64 decoding is now 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) * **npm**: Upgraded to v2.13.2, release notes can be found in (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Using multiple REPL instances in parallel may cause some REPL history corruption or loss. [#1634](https://github.com/nodejs/node/issues/1634) * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`bf2cd225a8`](https://github.com/nodejs/node/commit/bf2cd225a8)] - **process**: resize stderr on SIGWINCH (Jeremiah Senkpiel) [#2231](https://github.com/nodejs/node/pull/2231) * [[`99d9d7e716`](https://github.com/nodejs/node/commit/99d9d7e716)] - **benchmark**: add remaining path benchmarks & optimize (Nathan Woltman) [#2103](https://github.com/nodejs/node/pull/2103) * [[`66fc8ca22b`](https://github.com/nodejs/node/commit/66fc8ca22b)] - **(SEMVER-MINOR)** **cluster**: emit 'message' event on cluster master (Sam Roberts) [#861](https://github.com/nodejs/node/pull/861) * [[`eb35968de7`](https://github.com/nodejs/node/commit/eb35968de7)] - **crypto**: fix legacy SNICallback (Fedor Indutny) [#1720](https://github.com/nodejs/node/pull/1720) * [[`fef190cea6`](https://github.com/nodejs/node/commit/fef190cea6)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`b73a7465c5`](https://github.com/nodejs/node/commit/b73a7465c5)] - **deps**: upgrade to npm 2.13.2 (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241) * [[`0a7bf81d2f`](https://github.com/nodejs/node/commit/0a7bf81d2f)] - **deps**: update V8 to 4.2.77.21 (Ali Ijaz Sheikh) [#2238](https://github.com/nodejs/node/issues/2238) * [[`73cdcdd581`](https://github.com/nodejs/node/commit/73cdcdd581)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`04893a736d`](https://github.com/nodejs/node/commit/04893a736d)] - **deps**: upgrade to npm 2.13.1 (Kat Marchán) [#2210](https://github.com/nodejs/node/pull/2210) * [[`a3c1b9720e`](https://github.com/nodejs/node/commit/a3c1b9720e)] - **doc**: add GPG fingerprint for cjihrig (cjihrig) [#2217](https://github.com/nodejs/node/pull/2217) * [[`d9f857df3b`](https://github.com/nodejs/node/commit/d9f857df3b)] - **doc**: note about custom inspect functions (Sakthipriyan Vairamani) [#2142](https://github.com/nodejs/node/pull/2142) * [[`4ef2b5fbfb`](https://github.com/nodejs/node/commit/4ef2b5fbfb)] - **doc**: Replace util.debug with console.error (Yosuke Furukawa) [#2214](https://github.com/nodejs/node/pull/2214) * [[`b612f085ec`](https://github.com/nodejs/node/commit/b612f085ec)] - **doc**: add joaocgreis as a collaborator (João Reis) [#2208](https://github.com/nodejs/node/pull/2208) * [[`6b85d5a4b3`](https://github.com/nodejs/node/commit/6b85d5a4b3)] - **doc**: add TSC meeting minutes 2015-07-15 (Rod Vagg) [#2191](https://github.com/nodejs/node/pull/2191) * [[`c7d8b09162`](https://github.com/nodejs/node/commit/c7d8b09162)] - **doc**: recompile before testing core module changes (Phillip Johnsen) [#2051](https://github.com/nodejs/node/pull/2051) * [[`9afee6785e`](https://github.com/nodejs/node/commit/9afee6785e)] - **http**: Check this.connection before using it (Sakthipriyan Vairamani) [#2172](https://github.com/nodejs/node/pull/2172) * [[`2ca5a3db47`](https://github.com/nodejs/node/commit/2ca5a3db47)] - **https**: reuse TLS sessions in Agent (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) * [[`fef87fee1d`](https://github.com/nodejs/node/commit/fef87fee1d)] - **(SEMVER-MINOR)** **lib,test**: add freelist deprecation and test (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176) * [[`503b089dd8`](https://github.com/nodejs/node/commit/503b089dd8)] - **net**: don't throw on immediately destroyed socket (Evan Lucas) [#2251](https://github.com/nodejs/node/pull/2251) * [[`93660c8b8e`](https://github.com/nodejs/node/commit/93660c8b8e)] - **node**: remove bad fn call and check (Trevor Norris) [#2157](https://github.com/nodejs/node/pull/2157) * [[`afd7e37ee0`](https://github.com/nodejs/node/commit/afd7e37ee0)] - **repl**: better empty line handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) * [[`81ea52aa01`](https://github.com/nodejs/node/commit/81ea52aa01)] - **repl**: improving line continuation handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) * [[`30edb5aee9`](https://github.com/nodejs/node/commit/30edb5aee9)] - **repl**: preventing REPL crash with inherited properties (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) * [[`77fa385e5d`](https://github.com/nodejs/node/commit/77fa385e5d)] - **repl**: fixing `undefined` in invalid REPL keyword error (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) * [[`8fd3ce100e`](https://github.com/nodejs/node/commit/8fd3ce100e)] - **src**: make base64 decoding 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) * [[`c786d6341d`](https://github.com/nodejs/node/commit/c786d6341d)] - **test**: do not use public IPs for timeout testing (Rich Trott) [#2057](https://github.com/nodejs/node/pull/2057) * [[`4e78cd71c0`](https://github.com/nodejs/node/commit/4e78cd71c0)] - **test**: skip IPv6 part before testing it (Sakthipriyan Vairamani) [#2226](https://github.com/nodejs/node/pull/2226) * [[`ac70bc8240`](https://github.com/nodejs/node/commit/ac70bc8240)] - **test**: fix valgrind uninitialized memory warning (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) * [[`ac7d3fa0d9`](https://github.com/nodejs/node/commit/ac7d3fa0d9)] - **test**: add -no_rand_screen to s_client opts on Win (Shigeki Ohtsu) [#2209](https://github.com/nodejs/node/pull/2209) * [[`79c865a53f`](https://github.com/nodejs/node/commit/79c865a53f)] - **test**: changing process.exit to return while skipping tests (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) * [[`69298d36cf`](https://github.com/nodejs/node/commit/69298d36cf)] - **test**: formatting skip messages for TAP parsing (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) * [[`543dabb609`](https://github.com/nodejs/node/commit/543dabb609)] - **timers**: improve Timer.now() performance (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) * [[`3663b124e6`](https://github.com/nodejs/node/commit/3663b124e6)] - **timers**: remove unused Timer.again() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) * [[`bcce5cf9bb`](https://github.com/nodejs/node/commit/bcce5cf9bb)] - **timers**: remove unused Timer.getRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) * [[`f2c83bd202`](https://github.com/nodejs/node/commit/f2c83bd202)] - **timers**: remove unused Timer.setRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) * [[`e11fc67225`](https://github.com/nodejs/node/commit/e11fc67225)] - **(SEMVER-MINOR)** **tls**: add `getTicketKeys()`/`setTicketKeys()` (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227) * [[`68b06e94e3`](https://github.com/nodejs/node/commit/68b06e94e3)] - **tools**: use local or specified $NODE for test-npm (Jeremiah Senkpiel) [#1984](https://github.com/nodejs/node/pull/1984) * [[`ab479659c7`](https://github.com/nodejs/node/commit/ab479659c7)] - **util**: delay creation of debug context (Ali Ijaz Sheikh) [#2248](https://github.com/nodejs/node/pull/2248) * [[`6391f4d2fd`](https://github.com/nodejs/node/commit/6391f4d2fd)] - **util**: removing redundant checks in is* functions (Sakthipriyan Vairamani) [#2179](https://github.com/nodejs/node/pull/2179) * [[`b148c0dff3`](https://github.com/nodejs/node/commit/b148c0dff3)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) * [[`f90f1e75bb`](https://github.com/nodejs/node/commit/f90f1e75bb)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) ## 2015-07-17, Version 2.4.0, @Fishrock123 ### Notable changes * **src**: Added a new `--track-heap-objects` flag to track heap object allocations for heap snapshots (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135). * **readline**: Fixed a freeze that affected the repl if the keypress event handler threw (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107). * **npm**: Upgraded to v2.13.0, release notes can be found in (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`f95f9ef6ea`](https://github.com/nodejs/node/commit/f95f9ef6ea)] - **build**: always use prefix=/ for tar-headers (Rod Vagg) [#2082](https://github.com/nodejs/node/pull/2082) * [[`12bc397207`](https://github.com/nodejs/node/commit/12bc397207)] - **build**: run-ci makefile rule (Alexis Campailla) [#2134](https://github.com/nodejs/node/pull/2134) * [[`84012c99e0`](https://github.com/nodejs/node/commit/84012c99e0)] - **build**: fix vcbuild merge issues (Alexis Campailla) [#2131](https://github.com/nodejs/node/pull/2131) * [[`47e2c5c828`](https://github.com/nodejs/node/commit/47e2c5c828)] - **build**: bail early if clean is invoked (Johan Bergström) [#2127](https://github.com/nodejs/node/pull/2127) * [[`5acad6b163`](https://github.com/nodejs/node/commit/5acad6b163)] - **child_process**: fix arguments comments (Roman Reiss) [#2161](https://github.com/nodejs/node/pull/2161) * [[`3c4121c418`](https://github.com/nodejs/node/commit/3c4121c418)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`938cc757bb`](https://github.com/nodejs/node/commit/938cc757bb)] - **deps**: upgrade to npm 2.13.0 (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152) * [[`6f306e0ed2`](https://github.com/nodejs/node/commit/6f306e0ed2)] - **doc**: add targos as a collaborator (Michaël Zasso) [#2200](https://github.com/nodejs/node/pull/2200) * [[`c019d9a239`](https://github.com/nodejs/node/commit/c019d9a239)] - **doc**: add thefourtheye as a collaborator (Sakthipriyan Vairamani) [#2199](https://github.com/nodejs/node/pull/2199) * [[`4e92dbc26b`](https://github.com/nodejs/node/commit/4e92dbc26b)] - **doc**: add TSC members from the combined project (Jeremiah Senkpiel) [#2085](https://github.com/nodejs/node/pull/2085) * [[`6c3aabf455`](https://github.com/nodejs/node/commit/6c3aabf455)] - **doc**: add TSC meeting minutes 2015-07-08 (Rod Vagg) [#2184](https://github.com/nodejs/node/pull/2184) * [[`30a0d47d51`](https://github.com/nodejs/node/commit/30a0d47d51)] - **doc**: add TSC meeting minutes 2015-07-01 (Rod Vagg) [#2132](https://github.com/nodejs/node/pull/2132) * [[`23efb05cc3`](https://github.com/nodejs/node/commit/23efb05cc3)] - **doc**: document fs.watchFile behaviour on ENOENT (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) * [[`65963ec26f`](https://github.com/nodejs/node/commit/65963ec26f)] - **doc,test**: empty strings in path module (Sakthipriyan Vairamani) [#2106](https://github.com/nodejs/node/pull/2106) * [[`0ab81e6f58`](https://github.com/nodejs/node/commit/0ab81e6f58)] - **docs**: link to more up-to-date v8 docs (Jeremiah Senkpiel) [#2196](https://github.com/nodejs/node/pull/2196) * [[`1afc0c9e86`](https://github.com/nodejs/node/commit/1afc0c9e86)] - **fs**: fix error on bad listener type (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) * [[`2ba84606a6`](https://github.com/nodejs/node/commit/2ba84606a6)] - **path**: assert path.join() arguments equally (Phillip Johnsen) [#2159](https://github.com/nodejs/node/pull/2159) * [[`bd01603201`](https://github.com/nodejs/node/commit/bd01603201)] - **readline**: fix freeze if `keypress` event throws (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107) * [[`59f6b5da2a`](https://github.com/nodejs/node/commit/59f6b5da2a)] - **repl**: Prevent crash when tab-completed with Proxy (Sakthipriyan Vairamani) [#2120](https://github.com/nodejs/node/pull/2120) * [[`cf14a2427c`](https://github.com/nodejs/node/commit/cf14a2427c)] - **(SEMVER-MINOR)** **src**: add --track-heap-objects (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135) * [[`2b4b600660`](https://github.com/nodejs/node/commit/2b4b600660)] - **test**: fix test-debug-port-from-cmdline (João Reis) [#2186](https://github.com/nodejs/node/pull/2186) * [[`d4ceb16da2`](https://github.com/nodejs/node/commit/d4ceb16da2)] - **test**: properly clean up temp directory (Roman Reiss) [#2164](https://github.com/nodejs/node/pull/2164) * [[`842eb5b853`](https://github.com/nodejs/node/commit/842eb5b853)] - **test**: add test for dgram.setTTL (Evan Lucas) [#2121](https://github.com/nodejs/node/pull/2121) * [[`cff7300a57`](https://github.com/nodejs/node/commit/cff7300a57)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) ## 2015-07-09, Version 2.3.4, @Fishrock123 ### Notable changes * **openssl**: Upgrade to 1.0.2d, fixes CVE-2015-1793 (Alternate Chains Certificate Forgery) (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141). * **npm**: Upgraded to v2.12.1, release notes can be found in and (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`0d15161c24`](https://github.com/nodejs/node/commit/0d15161c24)] - **benchmark**: Add some path benchmarks for #1778 (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) * [[`c70e68fa32`](https://github.com/nodejs/node/commit/c70e68fa32)] - **deps**: update deps/openssl/conf/arch/*/opensslconf.h (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) * [[`ca93f7f2e6`](https://github.com/nodejs/node/commit/ca93f7f2e6)] - **deps**: upgrade openssl sources to 1.0.2d (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) * [[`b18c841ec1`](https://github.com/nodejs/node/commit/b18c841ec1)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`863cdbdd08`](https://github.com/nodejs/node/commit/863cdbdd08)] - **deps**: upgrade to npm 2.12.1 (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112) * [[`84b3915764`](https://github.com/nodejs/node/commit/84b3915764)] - **doc**: document current release procedure (Rod Vagg) [#2099](https://github.com/nodejs/node/pull/2099) * [[`46140334cd`](https://github.com/nodejs/node/commit/46140334cd)] - **doc**: update AUTHORS list (Rod Vagg) [#2100](https://github.com/nodejs/node/pull/2100) * [[`bca53dce76`](https://github.com/nodejs/node/commit/bca53dce76)] - **path**: refactor for performance and consistency (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) * [[`6bef15afe7`](https://github.com/nodejs/node/commit/6bef15afe7)] - **src**: remove traceSyncIO property from process (Bradley Meck) [#2143](https://github.com/nodejs/node/pull/2143) * [[`2ba1740ba1`](https://github.com/nodejs/node/commit/2ba1740ba1)] - **test**: add missing crypto checks (Johan Bergström) [#2129](https://github.com/nodejs/node/pull/2129) * [[`180fd392ca`](https://github.com/nodejs/node/commit/180fd392ca)] - **test**: refactor test-repl-tab-complete (Sakthipriyan Vairamani) [#2122](https://github.com/nodejs/node/pull/2122) * [[`fb05c8e27d`](https://github.com/nodejs/node/commit/fb05c8e27d)] - ***Revert*** "**test**: add test for missing `close`/`finish` event" (Fedor Indutny) * [[`9436a860cb`](https://github.com/nodejs/node/commit/9436a860cb)] - **test**: add test for missing `close`/`finish` event (Mark Plomer) [iojs/io.js#1373](https://github.com/iojs/io.js/pull/1373) * [[`ee3ce2ed88`](https://github.com/nodejs/node/commit/ee3ce2ed88)] - **tools**: install gdbinit from v8 to $PREFIX/share (Ali Ijaz Sheikh) [#2123](https://github.com/nodejs/node/pull/2123) * [[`dd523c75da`](https://github.com/nodejs/node/commit/dd523c75da)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) ## 2015-07-09, Version 0.12.7 (Stable) ### Commits * [[`0cf9f27703`](https://github.com/nodejs/node/commit/0cf9f27703)] - **deps**: upgrade openssl sources to 1.0.1p [#25654](https://github.com/joyent/node/pull/25654) * [[`8917e430b8`](https://github.com/nodejs/node/commit/8917e430b8)] - **deps**: upgrade to npm 2.11.3 [#25545](https://github.com/joyent/node/pull/25545) * [[`88a27a9621`](https://github.com/nodejs/node/commit/88a27a9621)] - **V8**: cherry-pick JitCodeEvent patch from upstream (Ben Noordhuis) [#25589](https://github.com/joyent/node/pull/25589) * [[`18d413d299`](https://github.com/nodejs/node/commit/18d413d299)] - **win,msi**: create npm folder in AppData directory (Steven Rockarts) [#8838](https://github.com/joyent/node/pull/8838) ## 2015-07-09, Version 0.10.40 (Maintenance) ### Commits * [[`0cf9f27703`](https://github.com/nodejs/node/commit/0cf9f27703)] - **openssl**: upgrade to 1.0.1p [#25654](https://github.com/joyent/node/pull/25654) * [[`5a60e0d904`](https://github.com/nodejs/node/commit/5a60e0d904)] - **V8**: back-port JitCodeEvent patch from upstream (Ben Noordhuis) [#25588](https://github.com/joyent/node/pull/25588) * [[`18d413d299`](https://github.com/nodejs/node/commit/18d413d299)] - **win,msi**: create npm folder in AppData directory (Steven Rockarts) [#8838](https://github.com/joyent/node/pull/8838) ## 2015-07-04, Version 2.3.3, @Fishrock123 ### Notable changes * **deps**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ## Commits * [[`030f8045c7`](https://github.com/nodejs/node/commit/030f8045c7)] - **deps**: fix out-of-band write in utf8 decoder (Fedor Indutny) * [[`0f09b8db28`](https://github.com/nodejs/node/commit/0f09b8db28)] - **doc**: don't recommend domains for error handling (Benjamin Gruenbaum) [#2056](https://github.com/nodejs/node/pull/2056) * [[`9cd44bb2b6`](https://github.com/nodejs/node/commit/9cd44bb2b6)] - **util**: prepend '(node) ' to deprecation messages (Sakthipriyan Vairamani) [#1892](https://github.com/nodejs/node/pull/1892) ## 2015-07-03, Version 0.12.6 (Stable) ### Notable changes * **deps**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. ### Commits * [[`78b0e30954`](https://github.com/nodejs/node/commit/78b0e30954)] - **deps**: fix out-of-band write in utf8 decoder (Fedor Indutny) ## 2015-07-01, Version 2.3.2, @rvagg ### Notable changes * **build**: - Added support for compiling with Microsoft Visual C++ 2015 - Started building and distributing headers-only tarballs along with binaries ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ## Commits * [[`9180140231`](https://github.com/nodejs/node/commit/9180140231)] - **_stream_wrap**: prevent use after free in TLS (Fedor Indutny) [#1910](https://github.com/nodejs/node/pull/1910) * [[`05a73c0f25`](https://github.com/nodejs/node/commit/05a73c0f25)] - **benchmark**: make concurrent requests configurable (Rich Trott) [#2068](https://github.com/nodejs/node/pull/2068) * [[`f52d73352e`](https://github.com/nodejs/node/commit/f52d73352e)] - **benchmark**: fix typo in README (Rich Trott) [#2067](https://github.com/nodejs/node/pull/2067) * [[`1cd9eeb556`](https://github.com/nodejs/node/commit/1cd9eeb556)] - **buffer**: prevent abort on bad proto (Trevor Norris) [#2012](https://github.com/nodejs/node/pull/2012) * [[`8350f3a3a2`](https://github.com/nodejs/node/commit/8350f3a3a2)] - **buffer**: optimize Buffer#toString() (Ben Noordhuis) [#2027](https://github.com/nodejs/node/pull/2027) * [[`628a3ab093`](https://github.com/nodejs/node/commit/628a3ab093)] - **build**: add tar-headers target for headers-only tar (Rod Vagg) [#1975](https://github.com/nodejs/node/pull/1975) * [[`dcbb9e1da6`](https://github.com/nodejs/node/commit/dcbb9e1da6)] - **build**: update build targets for io.js (Rod Vagg) [#1938](https://github.com/nodejs/node/pull/1938) * [[`c87c34c242`](https://github.com/nodejs/node/commit/c87c34c242)] - **build**: fix cherry-pick ooops, fix comment wording (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) * [[`4208dc4fef`](https://github.com/nodejs/node/commit/4208dc4fef)] - **build**: add MSVS 2015 support (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) * [[`834a365113`](https://github.com/nodejs/node/commit/834a365113)] - **build**: DTrace is enabled by default on darwin (Evan Lucas) [#2019](https://github.com/nodejs/node/pull/2019) * [[`c0c0d73269`](https://github.com/nodejs/node/commit/c0c0d73269)] - **build,win**: set env before generating projects (Alexis Campailla) [joyent/node#20109](https://github.com/joyent/node/pull/20109) * [[`9e890fe8b4`](https://github.com/nodejs/node/commit/9e890fe8b4)] - **crypto**: fix VerifyCallback in case of verify error (Shigeki Ohtsu) [#2064](https://github.com/nodejs/node/pull/2064) * [[`1f371e3988`](https://github.com/nodejs/node/commit/1f371e3988)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#2016](https://github.com/nodejs/node/pull/2016) * [[`c370bd3aea`](https://github.com/nodejs/node/commit/c370bd3aea)] - **doc**: make the abbreviation 1MM clear (Ivan Yan) [#2053](https://github.com/nodejs/node/pull/2053) * [[`54d5437566`](https://github.com/nodejs/node/commit/54d5437566)] - **doc**: Added sample command to test iojs build (Jimmy Hsu) [#850](https://github.com/nodejs/node/pull/850) * [[`f1f1b7e597`](https://github.com/nodejs/node/commit/f1f1b7e597)] - **doc**: add TSC meeting minutes 2015-06-17 (Rod Vagg) [#2048](https://github.com/nodejs/node/pull/2048) * [[`dbd5dc932d`](https://github.com/nodejs/node/commit/dbd5dc932d)] - **doc**: clarify prerequisites in benchmark/README.md (Jeremiah Senkpiel) [#2034](https://github.com/nodejs/node/pull/2034) * [[`50dbc8e143`](https://github.com/nodejs/node/commit/50dbc8e143)] - **doc**: add TSC meeting minutes 2015-05-27 (Rod Vagg) [#2037](https://github.com/nodejs/node/pull/2037) * [[`941ad362a7`](https://github.com/nodejs/node/commit/941ad362a7)] - **doc**: archive io.js TC minutes (Rod Vagg) * [[`644b2eaa89`](https://github.com/nodejs/node/commit/644b2eaa89)] - **doc**: rename tc-meetings to tsc-meetings (Rod Vagg) * [[`1330ee3b27`](https://github.com/nodejs/node/commit/1330ee3b27)] - **doc**: add TC meeting 2015-05-13 minutes (Rod Vagg) [#1700](https://github.com/nodejs/node/pull/1700) * [[`392e8fd64e`](https://github.com/nodejs/node/commit/392e8fd64e)] - **doc**: add @shigeki and @mscdex to TC (Rod Vagg) [#2008](https://github.com/nodejs/node/pull/2008) * [[`af249fa8a1`](https://github.com/nodejs/node/commit/af249fa8a1)] - **net**: wrap connect in nextTick (Evan Lucas) [#2054](https://github.com/nodejs/node/pull/2054) * [[`7f63449fde`](https://github.com/nodejs/node/commit/7f63449fde)] - **net**: fix debug for dnsopts (Evan Lucas) [#2059](https://github.com/nodejs/node/pull/2059) * [[`eabed2f518`](https://github.com/nodejs/node/commit/eabed2f518)] - **repl**: remove obsolete TODO (Rich Trott) [#2081](https://github.com/nodejs/node/pull/2081) * [[`a198c68b56`](https://github.com/nodejs/node/commit/a198c68b56)] - **repl**: make 'Unexpected token' errors recoverable (Julien Gilli) [#2052](https://github.com/nodejs/node/pull/2052) * [[`d735b2c6ef`](https://github.com/nodejs/node/commit/d735b2c6ef)] - **repl**: fix tab completion for a non-global context (Sangmin Yoon) [#2052](https://github.com/nodejs/node/pull/2052) * [[`8cee8f54fc`](https://github.com/nodejs/node/commit/8cee8f54fc)] - **src**: nix stdin _readableState.reading manipulation (Chris Dickinson) [#454](https://github.com/nodejs/node/pull/454) * [[`856c11f8c8`](https://github.com/nodejs/node/commit/856c11f8c8)] - **test**: purge stale disabled tests (Rich Trott) [#2045](https://github.com/nodejs/node/pull/2045) * [[`4d5089e181`](https://github.com/nodejs/node/commit/4d5089e181)] - **test**: do not swallow OpenSSL support error (Rich Trott) [#2042](https://github.com/nodejs/node/pull/2042) * [[`06721fe005`](https://github.com/nodejs/node/commit/06721fe005)] - **test**: fix test-repl-tab-complete.js (cjihrig) [#2052](https://github.com/nodejs/node/pull/2052) * [[`8e9089ac35`](https://github.com/nodejs/node/commit/8e9089ac35)] - **test**: check for error on Windows (Rich Trott) [#2035](https://github.com/nodejs/node/pull/2035) * [[`776a65ebcd`](https://github.com/nodejs/node/commit/776a65ebcd)] - **test**: remove obsolete TODO comments (Rich Trott) [#2033](https://github.com/nodejs/node/pull/2033) * [[`bdfeb798ad`](https://github.com/nodejs/node/commit/bdfeb798ad)] - **test**: remove obsolete TODO comments (Rich Trott) [#2032](https://github.com/nodejs/node/pull/2032) * [[`58e914f9bc`](https://github.com/nodejs/node/commit/58e914f9bc)] - **tools**: fix gyp to work on MacOSX without XCode (Shigeki Ohtsu) [iojs/io.js#1325](https://github.com/iojs/io.js/pull/1325) * [[`99cbbc0a13`](https://github.com/nodejs/node/commit/99cbbc0a13)] - **tools**: update gyp to 25ed9ac (Ben Noordhuis) [#2074](https://github.com/nodejs/node/pull/2074) * [[`e3f9335c40`](https://github.com/nodejs/node/commit/e3f9335c40)] - **tools**: re-enable comma-spacing linter rule (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) * [[`d91e10b3bd`](https://github.com/nodejs/node/commit/d91e10b3bd)] - **tools**: update eslint to 0.24.0 (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) * [[`6c61ca5325`](https://github.com/nodejs/node/commit/6c61ca5325)] - **url**: fix typo in comment (Rich Trott) [#2071](https://github.com/nodejs/node/pull/2071) * [[`1a51f0058c`](https://github.com/nodejs/node/commit/1a51f0058c)] - **v8**: cherry-pick JitCodeEvent patch from upstream (Ben Noordhuis) [#2075](https://github.com/nodejs/node/pull/2075) ## 2015-06-23, Version 2.3.1, @rvagg ### Notable changes * **module**: The number of syscalls made during a `require()` have been significantly reduced again (see [#1801](https://github.com/nodejs/node/pull/1801) from v2.2.0 for previous work), which should lead to a performance improvement (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920). * **npm**: * Upgrade to [v2.11.2](https://github.com/npm/npm/releases/tag/v2.11.2) (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956). * Upgrade to [v2.11.3](https://github.com/npm/npm/releases/tag/v2.11.3) (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018). * **zlib**: A bug was discovered where the process would abort if the final part of a zlib decompression results in a buffer that would exceed the maximum length of `0x3fffffff` bytes (~1GiB). This was likely to only occur during buffered decompression (rather than streaming). This is now fixed and will instead result in a thrown `RangeError` (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ## Commits * [[`e56758a5e0`](https://github.com/nodejs/node/commit/e56758a5e0)] - **async-wrap**: add provider id and object info cb (Trevor Norris) [#1896](https://github.com/nodejs/node/pull/1896) * [[`d5637e67c9`](https://github.com/nodejs/node/commit/d5637e67c9)] - **buffer**: fix cyclic dependency with util (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) * [[`c5353d7c62`](https://github.com/nodejs/node/commit/c5353d7c62)] - **build**: remove lint from test-ci on windows (Johan Bergström) [#2004](https://github.com/nodejs/node/pull/2004) * [[`c207e8d223`](https://github.com/nodejs/node/commit/c207e8d223)] - **build**: fix pkg-config output parsing in configure (Ben Noordhuis) [#1986](https://github.com/nodejs/node/pull/1986) * [[`8d8a26e8f7`](https://github.com/nodejs/node/commit/8d8a26e8f7)] - **build**: don't run lint from test-ci (Johan Bergström) [#1965](https://github.com/nodejs/node/pull/1965) * [[`1ec53c044d`](https://github.com/nodejs/node/commit/1ec53c044d)] - **build**: simplify execution of built binary (Johan Bergström) [#1955](https://github.com/nodejs/node/pull/1955) * [[`3beb880716`](https://github.com/nodejs/node/commit/3beb880716)] - **crypto**: add cert check to CNNIC Whitelist (Shigeki Ohtsu) [#1895](https://github.com/nodejs/node/pull/1895) * [[`48c0fb8b1a`](https://github.com/nodejs/node/commit/48c0fb8b1a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`6a359b1ce9`](https://github.com/nodejs/node/commit/6a359b1ce9)] - **deps**: upgrade to npm 2.11.3 (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018) * [[`6aab2f3b9a`](https://github.com/nodejs/node/commit/6aab2f3b9a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`3e12561b55`](https://github.com/nodejs/node/commit/3e12561b55)] - **deps**: upgrade to npm 2.11.2 (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956) * [[`8ac50819b6`](https://github.com/nodejs/node/commit/8ac50819b6)] - **doc**: add security section to README.md (Rod Vagg) [#1948](https://github.com/nodejs/node/pull/1948) * [[`1f93b63b11`](https://github.com/nodejs/node/commit/1f93b63b11)] - **doc**: change the info to the same as in gitconfig (Christian Tellnes) [#2000](https://github.com/nodejs/node/pull/2000) * [[`0cf94e6856`](https://github.com/nodejs/node/commit/0cf94e6856)] - **doc**: mention CI in Collaborator Guide (Rich Trott) [#1995](https://github.com/nodejs/node/pull/1995) * [[`7a3006efe4`](https://github.com/nodejs/node/commit/7a3006efe4)] - **doc**: add TOC links to Collaborator Guide (Rich Trott) [#1994](https://github.com/nodejs/node/pull/1994) * [[`30638b150f`](https://github.com/nodejs/node/commit/30638b150f)] - **doc**: add TSC meeting notes 2015-06-10 (Bert Belder) [#1943](https://github.com/nodejs/node/pull/1943) * [[`c4ec04136b`](https://github.com/nodejs/node/commit/c4ec04136b)] - **doc**: reformat authors section (Johan Bergström) [#1966](https://github.com/nodejs/node/pull/1966) * [[`96165f9be2`](https://github.com/nodejs/node/commit/96165f9be2)] - **doc**: minor clarification in the modules API doc. (Сковорода Никита Андреевич) [#1983](https://github.com/nodejs/node/pull/1983) * [[`5c2707c1b2`](https://github.com/nodejs/node/commit/5c2707c1b2)] - **doc**: benchmark/README.md copyedit (Rich Trott) [#1970](https://github.com/nodejs/node/pull/1970) * [[`74fdf732d0`](https://github.com/nodejs/node/commit/74fdf732d0)] - **doc**: copyedit COLLABORATOR_GUIDE.md (Rich Trott) [#1964](https://github.com/nodejs/node/pull/1964) * [[`5fe6e83640`](https://github.com/nodejs/node/commit/5fe6e83640)] - **doc**: copyedit GOVERNANCE.md (Rich Trott) [#1963](https://github.com/nodejs/node/pull/1963) * [[`428526544c`](https://github.com/nodejs/node/commit/428526544c)] - **doc**: add ChALkeR as collaborator (Сковорода Никита Андреевич) [#1927](https://github.com/nodejs/node/pull/1927) * [[`5dfe0d5d61`](https://github.com/nodejs/node/commit/5dfe0d5d61)] - **doc**: remove irrelevant SEMVER-MINOR & MAJOR (Rod Vagg) * [[`fb8811d95e`](https://github.com/nodejs/node/commit/fb8811d95e)] - **lib,test**: fix whitespace issues (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) * [[`a4f4909f3d`](https://github.com/nodejs/node/commit/a4f4909f3d)] - **module**: fix stat with long paths on Windows (Michaël Zasso) [#2013](https://github.com/nodejs/node/pull/2013) * [[`a71ee93afe`](https://github.com/nodejs/node/commit/a71ee93afe)] - **module**: reduce syscalls during require search (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920) * [[`671e64ac73`](https://github.com/nodejs/node/commit/671e64ac73)] - **module**: allow long paths for require on Windows (Michaël Zasso) * [[`061342a500`](https://github.com/nodejs/node/commit/061342a500)] - **net**: Defer reading until listeners could be added (James Hartig) [#1496](https://github.com/nodejs/node/pull/1496) * [[`5d2b846d11`](https://github.com/nodejs/node/commit/5d2b846d11)] - **test**: assert tmp and fixture dirs different (Rich Trott) [#2015](https://github.com/nodejs/node/pull/2015) * [[`b0990ef45d`](https://github.com/nodejs/node/commit/b0990ef45d)] - **test**: confirm symlink (Rich Trott) [#2014](https://github.com/nodejs/node/pull/2014) * [[`3ba4f71fc4`](https://github.com/nodejs/node/commit/3ba4f71fc4)] - **test**: check result as early as possible (Rich Trott) [#2007](https://github.com/nodejs/node/pull/2007) * [[`0abcf44d6b`](https://github.com/nodejs/node/commit/0abcf44d6b)] - **test**: add Buffer slice UTF-8 test (Rich Trott) [#1989](https://github.com/nodejs/node/pull/1989) * [[`88c1831ff4`](https://github.com/nodejs/node/commit/88c1831ff4)] - **test**: tmpdir creation failures should fail tests (Rich Trott) [#1976](https://github.com/nodejs/node/pull/1976) * [[`52a822d944`](https://github.com/nodejs/node/commit/52a822d944)] - **test**: fix test-cluster-worker-disconnect (Santiago Gimeno) [#1919](https://github.com/nodejs/node/pull/1919) * [[`7c79490bfb`](https://github.com/nodejs/node/commit/7c79490bfb)] - **test**: only refresh tmpDir for tests that need it (Rich Trott) [#1954](https://github.com/nodejs/node/pull/1954) * [[`88d7904c0b`](https://github.com/nodejs/node/commit/88d7904c0b)] - **test**: remove test repetition (Rich Trott) [#1874](https://github.com/nodejs/node/pull/1874) * [[`91dfb5e094`](https://github.com/nodejs/node/commit/91dfb5e094)] - **tools**: make test-npm work without global npm (Jeremiah Senkpiel) [#1926](https://github.com/nodejs/node/pull/1926) * [[`3777f41562`](https://github.com/nodejs/node/commit/3777f41562)] - **tools**: enable whitespace related rules in eslint (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) * [[`626432d843`](https://github.com/nodejs/node/commit/626432d843)] - **util**: dont repeat isBuffer (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) * [[`1d79f572f1`](https://github.com/nodejs/node/commit/1d79f572f1)] - **util**: move deprecate() to internal module (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) * [[`4b4b1760b5`](https://github.com/nodejs/node/commit/4b4b1760b5)] - **v8**: cherry-pick uclibc build patch from upstream (Ben Noordhuis) [#1974](https://github.com/nodejs/node/pull/1974) * [[`5d0cee46bb`](https://github.com/nodejs/node/commit/5d0cee46bb)] - **vm**: remove unnecessary HandleScopes (Ben Noordhuis) [#2001](https://github.com/nodejs/node/pull/2001) * [[`0ecf9457b5`](https://github.com/nodejs/node/commit/0ecf9457b5)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) * [[`953b3e75e8`](https://github.com/nodejs/node/commit/953b3e75e8)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) * [[`3806d875d3`](https://github.com/nodejs/node/commit/3806d875d3)] - **zlib**: prevent uncaught exception in zlibBuffer (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811) ## 2015-06-22, Version 0.12.5 (Stable) ### Commits * [[`456c22f63f`](https://github.com/nodejs/node/commit/456c22f63f)] - **openssl**: upgrade to 1.0.1o (Addressing multiple CVEs) [#25523](https://github.com/joyent/node/pull/25523) * [[`20d8db1a42`](https://github.com/nodejs/node/commit/20d8db1a42)] - **npm**: upgrade to 2.11.2 [#25517](https://github.com/joyent/node/pull/25517) * [[`50f961596d`](https://github.com/nodejs/node/commit/50f961596d)] - **uv**: upgrade to 1.6.1 [#25475](https://github.com/joyent/node/pull/25475) * [[`b81a643f9a`](https://github.com/nodejs/node/commit/b81a643f9a)] - **V8**: avoid deadlock when profiling is active (Dmitri Melikyan) [#25309](https://github.com/joyent/node/pull/25309) * [[`9d19dfbfdb`](https://github.com/nodejs/node/commit/9d19dfbfdb)] - **install**: fix source path for openssl headers (Oguz Bastemur) [#14089](https://github.com/joyent/node/pull/14089) * [[`4028669531`](https://github.com/nodejs/node/commit/4028669531)] - **install**: make sure opensslconf.h is overwritten (Oguz Bastemur) [#14089](https://github.com/joyent/node/pull/14089) * [[`d38e865fce`](https://github.com/nodejs/node/commit/d38e865fce)] - **timers**: fix timeout when added in timer's callback (Julien Gilli) [#17203](https://github.com/joyent/node/pull/17203) * [[`e7c84f82c7`](https://github.com/nodejs/node/commit/e7c84f82c7)] - **windows**: broadcast WM_SETTINGCHANGE after install (Mathias Küsel) [#25100](https://github.com/joyent/node/pull/25100) ## 2015-06-18, Version 0.10.39 (Maintenance) ### Commits * [[`456c22f63f`](https://github.com/nodejs/node/commit/456c22f63f)] - **openssl**: upgrade to 1.0.1o (Addressing multiple CVEs) [#25523](https://github.com/joyent/node/pull/25523) * [[`9d19dfbfdb`](https://github.com/nodejs/node/commit/9d19dfbfdb)] - **install**: fix source path for openssl headers (Oguz Bastemur) [#14089](https://github.com/joyent/node/pull/14089) * [[`4028669531`](https://github.com/nodejs/node/commit/4028669531)] - **install**: make sure opensslconf.h is overwritten (Oguz Bastemur) [#14089](https://github.com/joyent/node/pull/14089) * [[`d38e865fce`](https://github.com/nodejs/node/commit/d38e865fce)] - **timers**: fix timeout when added in timer's callback (Julien Gilli) [#17203](https://github.com/joyent/node/pull/17203) * [[`e7c84f82c7`](https://github.com/nodejs/node/commit/e7c84f82c7)] - **windows**: broadcast WM_SETTINGCHANGE after install (Mathias Küsel) [#25100](https://github.com/joyent/node/pull/25100) ## 2015-06-13, Version 2.3.0, @rvagg ### Notable changes * **libuv**: Upgraded to 1.6.0 and 1.6.1, see [full ChangeLog](https://github.com/libuv/libuv/blob/60e515d9e6f3d86c0eedad583805201f32ea3aed/ChangeLog#L1-L36) for details. (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) [#1889](https://github.com/nodejs/node/pull/1889). Highlights include: - Fix TTY becoming blocked on OS X - Fix UDP send callbacks to not to be synchronous - Add `uv_os_homedir()` (exposed as `os.homedir()`, see below) * **npm**: See full [release notes](https://github.com/npm/npm/releases/tag/v2.11.1) for details. (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899). Highlight: - Use GIT_SSH_COMMAND (available as of Git 2.3) * **openssl**: - Upgrade to 1.0.2b and 1.0.2c, introduces DHE man-in-the-middle protection (Logjam) and fixes malformed ECParameters causing infinite loop (CVE-2015-1788). See the [security advisory](https://www.openssl.org/news/secadv_20150611.txt) for full details. (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) [#1958](https://github.com/nodejs/node/pull/1958) - Support [FIPS](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards) mode of OpenSSL, see [README](https://github.com/nodejs/node#building-iojs-with-fips-compliant-openssl) for instructions. (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) * **os**: Add `os.homedir()` method. (Colin Ihrig) [#1791](https://github.com/nodejs/node/pull/1791) * **smalloc**: Deprecate whole module. (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) * Add new collaborators: - Alex Kocharin ([@rlidwka](https://github.com/rlidwka)) - Christopher Monsanto ([@monsanto](https://github.com/monsanto)) - Ali Ijaz Sheikh ([@ofrobots](https://github.com/ofrobots)) - Oleg Elifantiev ([@Olegas](https://github.com/Olegas)) - Domenic Denicola ([@domenic](https://github.com/domenic)) - Rich Trott ([@Trott](https://github.com/Trott)) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ## Commits * [[`9c0a1b8cfc`](https://github.com/nodejs/node/commit/9c0a1b8cfc)] - **cluster**: wait on servers closing before disconnect (Oleg Elifantiev) [#1400](https://github.com/nodejs/node/pull/1400) * [[`0f68377f69`](https://github.com/nodejs/node/commit/0f68377f69)] - **crypto**: support FIPS mode of OpenSSL (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) * [[`38d1afc24d`](https://github.com/nodejs/node/commit/38d1afc24d)] - **(SEMVER-MINOR)** **crypto**: add getCurves() to get supported ECs (Brian White) [#1914](https://github.com/nodejs/node/pull/1914) * [[`a4dbf45b59`](https://github.com/nodejs/node/commit/a4dbf45b59)] - **crypto**: update root certificates (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) * [[`81029c639a`](https://github.com/nodejs/node/commit/81029c639a)] - **debugger**: improve ESRCH error message (Jackson Tian) [#1863](https://github.com/nodejs/node/pull/1863) * [[`2a7fd0ad32`](https://github.com/nodejs/node/commit/2a7fd0ad32)] - **deps**: update UPGRADING.md doc to openssl-1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) * [[`6b3df929e0`](https://github.com/nodejs/node/commit/6b3df929e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) * [[`664a659696`](https://github.com/nodejs/node/commit/664a659696)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) * [[`42a8de2ac6`](https://github.com/nodejs/node/commit/42a8de2ac6)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`c66c3d9fa3`](https://github.com/nodejs/node/commit/c66c3d9fa3)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`86737cf0a0`](https://github.com/nodejs/node/commit/86737cf0a0)] - **deps**: upgrade openssl sources to 1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) * [[`94804969b7`](https://github.com/nodejs/node/commit/94804969b7)] - **deps**: update asm files for openssl-1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) * [[`38444915e0`](https://github.com/nodejs/node/commit/38444915e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) * [[`f62b613252`](https://github.com/nodejs/node/commit/f62b613252)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) * [[`f624d0122c`](https://github.com/nodejs/node/commit/f624d0122c)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`dcd67cc8d7`](https://github.com/nodejs/node/commit/dcd67cc8d7)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`c21b24decf`](https://github.com/nodejs/node/commit/c21b24decf)] - **deps**: upgrade openssl sources to 1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) * [[`2dc819b09a`](https://github.com/nodejs/node/commit/2dc819b09a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`f41b7f12b5`](https://github.com/nodejs/node/commit/f41b7f12b5)] - **deps**: upgrade to npm 2.11.1 (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899) * [[`a5bd466440`](https://github.com/nodejs/node/commit/a5bd466440)] - **deps**: update libuv to version 1.6.1 (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) * [[`aa33db3238`](https://github.com/nodejs/node/commit/aa33db3238)] - **deps**: update libuv to version 1.6.0 (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) * [[`0ee497f0b4`](https://github.com/nodejs/node/commit/0ee497f0b4)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) * [[`b5cd2f0986`](https://github.com/nodejs/node/commit/b5cd2f0986)] - **dgram**: partially revert 18d457b (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) * [[`a3cc43d0a4`](https://github.com/nodejs/node/commit/a3cc43d0a4)] - **doc**: add Trott as collaborator (Rich Trott) [#1962](https://github.com/nodejs/node/pull/1962) * [[`cf5020fc02`](https://github.com/nodejs/node/commit/cf5020fc02)] - **doc**: add domenic as collaborator (Domenic Denicola) [#1942](https://github.com/nodejs/node/pull/1942) * [[`11ed5f31ab`](https://github.com/nodejs/node/commit/11ed5f31ab)] - **doc**: add Olegas as collaborator (Oleg Elifantiev) [#1930](https://github.com/nodejs/node/pull/1930) * [[`f500e1833b`](https://github.com/nodejs/node/commit/f500e1833b)] - **doc**: add ofrobots as collaborator (Ali Ijaz Sheikh) * [[`717724611a`](https://github.com/nodejs/node/commit/717724611a)] - **doc**: add monsanto as collaborator (Christopher Monsanto) [#1932](https://github.com/nodejs/node/pull/1932) * [[`7192b6688c`](https://github.com/nodejs/node/commit/7192b6688c)] - **doc**: add rlidwka as collaborator (Alex Kocharin) [#1929](https://github.com/nodejs/node/pull/1929) * [[`9f3a03f0d4`](https://github.com/nodejs/node/commit/9f3a03f0d4)] - **doc**: add references to crypto.getCurves() (Roman Reiss) [#1918](https://github.com/nodejs/node/pull/1918) * [[`ff39ecb914`](https://github.com/nodejs/node/commit/ff39ecb914)] - **doc**: remove comma splice (Rich Trott) [#1900](https://github.com/nodejs/node/pull/1900) * [[`deb8b87dc9`](https://github.com/nodejs/node/commit/deb8b87dc9)] - **doc**: add note about available ECC curves (Ryan Petschek) [#1913](https://github.com/nodejs/node/pull/1913) * [[`89a5b9040e`](https://github.com/nodejs/node/commit/89a5b9040e)] - **doc**: fix http.IncomingMessage.socket documentation (Сковорода Никита Андреевич) [#1867](https://github.com/nodejs/node/pull/1867) * [[`d29034b34b`](https://github.com/nodejs/node/commit/d29034b34b)] - **doc**: adjust changelog to clarify `client` revert (Rod Vagg) [#1859](https://github.com/nodejs/node/pull/1859) * [[`a79dece8ad`](https://github.com/nodejs/node/commit/a79dece8ad)] - **docs**: add return value for sync fs functions (Tyler Anton) [#1770](https://github.com/nodejs/node/pull/1770) * [[`1cb72c14c4`](https://github.com/nodejs/node/commit/1cb72c14c4)] - **docs**: delete unused/duplicate css files (Robert Kowalski) [#1770](https://github.com/nodejs/node/pull/1770) * [[`53a4eb3198`](https://github.com/nodejs/node/commit/53a4eb3198)] - **fs**: make SyncWriteStream non-enumerable (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) * [[`a011c3243f`](https://github.com/nodejs/node/commit/a011c3243f)] - **fs**: minor refactoring (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) * [[`8841132f30`](https://github.com/nodejs/node/commit/8841132f30)] - **fs**: remove inStatWatchers and use Map for lookup (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) * [[`67a11b9bcc`](https://github.com/nodejs/node/commit/67a11b9bcc)] - **fs**: removing unnecessary nullCheckCallNT (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) * [[`09f2a67bd8`](https://github.com/nodejs/node/commit/09f2a67bd8)] - **fs**: improve error message descriptions (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) * [[`2dcef83b5f`](https://github.com/nodejs/node/commit/2dcef83b5f)] - **fs**: use `kMaxLength` from binding (Vladimir Kurchatkin) [#1903](https://github.com/nodejs/node/pull/1903) * [[`353e26e3c7`](https://github.com/nodejs/node/commit/353e26e3c7)] - **(SEMVER-MINOR)** **fs**: Add string encoding option for Stream method (Yosuke Furukawa) [#1845](https://github.com/nodejs/node/pull/1845) * [[`8357c5084b`](https://github.com/nodejs/node/commit/8357c5084b)] - **fs**: set encoding on fs.createWriteStream (Yosuke Furukawa) [#1844](https://github.com/nodejs/node/pull/1844) * [[`02c345020a`](https://github.com/nodejs/node/commit/02c345020a)] - **gitignore**: don't ignore the debug npm module (Kat Marchán) [#1908](https://github.com/nodejs/node/pull/1908) * [[`b5b8ff117c`](https://github.com/nodejs/node/commit/b5b8ff117c)] - **lib**: don't use global Buffer (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) * [[`a251657058`](https://github.com/nodejs/node/commit/a251657058)] - **node**: mark promises as handled as soon as possible (Vladimir Kurchatkin) [#1952](https://github.com/nodejs/node/pull/1952) * [[`2eb170874a`](https://github.com/nodejs/node/commit/2eb170874a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`a130132c8f`](https://github.com/nodejs/node/commit/a130132c8f)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) * [[`6e78e5feaa`](https://github.com/nodejs/node/commit/6e78e5feaa)] - **(SEMVER-MINOR)** **os**: add homedir() (cjihrig) [#1791](https://github.com/nodejs/node/pull/1791) * [[`d9e250295b`](https://github.com/nodejs/node/commit/d9e250295b)] - ***Revert*** "**readline**: allow tabs in input" (Jeremiah Senkpiel) [#1961](https://github.com/nodejs/node/pull/1961) * [[`4b3d493c4b`](https://github.com/nodejs/node/commit/4b3d493c4b)] - **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) * [[`6d95f4ff92`](https://github.com/nodejs/node/commit/6d95f4ff92)] - **(SEMVER-MINOR)** **smalloc**: deprecate whole module (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) * [[`8c71a9241d`](https://github.com/nodejs/node/commit/8c71a9241d)] - **src**: hide InitializeICUDirectory symbol (Ben Noordhuis) [#1815](https://github.com/nodejs/node/pull/1815) * [[`5b6f575c1f`](https://github.com/nodejs/node/commit/5b6f575c1f)] - ***Revert*** "**src**: add getopt option parser" (Evan Lucas) [#1862](https://github.com/nodejs/node/pull/1862) * [[`c0e7bf2d8c`](https://github.com/nodejs/node/commit/c0e7bf2d8c)] - **src**: add getopt option parser (Evan Lucas) [#1804](https://github.com/nodejs/node/pull/1804) * [[`8ea6844d26`](https://github.com/nodejs/node/commit/8ea6844d26)] - **test**: add test for failed save in REPL (Rich Trott) [#1818](https://github.com/nodejs/node/pull/1818) * [[`03ce84dfa1`](https://github.com/nodejs/node/commit/03ce84dfa1)] - **test**: fix cluster-worker-wait-server-close races (Sam Roberts) [#1953](https://github.com/nodejs/node/pull/1953) * [[`a6b8ee19b8`](https://github.com/nodejs/node/commit/a6b8ee19b8)] - **test**: create temp dir in common.js (Rich Trott) [#1877](https://github.com/nodejs/node/pull/1877) * [[`ff8202c6f4`](https://github.com/nodejs/node/commit/ff8202c6f4)] - **test**: fix undeclared variable access (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) * [[`d9ddd7d345`](https://github.com/nodejs/node/commit/d9ddd7d345)] - **test**: remove TODO comment (Rich Trott) [#1820](https://github.com/nodejs/node/pull/1820) * [[`6537fd4b55`](https://github.com/nodejs/node/commit/6537fd4b55)] - **test**: remove TODO (Rich Trott) [#1875](https://github.com/nodejs/node/pull/1875) * [[`a804026c9b`](https://github.com/nodejs/node/commit/a804026c9b)] - **test**: fix broken FreeBSD test (Santiago Gimeno) [#1881](https://github.com/nodejs/node/pull/1881) * [[`43a82f8a71`](https://github.com/nodejs/node/commit/43a82f8a71)] - **test**: fix test-sync-io-option (Evan Lucas) [#1840](https://github.com/nodejs/node/pull/1840) * [[`4ed25f664d`](https://github.com/nodejs/node/commit/4ed25f664d)] - **test**: add -no_rand_screen for tls-server-verify (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) * [[`4cf323d23d`](https://github.com/nodejs/node/commit/4cf323d23d)] - **test**: kill child in tls-server-verify for speed up (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) * [[`e6ccdcc1fe`](https://github.com/nodejs/node/commit/e6ccdcc1fe)] - **test**: improve console output of tls-server-verify (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) * [[`975e5956f0`](https://github.com/nodejs/node/commit/975e5956f0)] - **test**: run tls-server-verify servers in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) * [[`b18604ba2c`](https://github.com/nodejs/node/commit/b18604ba2c)] - **test**: running tls-server-verify clients in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) * [[`f78c722df5`](https://github.com/nodejs/node/commit/f78c722df5)] - **test**: remove hardwired references to 'iojs' (Rod Vagg) [#1882](https://github.com/nodejs/node/pull/1882) * [[`bd99e8de8e`](https://github.com/nodejs/node/commit/bd99e8de8e)] - **test**: more test coverage for maxConnections (Rich Trott) [#1855](https://github.com/nodejs/node/pull/1855) * [[`b9267189a5`](https://github.com/nodejs/node/commit/b9267189a5)] - **test**: fix test-child-process-stdout-flush-exit (Santiago Gimeno) [#1868](https://github.com/nodejs/node/pull/1868) * [[`d20f018dcf`](https://github.com/nodejs/node/commit/d20f018dcf)] - **test**: loosen condition to detect infinite loop (Yosuke Furukawa) [#1857](https://github.com/nodejs/node/pull/1857) * [[`e0e96acc6f`](https://github.com/nodejs/node/commit/e0e96acc6f)] - **test**: remove smalloc add-on test (Ben Noordhuis) [#1835](https://github.com/nodejs/node/pull/1835) * [[`8704c58fc4`](https://github.com/nodejs/node/commit/8704c58fc4)] - **test**: remove unneeded comment task (Rich Trott) [#1858](https://github.com/nodejs/node/pull/1858) * [[`8732977536`](https://github.com/nodejs/node/commit/8732977536)] - **tls**: fix references to undefined `cb` (Fedor Indutny) [#1951](https://github.com/nodejs/node/pull/1951) * [[`75930bb38c`](https://github.com/nodejs/node/commit/75930bb38c)] - **tls**: prevent use-after-free (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) * [[`5795e835a1`](https://github.com/nodejs/node/commit/5795e835a1)] - **tls**: emit errors on close whilst async action (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) * [[`59d9734e21`](https://github.com/nodejs/node/commit/59d9734e21)] - **tls_wrap**: invoke queued callbacks in DestroySSL (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) * [[`6e4d30286d`](https://github.com/nodejs/node/commit/6e4d30286d)] - **tools**: enable/add additional eslint rules (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) * [[`098354a9f8`](https://github.com/nodejs/node/commit/098354a9f8)] - **tools**: update certdata.txt (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) * [[`a2d921d6a0`](https://github.com/nodejs/node/commit/a2d921d6a0)] - **tools**: customize mk-ca-bundle.pl (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) * [[`5be9efca40`](https://github.com/nodejs/node/commit/5be9efca40)] - **tools**: update mk-ca-bundle.pl to HEAD of upstream (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) * [[`1baba0580d`](https://github.com/nodejs/node/commit/1baba0580d)] - **tools**: Fix copying contents of deps/npm (thefourtheye) [#1853](https://github.com/nodejs/node/pull/1853) * [[`628845b816`](https://github.com/nodejs/node/commit/628845b816)] - **(SEMVER-MINOR)** **util**: introduce `printDeprecationMessage` function (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) * [[`91d0a8b19c`](https://github.com/nodejs/node/commit/91d0a8b19c)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) ## 2015-06-01, Version 2.2.1, @rvagg ### Notable changes * **http**: Reverts the move of the `client` property of `IncomingMessage` to its prototype. Although undocumented, this property was used and assumed to be an "own property" in the wild, most notably by [request](https://github.com/request/request) which is used by npm. (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`c5a1009903`](https://github.com/nodejs/node/commit/c5a1009903)] - **build**: avoid passing empty strings to build flags (Johan Bergström) [#1789](https://github.com/nodejs/node/pull/1789) * [[`5d83401086`](https://github.com/nodejs/node/commit/5d83401086)] - **doc**: put SEMVER-MINOR on pre-load module fix 2.2.0 (Rod Vagg) * [[`4d6b768e5d`](https://github.com/nodejs/node/commit/4d6b768e5d)] - **http**: revert deprecation of client property (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852) ## 2015-05-31, Version 2.2.0, @rvagg ### Notable changes * **node**: Speed-up `require()` by replacing usage of `fs.statSync()` and `fs.readFileSync()` with internal variants that are faster for this use-case and do not create as many objects for the garbage collector to clean up. The primary two benefits are: significant increase in application start-up time on typical applications and better start-up time for the debugger by eliminating almost all of the thousands of exception events. (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801). * **node**: Resolution of pre-load modules (`-r` or `--require`) now follows the standard `require()` rules rather than just resolving paths, so you can now pre-load modules in node_modules. (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812). * **npm**: Upgraded npm to v2.11.0. New hooks for `preversion`, `version`, and `postversion` lifecycle events, some SPDX-related license changes and license file inclusions. See the [release notes](https://github.com/npm/npm/releases/tag/v2.11.0) for full details. ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`a77c330c32`](https://github.com/nodejs/node/commit/a77c330c32)] - **(SEMVER-MINOR)** **child_process**: expose ChildProcess constructor (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) * [[`3a1bc067d4`](https://github.com/nodejs/node/commit/3a1bc067d4)] - ***Revert*** "**core**: set PROVIDER type as Persistent class id" (Ben Noordhuis) [#1827](https://github.com/nodejs/node/pull/1827) * [[`f9fd554500`](https://github.com/nodejs/node/commit/f9fd554500)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`c1afa53648`](https://github.com/nodejs/node/commit/c1afa53648)] - **deps**: upgrade npm to 2.11.0 (Forrest L Norvell) [iojs/io.js#1829](https://github.com/iojs/io.js/pull/1829) * [[`ff794498e7`](https://github.com/nodejs/node/commit/ff794498e7)] - **doc**: `fs.*File()` also accept encoding strings (Rich Trott) [#1806](https://github.com/nodejs/node/pull/1806) * [[`98649fd31a`](https://github.com/nodejs/node/commit/98649fd31a)] - **doc**: add documentation for AtExit hook (Steve Sharp) [#1014](https://github.com/nodejs/node/pull/1014) * [[`eb1856dfd1`](https://github.com/nodejs/node/commit/eb1856dfd1)] - **doc**: clarify stability of fs.watch and relatives (Rich Trott) [#1775](https://github.com/nodejs/node/pull/1775) * [[`a74c2c9458`](https://github.com/nodejs/node/commit/a74c2c9458)] - **doc**: state url decoding behavior (Josh Gummersall) [#1731](https://github.com/nodejs/node/pull/1731) * [[`ba76a9d872`](https://github.com/nodejs/node/commit/ba76a9d872)] - **doc**: remove bad semver-major entry from CHANGELOG (Rod Vagg) [#1782](https://github.com/nodejs/node/pull/1782) * [[`a6a3f8c78d`](https://github.com/nodejs/node/commit/a6a3f8c78d)] - **doc**: fix changelog s/2.0.3/2.1.0 (Rod Vagg) * [[`2c686fd3ce`](https://github.com/nodejs/node/commit/2c686fd3ce)] - **http**: flush stored header (Vladimir Kurchatkin) [#1695](https://github.com/nodejs/node/pull/1695) * [[`1eec5f091a`](https://github.com/nodejs/node/commit/1eec5f091a)] - **http**: simplify code and remove unused properties (Brian White) [#1572](https://github.com/nodejs/node/pull/1572) * [[`1bbf8d0720`](https://github.com/nodejs/node/commit/1bbf8d0720)] - **lib**: speed up require(), phase 2 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) * [[`b14fd1a720`](https://github.com/nodejs/node/commit/b14fd1a720)] - **lib**: speed up require(), phase 1 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) * [[`5abd4ac079`](https://github.com/nodejs/node/commit/5abd4ac079)] - **lib**: simplify nextTick() usage (Brian White) [#1612](https://github.com/nodejs/node/pull/1612) * [[`5759722cfa`](https://github.com/nodejs/node/commit/5759722cfa)] - **(SEMVER-MINOR)** **src**: fix module search path for preload modules (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812) * [[`a65762cab6`](https://github.com/nodejs/node/commit/a65762cab6)] - **src**: remove old code (Brendan Ashworth) [#1819](https://github.com/nodejs/node/pull/1819) * [[`93a44d5228`](https://github.com/nodejs/node/commit/93a44d5228)] - **src**: fix deferred events not working with -e (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) * [[`8059393934`](https://github.com/nodejs/node/commit/8059393934)] - **test**: check error type from net.Server.listen() (Rich Trott) [#1821](https://github.com/nodejs/node/pull/1821) * [[`4e90c82cdb`](https://github.com/nodejs/node/commit/4e90c82cdb)] - **test**: add heap profiler add-on regression test (Ben Noordhuis) [#1828](https://github.com/nodejs/node/pull/1828) * [[`6dfca71af0`](https://github.com/nodejs/node/commit/6dfca71af0)] - **test**: don't lint autogenerated test/addons/doc-*/ (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) * [[`c2b8b30836`](https://github.com/nodejs/node/commit/c2b8b30836)] - **test**: remove stray copyright notices (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) * [[`280fb01daf`](https://github.com/nodejs/node/commit/280fb01daf)] - **test**: fix deprecation warning in addons test (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) * [[`8606793999`](https://github.com/nodejs/node/commit/8606793999)] - **tools**: pass constant to logger instead of string (Johan Bergström) [#1842](https://github.com/nodejs/node/pull/1842) * [[`fbd2b59716`](https://github.com/nodejs/node/commit/fbd2b59716)] - **tools**: add objectLiteralShorthandProperties to .eslintrc (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) * [[`53e98cc1b4`](https://github.com/nodejs/node/commit/53e98cc1b4)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) ## 2015-05-24, Version 2.1.0, @rvagg ### Notable changes * **crypto**: Diffie-Hellman key exchange (DHE) parameters (`'dhparams'`) must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739). * **node**: A new `--trace-sync-io` command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707). * **node**: To allow for chaining of methods, the `setTimeout()`, `setKeepAlive()`, `setNoDelay()`, `ref()` and `unref()` methods used in `'net'`, `'dgram'`, `'http'`, `'https'` and `'tls'` now return the current instance instead of `undefined` (Roman Reiss & Evan Lucas) [#1699](https://github.com/nodejs/node/pull/1699) [#1768](https://github.com/nodejs/node/pull/1768) [#1779](https://github.com/nodejs/node/pull/1779). * **npm**: Upgraded to v2.10.1, release notes can be found in and . * **util**: A significant speed-up (in the order of 35%) for the common-case of a single string argument to `util.format()`, used by `console.log()` (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749). ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`9da168b71f`](https://github.com/nodejs/node/commit/9da168b71f)] - **buffer**: optimize Buffer.byteLength (Brendan Ashworth) [#1713](https://github.com/nodejs/node/pull/1713) * [[`2b1c01c2cc`](https://github.com/nodejs/node/commit/2b1c01c2cc)] - **build**: refactor pkg-config for shared libraries (Johan Bergström) [#1603](https://github.com/nodejs/node/pull/1603) * [[`3c44100558`](https://github.com/nodejs/node/commit/3c44100558)] - **core**: set PROVIDER type as Persistent class id (Trevor Norris) [#1730](https://github.com/nodejs/node/pull/1730) * [[`c1de6d249e`](https://github.com/nodejs/node/commit/c1de6d249e)] - **(SEMVER-MINOR)** **core**: implement runtime flag to trace sync io (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707) * [[`9e7099fa4e`](https://github.com/nodejs/node/commit/9e7099fa4e)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) * [[`c54d057598`](https://github.com/nodejs/node/commit/c54d057598)] - **deps**: upgrade to npm 2.10.1 (Rebecca Turner) [#1763](https://github.com/nodejs/node/pull/1763) * [[`367ffd167d`](https://github.com/nodejs/node/commit/367ffd167d)] - **doc**: update AUTHORS list (Rod Vagg) [#1776](https://github.com/nodejs/node/pull/1776) * [[`2bb2f06b3e`](https://github.com/nodejs/node/commit/2bb2f06b3e)] - **doc**: fix typo in CONTRIBUTING.md (Rich Trott) [#1755](https://github.com/nodejs/node/pull/1755) * [[`515afc6367`](https://github.com/nodejs/node/commit/515afc6367)] - **doc**: path is ignored in url.format (Maurice Butler) [#1753](https://github.com/nodejs/node/pull/1753) * [[`f0a8bc3f84`](https://github.com/nodejs/node/commit/f0a8bc3f84)] - **doc**: fix spelling in CHANGELOG (Felipe Batista) * [[`86dd244d9b`](https://github.com/nodejs/node/commit/86dd244d9b)] - **doc**: add notes to child_process.fork() and .exec() (Rich Trott) [#1718](https://github.com/nodejs/node/pull/1718) * [[`066274794c`](https://github.com/nodejs/node/commit/066274794c)] - **doc**: update links from iojs/io.js to nodejs/io.js (Frederic Hemberger) [#1715](https://github.com/nodejs/node/pull/1715) * [[`cb381fe3e0`](https://github.com/nodejs/node/commit/cb381fe3e0)] - **(SEMVER-MINOR)** **net**: return this from setNoDelay and setKeepAlive (Roman Reiss) [#1779](https://github.com/nodejs/node/pull/1779) * [[`85d9983009`](https://github.com/nodejs/node/commit/85d9983009)] - **net**: persist net.Socket options before connect (Evan Lucas) [#1518](https://github.com/nodejs/node/pull/1518) * [[`39dde3222e`](https://github.com/nodejs/node/commit/39dde3222e)] - **(SEMVER-MINOR)** **net,dgram**: return this from ref and unref methods (Roman Reiss) [#1768](https://github.com/nodejs/node/pull/1768) * [[`5773438913`](https://github.com/nodejs/node/commit/5773438913)] - **test**: fix jslint error (Michaël Zasso) [#1743](https://github.com/nodejs/node/pull/1743) * [[`867631986f`](https://github.com/nodejs/node/commit/867631986f)] - **test**: fix test-sync-io-option (Santiago Gimeno) [#1734](https://github.com/nodejs/node/pull/1734) * [[`f29762f4dd`](https://github.com/nodejs/node/commit/f29762f4dd)] - **test**: enable linting for tests (Roman Reiss) [#1721](https://github.com/nodejs/node/pull/1721) * [[`2a71f02988`](https://github.com/nodejs/node/commit/2a71f02988)] - **tls**: emit errors happening before handshake finish (Malte-Thorben Bruns) [#1769](https://github.com/nodejs/node/pull/1769) * [[`80342f649d`](https://github.com/nodejs/node/commit/80342f649d)] - **tls**: use `.destroy(err)` instead of destroy+emit (Fedor Indutny) [#1711](https://github.com/nodejs/node/pull/1711) * [[`9b35be5810`](https://github.com/nodejs/node/commit/9b35be5810)] - **tls**: make server not use DHE in less than 1024bits (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739) * [[`214d02040e`](https://github.com/nodejs/node/commit/214d02040e)] - **util**: speed up common case of formatting string (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749) * [[`d144e96fbf`](https://github.com/nodejs/node/commit/d144e96fbf)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) * [[`0d6d3dda95`](https://github.com/nodejs/node/commit/0d6d3dda95)] - **win,node-gyp**: make delay-load hook C89 compliant (Sharat M R) [TooTallNate/node-gyp#616](https://github.com/TooTallNate/node-gyp/pull/616) ## 2015-05-22, Version 0.12.4 (Stable) ### Commits * [[`202c18bbc3`](https://github.com/nodejs/node/commit/202c18bbc3)] - **npm**: upgrade to 2.10.1 [#25364](https://github.com/joyent/node/pull/25364) * [[`6157697bd5`](https://github.com/nodejs/node/commit/6157697bd5)] - **V8**: revert v8 Array.prototype.values() removal (cjihrig) [#25328](https://github.com/joyent/node/pull/25328) * [[`3122052890`](https://github.com/nodejs/node/commit/3122052890)] - **win**: bring back xp/2k3 support (Bert Belder) [#25367](https://github.com/joyent/node/pull/25367) ## 2015-05-15, Version 2.0.2, @Fishrock123 ### Notable changes * **win,node-gyp**: the delay-load hook for windows addons has now been correctly enabled by default, it had wrongly defaulted to off in the release version of 2.0.0 (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) * **os**: `tmpdir()`'s trailing slash stripping has been refined to fix an issue when the temp directory is at '/'. Also considers which slash is used by the operating system. (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) * **tls**: default ciphers have been updated to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) * **build**: v8 snapshots have been re-enabled by default as suggested by the v8 team, since prior security issues have been resolved. This should give some perf improvements to both startup and vm context creation. (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) * **src**: fixed preload modules not working when other flags were used before `--require` (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) * **dgram**: fixed `send()`'s callback not being asynchronous (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) * **readline**: emitKeys now keeps buffering data until it has enough to parse. This fixes an issue with parsing split escapes. (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) * **cluster**: works now properly emit 'disconnect' to `cluser.worker` (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) * **events**: uncaught errors now provide some context (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). ### Commits * [[`8a0e5295b4`](https://github.com/nodejs/node/commit/8a0e5295b4)] - **build**: use backslashes for paths on windows (Johan Bergström) [#1698](https://github.com/nodejs/node/pull/1698) * [[`20c9a52227`](https://github.com/nodejs/node/commit/20c9a52227)] - **build**: move --with-intl to intl optgroup (Johan Bergström) [#1680](https://github.com/nodejs/node/pull/1680) * [[`36cdc7c8ac`](https://github.com/nodejs/node/commit/36cdc7c8ac)] - **build**: re-enable V8 snapshots (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) * [[`5883a59b21`](https://github.com/nodejs/node/commit/5883a59b21)] - **cluster**: disconnect event not emitted correctly (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) * [[`0f850f7ae7`](https://github.com/nodejs/node/commit/0f850f7ae7)] - **deps**: provide TXT chunk info in c-ares (Fedor Indutny) * [[`7e1c0e75ed`](https://github.com/nodejs/node/commit/7e1c0e75ed)] - **deps**: sync with upstream bagder/c-ares@bba4dc5 (Ben Noordhuis) [#1678](https://github.com/nodejs/node/pull/1678) * [[`18d457bd34`](https://github.com/nodejs/node/commit/18d457bd34)] - **dgram**: call send callback asynchronously (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) * [[`8b9a1537ad`](https://github.com/nodejs/node/commit/8b9a1537ad)] - **events**: provide better error message for unhandled error (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) * [[`19ffb5cf1c`](https://github.com/nodejs/node/commit/19ffb5cf1c)] - **lib**: fix eslint styles (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) * [[`76937051f8`](https://github.com/nodejs/node/commit/76937051f8)] - **os**: refine tmpdir() trailing slash stripping (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) * [[`aed6bce906`](https://github.com/nodejs/node/commit/aed6bce906)] - **readline**: turn emitKeys into a streaming parser (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) * [[`0a461e5360`](https://github.com/nodejs/node/commit/0a461e5360)] - **src**: fix preload when used with prior flags (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) * [[`931a0d4634`](https://github.com/nodejs/node/commit/931a0d4634)] - **src**: add type check to v8.setFlagsFromString() (Roman Klauke) [#1652](https://github.com/nodejs/node/pull/1652) * [[`08d08668c9`](https://github.com/nodejs/node/commit/08d08668c9)] - **src,deps**: replace LoadLibrary by LoadLibraryW (Cheng Zhao) [#226](https://github.com/nodejs/node/pull/226) * [[`4e2f999a62`](https://github.com/nodejs/node/commit/4e2f999a62)] - **test**: fix infinite loop detection (Yosuke Furukawa) [#1681](https://github.com/nodejs/node/pull/1681) * [[`5755fc099f`](https://github.com/nodejs/node/commit/5755fc099f)] - **tls**: update default ciphers to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) * [[`966acb9916`](https://github.com/nodejs/node/commit/966acb9916)] - **tools**: remove closure_linter to eslint on windows (Yosuke Furukawa) [#1685](https://github.com/nodejs/node/pull/1685) * [[`c58264e58b`](https://github.com/nodejs/node/commit/c58264e58b)] - **tools**: make eslint work on subdirectories (Roman Reiss) [#1686](https://github.com/nodejs/node/pull/1686) * [[`0b21ab13b7`](https://github.com/nodejs/node/commit/0b21ab13b7)] - **tools**: refactor `make test-npm` into test-npm.sh (Jeremiah Senkpiel) [#1662](https://github.com/nodejs/node/pull/1662) * [[`f07b3b600b`](https://github.com/nodejs/node/commit/f07b3b600b)] - **tools**: set eslint comma-spacing to 'warn' (Roman Reiss) [#1672](https://github.com/nodejs/node/pull/1672) * [[`f9dd34d301`](https://github.com/nodejs/node/commit/f9dd34d301)] - **tools**: replace closure-linter with eslint (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) * [[`64d3210c98`](https://github.com/nodejs/node/commit/64d3210c98)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1667](https://github.com/nodejs/node/issues/1667) ## 2015-05-13, Version 0.12.3 (Stable) ### Commits * [[`32166a90cf`](https://github.com/nodejs/node/commit/32166a90cf)] - **V8**: update to 3.28.71.19 [#18206](https://github.com/joyent/node/pull/18206) * [[`84f1ab6114`](https://github.com/nodejs/node/commit/84f1ab6114)] - **uv**: upgrade to 1.5.0 [#25141](https://github.com/joyent/node/pull/25141) * [[`03cfbd65fb`](https://github.com/nodejs/node/commit/03cfbd65fb)] - **npm**: upgrade to 2.9.1 [#25289](https://github.com/joyent/node/pull/25289) * [[`80cdae855f`](https://github.com/nodejs/node/commit/80cdae855f)] - **V8**: don't busy loop in v8 cpu profiler thread (Mike Tunnicliffe) [#25268](https://github.com/joyent/node/pull/25268) * [[`2a5f4bd7ce`](https://github.com/nodejs/node/commit/2a5f4bd7ce)] - **V8**: fix issue with let bindings in for loops (adamk) [#23948](https://github.com/joyent/node/pull/23948) * [[`f0ef597e09`](https://github.com/nodejs/node/commit/f0ef597e09)] - **debugger**: don't spawn child process in remote mode (Jackson Tian) [#14172](https://github.com/joyent/node/pull/14172) * [[`0e392f3b68`](https://github.com/nodejs/node/commit/0e392f3b68)] - **net**: do not set V4MAPPED on FreeBSD (Julien Gilli) [#18204](https://github.com/joyent/node/pull/18204) * [[`101e103e3b`](https://github.com/nodejs/node/commit/101e103e3b)] - **repl**: make 'Unexpected token' errors recoverable (Julien Gilli) [#8875](https://github.com/joyent/node/pull/8875) * [[`d5b32246fb`](https://github.com/nodejs/node/commit/d5b32246fb)] - **src**: backport ignore ENOTCONN on shutdown race (Ben Noordhuis) [#14480](https://github.com/joyent/node/pull/14480) * [[`f99eaefe75`](https://github.com/nodejs/node/commit/f99eaefe75)] - **src**: fix backport of SIGINT crash fix on FreeBSD (Julien Gilli) [#14819](https://github.com/joyent/node/pull/14819) ## 2015-05-07, Version 2.0.1, @rvagg ### Notable changes * **async_wrap**: (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - it is now possible to filter by providers - bit flags have been removed and replaced with method calls on the binding object - _note that this is an unstable API so feature additions and breaking changes won't change io.js semver_ * **libuv**: resolves numerous io.js issues: - [#862](https://github.com/nodejs/node/issues/862) prevent spawning child processes with invalid stdio file descriptors - [#1397](https://github.com/nodejs/node/issues/1397) fix EPERM error with fs.access(W_OK) on Windows - [#1621](https://github.com/nodejs/node/issues/1621) build errors associated with the bundled libuv - [#1512](https://github.com/nodejs/node/issues/1512) should properly fix Windows termination errors * **addons**: the `NODE_DEPRECATED` macro was causing problems when compiling addons with older compilers, this should now be resolved (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) * **V8**: upgrade V8 from 4.2.77.18 to 4.2.77.20 with minor fixes, including a bug preventing builds on FreeBSD ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) ### Commits * [[`7dde95a8bd`](https://github.com/nodejs/node/commit/7dde95a8bd)] - **async-wrap**: remove before/after calls in init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) * [[`bd42ba056a`](https://github.com/nodejs/node/commit/bd42ba056a)] - **async-wrap**: set flags using functions (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) * [[`4b2c786449`](https://github.com/nodejs/node/commit/4b2c786449)] - **async-wrap**: pass PROVIDER as first arg to init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) * [[`84bf609fd2`](https://github.com/nodejs/node/commit/84bf609fd2)] - **async-wrap**: don't call init callback unnecessarily (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) * [[`04cc03b029`](https://github.com/nodejs/node/commit/04cc03b029)] - **deps**: update libuv to 1.5.0 (Saúl Ibarra Corretgé) [#1646](https://github.com/nodejs/node/pull/1646) * [[`b16d9c28e8`](https://github.com/nodejs/node/commit/b16d9c28e8)] - **deps**: upgrade v8 to 4.2.77.20 (Ben Noordhuis) [#1639](https://github.com/nodejs/node/pull/1639) * [[`9ec3109272`](https://github.com/nodejs/node/commit/9ec3109272)] - **doc**: add TC meeting 2015-04-29 minutes (Rod Vagg) [#1585](https://github.com/nodejs/node/pull/1585) * [[`2c7206254c`](https://github.com/nodejs/node/commit/2c7206254c)] - **doc**: fix typo in readme.md (AQNOUCH Mohammed) [#1643](https://github.com/nodejs/node/pull/1643) * [[`71dc7152ee`](https://github.com/nodejs/node/commit/71dc7152ee)] - **doc**: fix PR link in CHANGELOG (Brian White) [#1624](https://github.com/nodejs/node/pull/1624) * [[`b97b96d05a`](https://github.com/nodejs/node/commit/b97b96d05a)] - **install**: fix NameError (thefourtheye) [#1628](https://github.com/nodejs/node/pull/1628) * [[`6ccbe75384`](https://github.com/nodejs/node/commit/6ccbe75384)] - **js_stream**: fix buffer index in DoWrite (Shigeki Ohtsu) [#1635](https://github.com/nodejs/node/pull/1635) * [[`c43855c49c`](https://github.com/nodejs/node/commit/c43855c49c)] - **src**: export the ParseEncoding function on Windows (Ivan Kozik) [#1596](https://github.com/nodejs/node/pull/1596) * [[`8315b22390`](https://github.com/nodejs/node/commit/8315b22390)] - **src**: fix pedantic cpplint whitespace warnings (Ben Noordhuis) [#1640](https://github.com/nodejs/node/pull/1640) * [[`b712af79a7`](https://github.com/nodejs/node/commit/b712af79a7)] - **src**: fix NODE_DEPRECATED macro with old compilers (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) * [[`2ed10f1349`](https://github.com/nodejs/node/commit/2ed10f1349)] - **src**: fix minor inefficiency in Buffer::New() call (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) * [[`f696c9efab`](https://github.com/nodejs/node/commit/f696c9efab)] - **src**: fix deprecated use of Buffer::New() (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) * [[`0c8f13df8f`](https://github.com/nodejs/node/commit/0c8f13df8f)] - **tools**: remove unused GuessWordSize function (thefourtheye) [#1638](https://github.com/nodejs/node/pull/1638) ## 2015-05-04, Version 2.0.0, @rvagg ### Breaking changes Full details at https://github.com/nodejs/node/wiki/Breaking-Changes#200-from-1x * V8 upgrade to 4.2, minor changes to C++ API * `os.tmpdir()` is now cross-platform consistent and no longer returns a path with a trailing slash on any platform * While not a *breaking change* the 'smalloc' module has been deprecated in anticipation of it becoming unsupportable with a future upgrade to V8 4.4. See [#1451](https://github.com/nodejs/node/issues/1451) for further information. _Note: a new version of the 'url' module was reverted prior to release as it was decided the potential for breakage across the npm ecosystem was too great and that more compatibility work needed to be done before releasing it. See [#1602](https://github.com/nodejs/node/pull/1602) for further information._ ### Notable changes * **crypto**: significantly reduced memory usage for TLS (Fedor Indutny & Сковорода Никита Андреевич) [#1529](https://github.com/nodejs/node/pull/1529) * **net**: `socket.connect()` now accepts a `'lookup'` option for a custom DNS resolution mechanism, defaults to `dns.lookup()` (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) * **npm**: Upgrade npm to 2.9.0. See the [v2.8.4](https://github.com/npm/npm/releases/tag/v2.8.4) and [v2.9.0](https://github.com/npm/npm/releases/tag/v2.9.0) release notes for details. Notable items: - Add support for default author field to make `npm init -y` work without user-input (@othiym23) [npm/npm/d8eee6cf9d](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9af) - Include local modules in `npm outdated` and `npm update` (@ArnaudRinquin) [npm/npm#7426](https://github.com/npm/npm/issues/7426) - The prefix used before the version number on `npm version` is now configurable via `tag-version-prefix` (@kkragenbrink) [npm/npm#8014](https://github.com/npm/npm/issues/8014) * **os**: `os.tmpdir()` is now cross-platform consistent and will no longer returns a path with a trailing slash on any platform (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) * **process**: - `process.nextTick()` performance has been improved by between 2-42% across the benchmark suite, notable because this is heavily used across core (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) - New `process.geteuid()`, `process.seteuid(id)`, `process.getegid()` and `process.setegid(id)` methods allow you to get and set effective UID and GID of the process (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) * **repl**: - REPL history can be persisted across sessions if the `NODE_REPL_HISTORY_FILE` environment variable is set to a user accessible file, `NODE_REPL_HISTORY_SIZE` can set the maximum history size and defaults to `1000` (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) - The REPL can be placed in to one of three modes using the `NODE_REPL_MODE` environment variable: `sloppy`, `strict` or `magic` (default); the new `magic` mode will automatically run "strict mode only" statements in strict mode (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) * **smalloc**: the 'smalloc' module has been deprecated due to changes coming in V8 4.4 that will render it unusable * **util**: add Promise, Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) * **V8**: upgrade to 4.2.77.18, see the [ChangeLog](https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.77/ChangeLog) for full details. Notable items: - Classes have moved out of staging; the `class` keyword is now usable in strict mode without flags - Object literal enhancements have moved out of staging; shorthand method and property syntax is now usable (`{ method() { }, property }`) - Rest parameters (`function(...args) {}`) are implemented in staging behind the `--harmony-rest-parameters` flag - Computed property names (`{['foo'+'bar']:'bam'}`) are implemented in staging behind the `--harmony-computed-property-names` flag - Unicode escapes (`'\u{xxxx}'`) are implemented in staging behind the `--harmony_unicode` flag and the `--harmony_unicode_regexps` flag for use in regular expressions * **Windows**: - Random process termination on Windows fixed (Fedor Indutny) [#1512](https://github.com/nodejs/node/issues/1512) / [#1563](https://github.com/nodejs/node/pull/1563) - The delay-load hook introduced to fix issues with process naming (iojs.exe / node.exe) has been made opt-out for native add-ons. Native add-ons should include `'win_delay_load_hook': 'false'` in their binding.gyp to disable this feature if they experience problems . (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) * **Governance**: - Rod Vagg (@rvagg) was added to the Technical Committee (TC) - Jeremiah Senkpiel (@Fishrock123) was added to the Technical Committee (TC) ### Known issues See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) ### Commits * [[`5404cbc745`](https://github.com/nodejs/node/commit/5404cbc745)] - **buffer**: fix copy() segfault with zero arguments (Trevor Norris) [#1520](https://github.com/nodejs/node/pull/1520) * [[`3d3083b91f`](https://github.com/nodejs/node/commit/3d3083b91f)] - **buffer**: little improve for Buffer.concat method (Jackson Tian) [#1437](https://github.com/nodejs/node/pull/1437) * [[`e67542ae17`](https://github.com/nodejs/node/commit/e67542ae17)] - **build**: disable -Og when building with clang (Ben Noordhuis) [#1609](https://github.com/nodejs/node/pull/1609) * [[`78f4b038f8`](https://github.com/nodejs/node/commit/78f4b038f8)] - **build**: turn on debug-safe optimizations with -Og (Ben Noordhuis) [#1569](https://github.com/nodejs/node/pull/1569) * [[`a5dcff827a`](https://github.com/nodejs/node/commit/a5dcff827a)] - **build**: Use option groups in configure output (Johan Bergström) [#1533](https://github.com/nodejs/node/pull/1533) * [[`2a3c8c187e`](https://github.com/nodejs/node/commit/2a3c8c187e)] - **build**: remove -J from test-ci (Rod Vagg) [#1544](https://github.com/nodejs/node/pull/1544) * [[`e6874dd0f9`](https://github.com/nodejs/node/commit/e6874dd0f9)] - **crypto**: track external memory for SSL structures (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) * [[`935c9d3fa7`](https://github.com/nodejs/node/commit/935c9d3fa7)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) * [[`56e4255382`](https://github.com/nodejs/node/commit/56e4255382)] - **deps**: upgrade npm to 2.9.0 (Forrest L Norvell) [#1573](https://github.com/nodejs/node/pull/1573) * [[`509b59ea7c`](https://github.com/nodejs/node/commit/509b59ea7c)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) * [[`01652c7709`](https://github.com/nodejs/node/commit/01652c7709)] - **deps**: upgrade v8 to 4.2.77.18 (Chris Dickinson) [#1506](https://github.com/nodejs/node/pull/1506) * [[`01e6632d70`](https://github.com/nodejs/node/commit/01e6632d70)] - **deps**: upgrade v8 to 4.2.77.15 (Ben Noordhuis) [#1399](https://github.com/nodejs/node/pull/1399) * [[`db4ded5903`](https://github.com/nodejs/node/commit/db4ded5903)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) * [[`36cd5fb9d2`](https://github.com/nodejs/node/commit/36cd5fb9d2)] - **(SEMVER-MAJOR)** **deps**: upgrade v8 to 4.2.77.13 (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) * [[`b3a7da1091`](https://github.com/nodejs/node/commit/b3a7da1091)] - **deps**: update http_parser to 2.5.0 (Fedor Indutny) [#1517](https://github.com/nodejs/node/pull/1517) * [[`ac1fb39ce8`](https://github.com/nodejs/node/commit/ac1fb39ce8)] - **doc**: add rvagg to the TC (Rod Vagg) [#1613](https://github.com/nodejs/node/pull/1613) * [[`dacc1fa35c`](https://github.com/nodejs/node/commit/dacc1fa35c)] - **doc**: update AUTHORS list (Rod Vagg) [#1586](https://github.com/nodejs/node/pull/1586) * [[`2a3a1909ab`](https://github.com/nodejs/node/commit/2a3a1909ab)] - **doc**: add require() lines to child.stdio example (Nick Raienko) [#1504](https://github.com/nodejs/node/pull/1504) * [[`02388dbf40`](https://github.com/nodejs/node/commit/02388dbf40)] - **doc**: fix some cross-references (Alexander Gromnitsky) [#1584](https://github.com/nodejs/node/pull/1584) * [[`57c4cc26e2`](https://github.com/nodejs/node/commit/57c4cc26e2)] - **doc**: add TC meeting 2015-04-22 minutes (Rod Vagg) [#1556](https://github.com/nodejs/node/pull/1556) * [[`b4ad5d7050`](https://github.com/nodejs/node/commit/b4ad5d7050)] - **doc**: improve http.request and https.request opts (Roman Reiss) [#1551](https://github.com/nodejs/node/pull/1551) * [[`7dc8eec0a6`](https://github.com/nodejs/node/commit/7dc8eec0a6)] - **doc**: deprecate smalloc module (Ben Noordhuis) [#1566](https://github.com/nodejs/node/pull/1566) * [[`1bcdf46ca7`](https://github.com/nodejs/node/commit/1bcdf46ca7)] - **doc**: add TC meeting 2015-04-15 minutes (Rod Vagg) [#1498](https://github.com/nodejs/node/pull/1498) * [[`391cae3595`](https://github.com/nodejs/node/commit/391cae3595)] - **doc**: Add Known issues to v1.7.0/1.7.1 CHANGELOG (Yosuke Furukawa) [#1473](https://github.com/nodejs/node/pull/1473) * [[`e55fdc47a7`](https://github.com/nodejs/node/commit/e55fdc47a7)] - **doc**: fix util.deprecate example (Nick Raienko) [#1535](https://github.com/nodejs/node/pull/1535) * [[`5178f93bc0`](https://github.com/nodejs/node/commit/5178f93bc0)] - **doc**: Add Addon API (NAN) to working group list (Julian Duque) [#1523](https://github.com/nodejs/node/pull/1523) * [[`f3cc50f811`](https://github.com/nodejs/node/commit/f3cc50f811)] - **doc**: add TC meeting 2015-04-08 minutes (Rod Vagg) [#1497](https://github.com/nodejs/node/pull/1497) * [[`bb254b533b`](https://github.com/nodejs/node/commit/bb254b533b)] - **doc**: update branch to master (Roman Reiss) [#1511](https://github.com/nodejs/node/pull/1511) * [[`22aafa5597`](https://github.com/nodejs/node/commit/22aafa5597)] - **doc**: add Fishrock123 to the TC (Jeremiah Senkpiel) [#1507](https://github.com/nodejs/node/pull/1507) * [[`b16a328ede`](https://github.com/nodejs/node/commit/b16a328ede)] - **doc**: add spaces to child.kill example (Nick Raienko) [#1503](https://github.com/nodejs/node/pull/1503) * [[`26327757f8`](https://github.com/nodejs/node/commit/26327757f8)] - **doc**: update AUTHORS list (Rod Vagg) [#1476](https://github.com/nodejs/node/pull/1476) * [[`f9c681cf62`](https://github.com/nodejs/node/commit/f9c681cf62)] - **fs**: validate fd on fs.write (Julian Duque) [#1553](https://github.com/nodejs/node/pull/1553) * [[`801b47acc5`](https://github.com/nodejs/node/commit/801b47acc5)] - **gitignore**: ignore xcode workspaces and projects (Roman Klauke) [#1562](https://github.com/nodejs/node/pull/1562) * [[`d5ce47e433`](https://github.com/nodejs/node/commit/d5ce47e433)] - **(SEMVER-MINOR)** **lib**: deprecate the smalloc module (Ben Noordhuis) [#1564](https://github.com/nodejs/node/pull/1564) * [[`7384ca83f9`](https://github.com/nodejs/node/commit/7384ca83f9)] - **module**: remove '' from Module.globalPaths (Chris Yip) [#1488](https://github.com/nodejs/node/pull/1488) * [[`b4f5898395`](https://github.com/nodejs/node/commit/b4f5898395)] - **net**: ensure Write/ShutdownWrap references handle (Fedor Indutny) [#1590](https://github.com/nodejs/node/pull/1590) * [[`4abe2fa1cf`](https://github.com/nodejs/node/commit/4abe2fa1cf)] - **(SEMVER-MINOR)** **net**: add lookup option to Socket.prototype.connect (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) * [[`1bef717476`](https://github.com/nodejs/node/commit/1bef717476)] - **(SEMVER-MINOR)** **net**: cleanup connect logic (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) * [[`c7782c0af8`](https://github.com/nodejs/node/commit/c7782c0af8)] - **node**: improve nextTick performance (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) * [[`b57cc51d8d`](https://github.com/nodejs/node/commit/b57cc51d8d)] - **(SEMVER-MAJOR)** **os**: remove trailing slash from os.tmpdir() (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) * [[`ca219b00d1`](https://github.com/nodejs/node/commit/ca219b00d1)] - **repl**: fix for a+ fd clearing the file on read (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) * [[`051d482b15`](https://github.com/nodejs/node/commit/051d482b15)] - **repl**: fix \_debugger by properly proxying repl (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) * [[`2e2fce0502`](https://github.com/nodejs/node/commit/2e2fce0502)] - **repl**: fix persistent history and env variable name (Roman Reiss) [#1593](https://github.com/nodejs/node/pull/1593) * [[`ea5195ccaf`](https://github.com/nodejs/node/commit/ea5195ccaf)] - **repl**: do not save history for non-terminal repl (Fedor Indutny) [#1575](https://github.com/nodejs/node/pull/1575) * [[`0450ce7db2`](https://github.com/nodejs/node/commit/0450ce7db2)] - **repl**: add mode detection, cli persistent history (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) * [[`af9fe3bbc7`](https://github.com/nodejs/node/commit/af9fe3bbc7)] - **(SEMVER-MAJOR)** **src**: bump NODE_MODULE_VERSION due to V8 API (Rod Vagg) [#1532](https://github.com/nodejs/node/pull/1532) * [[`279f6116aa`](https://github.com/nodejs/node/commit/279f6116aa)] - **src**: fix -Wmissing-field-initializers warning (Ben Noordhuis) [#1606](https://github.com/nodejs/node/pull/1606) * [[`73062521a4`](https://github.com/nodejs/node/commit/73062521a4)] - **src**: deprecate smalloc public functions (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) * [[`ccb199af17`](https://github.com/nodejs/node/commit/ccb199af17)] - **src**: fix deprecation warnings (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) * [[`609fa0de03`](https://github.com/nodejs/node/commit/609fa0de03)] - **src**: fix NODE_DEPRECATED macro (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) * [[`3c92ca2b5c`](https://github.com/nodejs/node/commit/3c92ca2b5c)] - **(SEMVER-MINOR)** **src**: add ability to get/set effective uid/gid (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) * [[`30b7349176`](https://github.com/nodejs/node/commit/30b7349176)] - **stream_base**: dispatch reqs in the stream impl (Fedor Indutny) [#1563](https://github.com/nodejs/node/pull/1563) * [[`0fa6c4a6fc`](https://github.com/nodejs/node/commit/0fa6c4a6fc)] - **string_decoder**: don't cache Buffer.isEncoding (Brian White) [#1548](https://github.com/nodejs/node/pull/1548) * [[`f9b226c1c1`](https://github.com/nodejs/node/commit/f9b226c1c1)] - **test**: extend timeouts for ARMv6 (Rod Vagg) [#1554](https://github.com/nodejs/node/pull/1554) * [[`bfae8236b1`](https://github.com/nodejs/node/commit/bfae8236b1)] - **test**: fix test-net-dns-custom-lookup test assertion (Evan Lucas) [#1531](https://github.com/nodejs/node/pull/1531) * [[`547213913b`](https://github.com/nodejs/node/commit/547213913b)] - **test**: adjust Makefile/test-ci, add to vcbuild.bat (Rod Vagg) [#1530](https://github.com/nodejs/node/pull/1530) * [[`550c2638c0`](https://github.com/nodejs/node/commit/550c2638c0)] - **tls**: use `SSL_set_cert_cb` for async SNI/OCSP (Fedor Indutny) [#1464](https://github.com/nodejs/node/pull/1464) * [[`1787416376`](https://github.com/nodejs/node/commit/1787416376)] - **tls**: destroy singleUse context immediately (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) * [[`2684c902c4`](https://github.com/nodejs/node/commit/2684c902c4)] - **tls**: zero SSL_CTX freelist for a singleUse socket (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) * [[`2d241b3b82`](https://github.com/nodejs/node/commit/2d241b3b82)] - **tls**: destroy SSL once it is out of use (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) * [[`f7620fb96d`](https://github.com/nodejs/node/commit/f7620fb96d)] - **tls_wrap**: Unlink TLSWrap and SecureContext objects (Сковорода Никита Андреевич) [#1580](https://github.com/nodejs/node/pull/1580) * [[`a7d74633f2`](https://github.com/nodejs/node/commit/a7d74633f2)] - **tls_wrap**: use localhost if options.host is empty (Guilherme Souza) [#1493](https://github.com/nodejs/node/pull/1493) * [[`702997c1f0`](https://github.com/nodejs/node/commit/702997c1f0)] - ***Revert*** "**url**: significantly improve the performance of the url module" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) * [[`0daed24883`](https://github.com/nodejs/node/commit/0daed24883)] - ***Revert*** "**url**: delete href cache on all setter code paths" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) * [[`0f39ef4ca1`](https://github.com/nodejs/node/commit/0f39ef4ca1)] - ***Revert*** "**url**: fix treatment of some values as non-empty" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) * [[`66877216bd`](https://github.com/nodejs/node/commit/66877216bd)] - **url**: fix treatment of some values as non-empty (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) * [[`dbdd81a91b`](https://github.com/nodejs/node/commit/dbdd81a91b)] - **url**: delete href cache on all setter code paths (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) * [[`3fd7fc429c`](https://github.com/nodejs/node/commit/3fd7fc429c)] - **url**: significantly improve the performance of the url module (Petka Antonov) [#1561](https://github.com/nodejs/node/pull/1561) * [[`bf7ac08dd0`](https://github.com/nodejs/node/commit/bf7ac08dd0)] - **util**: add Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) * [[`30e83d2e84`](https://github.com/nodejs/node/commit/30e83d2e84)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) * [[`3bda6cbfa4`](https://github.com/nodejs/node/commit/3bda6cbfa4)] - **(SEMVER-MAJOR)** **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) ## 2015-04-20, Version 1.8.1, @chrisdickinson ### Notable changes * **NOTICE**: Skipped v1.8.0 due to problems with release tooling. See [#1436](https://github.com/nodejs/node/issues/1436) for details. * **build**: Support for building io.js as a static library (Marat Abdullin) [#1341](https://github.com/nodejs/node/pull/1341) * **deps**: Upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * Users should see performance improvements when using the crypto API. See [here](https://github.com/nodejs/node/wiki/Crypto-Performance-Notes-for-OpenSSL-1.0.2a-on-iojs-v1.8.0) for details. * **npm**: Upgrade npm to 2.8.3. See the [release notes](https://github.com/npm/npm/releases/tag/v2.8.3) for details. Includes improved git support. Summary: * [`387f889`](https://github.com/npm/npm/commit/387f889c0e8fb617d9cc9a42ed0a3ec49424ab5d) [#7961](https://github.com/npm/npm/issues/7961) Ensure that hosted git SSH URLs always have a valid protocol when stored in `resolved` fields in `npm-shrinkwrap.json`. ([@othiym23](https://github.com/othiym23)) * [`394c2f5`](https://github.com/npm/npm/commit/394c2f5a1227232c0baf42fbba1402aafe0d6ffb) Switch the order in which hosted Git providers are checked to `git:`, `git+https:`, then `git+ssh:` (from `git:`, `git+ssh:`, then `git+https:`) in an effort to go from most to least likely to succeed, to make for less confusing error message. ([@othiym23](https://github.com/othiym23)) * [`431c3bf`](https://github.com/npm/npm/commit/431c3bf6cdec50f9f0c735f478cb2f3f337d3313) [#7699](https://github.com/npm/npm/issues/7699) `npm-registry-client@6.3.2`: Don't send body with HTTP GET requests when logging in. ([@smikes](https://github.com/smikes)) * [`15efe12`](https://github.com/npm/npm/commit/15efe124753257728a0ddc64074fa5a4b9c2eb30) [#7872](https://github.com/npm/npm/issues/7872) Use the new version of `hosted-git-info` to pass along credentials embedded in git URLs. Test it. Test it a lot. ([@othiym23](https://github.com/othiym23)) * [`b027319`](https://github.com/npm/npm/commit/b0273190c71eba14395ddfdd1d9f7ba625297523) [#7920](https://github.com/npm/npm/issues/7920) Scoped packages with `peerDependencies` were installing the `peerDependencies` into the wrong directory. ([@ewie](https://github.com/ewie)) * [`6b0f588`](https://github.com/npm/npm/commit/6b0f58877f37df9904490ffbaaad33862bd36dce) [#7867](https://github.com/npm/npm/issues/7867) Use git shorthand and git URLs as presented by user. Support new `hosted-git-info` shortcut syntax. Save shorthand in `package.json`. Try cloning via `git:`, `git+ssh:`, and `git+https:`, in that order, when supported by the underlying hosting provider. ([@othiym23](https://github.com/othiym23)) * **src**: Allow multiple arguments to be passed to process.nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) * **module**: The interaction of `require('.')` with `NODE_PATH` has been restored and deprecated. This functionality will be removed at a later point. (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) ### Commits * [[`53ed89d927`](https://github.com/nodejs/node/commit/53ed89d927)] - ***Revert*** "**build**: use %PYTHON% instead of python" (Rod Vagg) [#1475](https://github.com/nodejs/node/pull/1475) * [[`2b744b0ab7`](https://github.com/nodejs/node/commit/2b744b0ab7)] - **src**: revert NODE_MODULE_VERSION to 43 (Chris Dickinson) [#1460](https://github.com/nodejs/node/pull/1460) * [[`431673ebd1`](https://github.com/nodejs/node/commit/431673ebd1)] - **buffer**: fast-case for empty string in byteLength (Jackson Tian) [#1441](https://github.com/nodejs/node/pull/1441) * [[`1b22bad35f`](https://github.com/nodejs/node/commit/1b22bad35f)] - **build**: fix logic for shared library flags (Jeremiah Senkpiel) [#1454](https://github.com/nodejs/node/pull/1454) * [[`91943a99d5`](https://github.com/nodejs/node/commit/91943a99d5)] - **build**: use %PYTHON% instead of python (Rod Vagg) [#1444](https://github.com/nodejs/node/pull/1444) * [[`c7769d417b`](https://github.com/nodejs/node/commit/c7769d417b)] - **build**: Expose xz compression level (Johan Bergström) [#1428](https://github.com/nodejs/node/pull/1428) * [[`a530b2baf1`](https://github.com/nodejs/node/commit/a530b2baf1)] - **build**: fix error message in configure (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`92dfb794f9`](https://github.com/nodejs/node/commit/92dfb794f9)] - **build**: enable ssl support on arm64 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`7de0dcde83`](https://github.com/nodejs/node/commit/7de0dcde83)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) * [[`4870213f9e`](https://github.com/nodejs/node/commit/4870213f9e)] - **deps**: upgrade npm to 2.8.3 (Forrest L Norvell) * [[`49bb7ded2c`](https://github.com/nodejs/node/commit/49bb7ded2c)] - **deps**: fix git case sensitivity issue in npm (Chris Dickinson) [#1456](https://github.com/nodejs/node/pull/1456) * [[`4830b4bce8`](https://github.com/nodejs/node/commit/4830b4bce8)] - **deps**: add docs to upgrade openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`11bec72c87`](https://github.com/nodejs/node/commit/11bec72c87)] - **deps**: update asm files for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`53924d8ebe`](https://github.com/nodejs/node/commit/53924d8ebe)] - **deps**: update asm Makefile for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`418e839456`](https://github.com/nodejs/node/commit/418e839456)] - **deps**: update openssl.gyp/gypi for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`02f12ab666`](https://github.com/nodejs/node/commit/02f12ab666)] - **deps**: update opensslconf.h for 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`eb7a23595f`](https://github.com/nodejs/node/commit/eb7a23595f)] - **deps**: add x32 and arm64 support for opensslconf.h (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`033a663127`](https://github.com/nodejs/node/commit/033a663127)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`ae8831f240`](https://github.com/nodejs/node/commit/ae8831f240)] - **deps**: backport openssl patch of alt cert chains 1 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`71316c46d9`](https://github.com/nodejs/node/commit/71316c46d9)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`d293a4f096`](https://github.com/nodejs/node/commit/d293a4f096)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [#1389](https://github.com/nodejs/node/pull/1389) * [[`e4872d7405`](https://github.com/nodejs/node/commit/e4872d7405)] - **deps**: upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`a1c9ef3142`](https://github.com/nodejs/node/commit/a1c9ef3142)] - **deps, build**: add support older assembler (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`76f219c128`](https://github.com/nodejs/node/commit/76f219c128)] - **doc**: Document forced pushing with git (Johan Bergström) [#1420](https://github.com/nodejs/node/pull/1420) * [[`12e51d56c1`](https://github.com/nodejs/node/commit/12e51d56c1)] - **doc**: add Addon API WG (Rod Vagg) [#1226](https://github.com/nodejs/node/pull/1226) * [[`7956a13dad`](https://github.com/nodejs/node/commit/7956a13dad)] - **http**: logically respect maxSockets (fengmk2) [#1242](https://github.com/nodejs/node/pull/1242) * [[`5b844e140b`](https://github.com/nodejs/node/commit/5b844e140b)] - **module**: fix style (Roman Reiss) [#1453](https://github.com/nodejs/node/pull/1453) * [[`3ad82c335d`](https://github.com/nodejs/node/commit/3ad82c335d)] - **(SEMVER-MINOR)** **module**: handle NODE_PATH in require('.') (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) * [[`cd60ff0328`](https://github.com/nodejs/node/commit/cd60ff0328)] - **net**: add fd into listen2 debug info (Jackson Tian) [#1442](https://github.com/nodejs/node/pull/1442) * [[`10e31ba56c`](https://github.com/nodejs/node/commit/10e31ba56c)] - **(SEMVER-MINOR)** **node**: allow multiple arguments passed to nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) * [[`116c54692a`](https://github.com/nodejs/node/commit/116c54692a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`62f5f4cec9`](https://github.com/nodejs/node/commit/62f5f4cec9)] - **src**: remove duplicate byteLength from Buffer (Jackson Tian) [#1438](https://github.com/nodejs/node/pull/1438) * [[`51d0808c90`](https://github.com/nodejs/node/commit/51d0808c90)] - **stream**: remove duplicated expression (Yazhong Liu) [#1444](https://github.com/nodejs/node/pull/1444) * [[`deb9d23d7b`](https://github.com/nodejs/node/commit/deb9d23d7b)] - **test**: fix error message check for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) * [[`ca8c9ec2c8`](https://github.com/nodejs/node/commit/ca8c9ec2c8)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) ## 2015-04-14, Version 1.7.1, @rvagg ### Notable changes * **build**: A syntax error in the Makefile for release builds caused 1.7.0 to be DOA and unreleased. (Rod Vagg) [#1421](https://github.com/nodejs/node/pull/1421). ### Known issues * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) ### Commits * [[`aee86a21f2`](https://github.com/nodejs/node/commit/aee86a21f2)] - **build**: fix RELEASE check (Rod Vagg) [#1421](https://github.com/nodejs/node/pull/1421) ## 2015-04-14, Version 1.7.0, @rvagg ### Notable changes * **C++ API**: Fedor Indutny contributed a feature to V8 which has been backported to the V8 bundled in io.js. `SealHandleScope` allows a C++ add-on author to _seal_ a `HandleScope` to prevent further, unintended allocations within it. Currently only enabled for debug builds of io.js. This feature helped detect the leak in [#1075](https://github.com/nodejs/node/issues/1075) and is now activated on the root `HandleScope` in io.js. (Fedor Indutny) [#1395](https://github.com/nodejs/node/pull/1395). * **ARM**: This release includes significant work to improve the state of ARM support for builds and tests. The io.js CI cluster's ARMv6, ARMv7 and ARMv8 build servers are now all (mostly) reporting passing builds and tests. * ARMv8 64-bit (AARCH64) is now properly supported, including a backported fix in libuv that was mistakenly detecting the existence of `epoll_wait()`. (Ben Noordhuis) [#1365](https://github.com/nodejs/node/pull/1365). * ARMv6: [#1376](https://github.com/nodejs/node/issues/1376) reported a problem with `Math.exp()` on ARMv6 (incl Raspberry Pi). The culprit is erroneous codegen for ARMv6 when using the "fast math" feature of V8. `--nofast_math` has been turned on for all ARMv6 variants by default to avoid this, fast math can be turned back on with `--fast_math`. (Ben Noordhuis) [#1398](https://github.com/nodejs/node/pull/1398). * Tests: timeouts have been tuned specifically for slower platforms, detected as ARMv6 and ARMv7. (Roman Reiss) [#1366](https://github.com/nodejs/node/pull/1366). * **npm**: Upgrade npm to 2.7.6. See the [release notes](https://github.com/npm/npm/releases/tag/v2.7.6) for details. Summary: * [`b747593`](https://github.com/npm/npm/commit/b7475936f473f029e6a027ba1b16277523747d0b)[#7630](https://github.com/npm/npm/issues/7630) Don't automatically log all git failures as errors. `maybeGithub` needs to be able to fail without logging to support its fallback logic. ([@othiym23](https://github.com/othiym23)) * [`78005eb`](https://github.com/npm/npm/commit/78005ebb6f4103c20f077669c3929b7ea46a4c0d)[#7743](https://github.com/npm/npm/issues/7743) Always quote arguments passed to `npm run-script`. This allows build systems and the like to safely escape glob patterns passed as arguments to `run-scripts` with `npm run-script node-v4.2.6/doc/tsc-meetings/000755 000766 000024 00000000000 12650222326 016115 5ustar00iojsstaff000000 000000 node-v4.2.6/doc/tsc-meetings/2015-05-27.md000644 000766 000024 00000015223 12650222326 017501 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-05-27 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-05-27 * **Public YouTube feed**: http://www.youtube.com/watch?v=0DPfLxulsbQ * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/41 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1-KlxiQGMsJFNJu3meok9e9XFsM39k_PMnQmY_9d_cy0 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/node-convergence-archive * \[Converge\] timers: Avoid linear scan in `_unrefActive`. [#23](https://github.com/nodejs/node-convergence-archive/issues/23) * \[Converge\] child_process argument type checking [#22](https://github.com/nodejs/node-convergence-archive/issues/22) * \[Converge\] SSLv2/3 disable/enable related commits [#20](https://github.com/nodejs/node-convergence-archive/issues/20) * doc: Add new working groups [#15](https://github.com/nodejs/node-convergence-archive/pull/15) ### nodejs/io.js * Buffer implemented using Uint8Array [#1810](https://github.com/nodejs/io.js/issues/1810) * \[Discussion\] FFI - Giving Buffer more low-level C functionality [#1750](https://github.com/nodejs/io.js/pull/1750) * Chrome 43 released; time for V8 4.3! [#1735](https://github.com/nodejs/io.js/issues/1735) * Deprecation Policy [#1704](https://github.com/nodejs/io.js/issues/1704) * TSC needs to elect a board representative. [#1697](https://github.com/nodejs/io.js/issues/1697) * V8 4.4 to remove indexed properties via external data [#1451](https://github.com/nodejs/io.js/issues/1451) ### joyent/node ## Present * Alexis Campailla (TSC) * Ben Noordhuis (TSC) * Bert Belder (TSC) * Brian White * Chris Dickinson (TSC) * Colin Ihrig (TSC) * James M Snell (TSC) * Jeremiah Senkpiel (TSC) * Mikeal Rogers * Michael Dawson (TSC) * Mike Dolan (TSC) * Rod Vagg (TSC) * Shigeki Ohtsu * Trevor Norris (TSC) ## Quick stand-up * Rod: Working on combining the build, 3.0 * James: Working on repo convergence, triaging joyent/node issues, LTS policy drafting * Shigeki: Investigating a slow tls test and SSL mitigations for a log jam attack. * Jeremiah: Lots of little things * Colin: Libuv work for os.homedir() * Chris: Removing sys, checking breakage; fixing bug I introduced in persistent history * Bert: Looking at issues * Alexis: Working on combining the build, fixing windows issues * Trevor: Working on the new Buffer impl using Uint8Array * Michael: Traging joyent/node, spun up the benchmarking WG, looking into adding powerpc build machines * Brian: Almost done the pure JS dns resolver, all tests are passing * Ben: - Make require faster - Date.now() perf improvements ## Review of last meeting * _Skipping_ ## Minutes ### \[Converge\] timers: Avoid linear scan in `_unrefActive`. [#23](https://github.com/nodejs/node-convergence-archive/issues/23) * James: conflicting approaches in both repos * Ben: both are terrible under different workloads - do away with the code and start again * Jeremiah: might have a go at it, working off an existing heap impl by Ben (ACTION) * Bert: some problems with http - discussion happened about the implementation * Chris: would be good to have Julien’s input since he was active on the joyent/node impl ### \[Converge\] child_process argument type checking [#22](https://github.com/nodejs/node-convergence-archive/issues/22) * James: arg checking merged in 0.10 after the fork * Discussion about why this wasn’t merged to io.js * Defer back to GitHub discussion after no reason for not merging could be found on the call ### \[Converge\] SSLv2/3 disable/enable related commits [#20](https://github.com/nodejs/node-convergence-archive/issues/20) * James: SSLv2/3 removed in io.js, merging these commits would involve reverting * Jeremiah proposed 0.12 being the LTS for SSLv2/3 support * Rod: are we happy killing this off? * Michael: we don’t know how extensively it’s being used? * James: pending research into that question we’ll leave this alone, come back if there’s a compelling reason to revert ### doc: Add new working groups [#15](https://github.com/nodejs/node-convergence-archive/pull/15) * Michael: Benchmarking and Post Mortem Debugging working groups are ready and have started, i18n group needs a bit more work to get off the ground * Group didn’t see any reason not to go forward with these groups, they have repos and can be in an “incubating” state for now ### Buffer implemented using Uint8Array [#1810](https://github.com/nodejs/io.js/issues/1810) * Trevor: Buffer using Uint8Array is now working, all applicable tests pass, currently behind a flag: * Trevor Questions: - Are we going with v8 4.3 or 4.4? - If we go v8 4.3, do we want to release behind a flag? - we still want an upper kMaxlength Buffer size limit? * Ben: Buffer size limit should be safe to remove * Rod: 4.3 and 4.4 both contain major breakage for native addons * Discussed if we would like to delay 3.0 until v8 4.4 * Rod: no appetite here for delaying a 3.0 with 4.3, take discussion on that back to GitHub * Ben: suggested we release new Buffer impl with a flag to revert to old impl, Jeremiah seconded * Discussed how hard it would be to land and review * Fedor: how does it work with 32bit numbers? * Trevor: It acts the same as before ### \[Discussion\] FFI - Giving Buffer more low-level C functionality [#1750](https://github.com/nodejs/io.js/pull/1750) * Trevor: concerns about being able to write to buffers and execute arbitrary code * Rod: concerned about changing the nature of what Node _is_ and the safety it exposes * Ben suggested that we move this new work to an ffi module rather than hanging it off Buffer - Group agreed to take this suggestion back to the issue for discussion ### Chrome 43 released; time for V8 4.3! [#1735](https://github.com/nodejs/io.js/issues/1735) * Concerns about deps forcing semver-major, the C++ API changes are big enough to warrant this though ### Deprecation Policy [#1704](https://github.com/nodejs/io.js/issues/1704) * Discussion dividing into two camps - conservative camp and those who want to test the size of the impact on the ecosystem * Suggestion (Michael?) that we use LTS releases to determine when things get properly removed * Discussed why we want a deprecation policy ### TSC needs to elect a board representative. [#1697](https://github.com/nodejs/io.js/issues/1697) * Deferred till next meeting - need to nominate and vote someone in to this role and should discuss how we want to structure the role in terms of rotation ### V8 4.4 to remove indexed properties via external data [#1451](https://github.com/nodejs/io.js/issues/1451) * Nothing to discuss, rolled up in to Buffer discussion earlier ## Next meeting * June 3rd, 8PM UTC node-v4.2.6/doc/tsc-meetings/2015-06-03.md000644 000766 000024 00000017626 12650222326 017505 0ustar00iojsstaff000000 000000 # Node.js Foundation TSC Meeting 2015-06-03 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-06-03 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/47 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1sTD0uryasBR15UBzEbJj3oHYtnuN9ZIqVxA2A_-N56E ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Add working group state per Project Lifecycle. [#1880](https://github.com/nodejs/io.js/pull/1880) * Proposal: Split TSC agenda in to two meetings [#1879](https://github.com/nodejs/io.js/issues/1879) * Chrome 43 released; time for V8 4.3! [#1735](https://github.com/nodejs/io.js/issues/1735) * TSC needs to elect a board representative. [#1697](https://github.com/nodejs/io.js/issues/1697) * Expose `deepEqual` and `deepStrictEqual` in `util`. #1172 [#1177](https://github.com/nodejs/io.js/pull/1177) ## Present * Rod Vagg (TSC) * Mikeal Rogers * Shigeki Ohtsu (TSC) * Chris Dickinson (TSC) * Colin Ihrig (TSC) * Julien Gilli (TSC) * James Snell (TSC) * Michael Dawson (TSC) * Bert Belder (TSC) * Fedor Indutny (TSC) * Jeremiah Senkpiel (TSC) * Domenic Denicola * Alexis Campailla (TSC) * Ben Noordhuis (TSC) ## Quick stand-up * Rod: working on the build, looking into npm smoke-testing * Mikeal: getting foundation legalities and officialities in order * Shigeki: working on security issues, reviewing root cert update * Chris: working on getting npm static analysis working [estoc](https://github.com/chrisdickinson/estoc) * Colin: reviewing prs and issues, doing some libuv work (uv_os_homedir, which landed in libuv 1.6.0) * Julien: vacation, nodejs.org downtime postmortem * James: working on convergence, triaging joyent/node issues * Michael: triaging some joyent/node issues, working on powerpc build and npm testing * Bert: not much, looked at some issues, discussing with Saul if libuv should move into the Node Foundation * Fedor: reviewed some pull requests and issues, working on some openssl mode * Jeremiah: issues, convergence, `_unrefActive` timers work, looking at improving Ben’s binary heap implementation * Domenic: vm fixes in v8 integrating patches * Alexis: patch for timers firing early, CI convergence work - jenkins hackery * Ben: reviewing pull requests, making libuv threadpool more scalable * Brian: JS dns resolver * Trevor: merged UInt8Array Buffer changes into the next branch, additional ArrayBuffer-related changes and fiddling ## Review of last meeting ### nodejs/node * \[Converge\] timers: Avoid linear scan in `_unrefActive`. [#23](https://github.com/nodejs/node/issues/23) * \[Converge\] child_process argument type checking [#22](https://github.com/nodejs/node/issues/22) * \[Converge\] SSLv2/3 disable/enable related commits [#20](https://github.com/nodejs/node/issues/20) * doc: Add new working groups [#15](https://github.com/nodejs/node/pull/15) ### nodejs/io.js * Buffer implemented using Uint8Array [#1810](https://github.com/nodejs/io.js/issues/1810) * \[Discussion\] FFI - Giving Buffer more low-level C functionality [#1750](https://github.com/nodejs/io.js/pull/1750) * Chrome 43 released; time for V8 4.3! [#1735](https://github.com/nodejs/io.js/issues/1735) * Deprecation Policy [#1704](https://github.com/nodejs/io.js/issues/1704) * TSC needs to elect a board representative. [#1697](https://github.com/nodejs/io.js/issues/1697) * V8 4.4 to remove indexed properties via external data [#1451](https://github.com/nodejs/io.js/issues/1451) ## Minutes ### Add working group state per Project Lifecycle. [#1880](https://github.com/nodejs/io.js/pull/1880) * Mikeal: making working groups as “core” means they get to elect a TSC seat. * Brief discussion about what WG’s should be considered “core” and get a TSC seat. * Deferred to GitHub. ### Chrome 43 released; time for V8 4.3! [#1735](https://github.com/nodejs/io.js/issues/1735) Domenic: things are ready to go. There’s some concern about double-breakage in 4.3 and 4.4. Jeremiah: what about the maybe changes? Domenic: the non-Maybe versions are still there, and haven’t been removed yet, either in 4.3 or 4.4 or even 4.5 (which isn’t finalized yet though). Rod: blocker is whether the double-breakage is real, if not then we should move forward. Domenic: there’s also the issue of some people in the thread advocating blocking a release on readying the ecosystem. Rod: we shouldn’t be following the ecosystem and waiting for them to catch up before we release. Mikeal: it’s more a matter of how we approach these things. Michael: LTS should help this? Mikeal: the problem is about major releases and the messaging - currently when people download them lots of stuff is broken. Domenic called for a vote on a 3.0 release _assuming there is no double-breakage_. Rod: I need to get the fix for node-gyp in place. Also we should see if we can get nvm to allow testing nightlies so that people can test them more easily (including on Travis). Jeremiah: when I last talked to Jordan (@ljharb) he wanted to make sure that the mechanism we used for nightlies would also be the mechanism used in the converged project. Mikeal: well that’s definitely true. So we should be good. Trevor: do we have a way of measuring uptake? Domenic/Rod: npm traffic is probably the best metric. Rod calls for a vote. Domenic: can we clarify whether we allow minor, covered-by-nan breakages between 4.3/3.0.0 and 4.4/4.0.0, or do we require no breakages at all? Mikeal: is nan released? Jeremiah: not yet; it is experimental and they don’t release until we merge next into master Mikeal: that seems bad (General agreement that we want nan to release first.) Trevor: looking at nan they seem to be working to encapsulate changes all the way out to V8 4.6. Bert: what was the problem with putting nan into core? Rod/Ben: sometimes V8 makes big changes that cause breaking changes in nan. E.g. isolates, buffer changes, maybes. Until now it’s been just individual APIs, but the 4.3 and 4.4 change has been very big. nan’s promise is just that you can write against a single, possibly-changing API that will support multiple node versions. ### Expose `deepEqual` and `deepStrictEqual` in `util`. #1172 [#1177](https://github.com/nodejs/io.js/pull/1177) Jeremiah: what do we want to expose from core, there’s pressure from some parts of the community for core to be more isomorphic and support a lot of browser stuff. This issue is specifically about exposing what’s already implemented. Ben: why not pull it out of core and put it in npm? util has always been about utilities that core uses. Rod: when you expose something you’re stuck with it forever, minimising surface area should be our goal because the more we have to officially support the slower our release cycle will be. ### Proposal: Split TSC agenda in to two meetings [#1879](https://github.com/nodejs/io.js/issues/1879) Mikeal: the scope of the TSC responsibilities are too wide, making meeting times go to long. The suggestion is to split up in to “project” related issues and “core” related issues. Rod: can there be a clear distinction between the issues? Domenic: assuming nobody wanted to attend two meetings, would there be enough? Mikeal: yes because there are lots of people that aren’t here who would be in the other group Rod: I wonder about the timing, e.g. letting the foundation kickoff happen first; it feels a bit premature to split now. Mikeal: it’s a little premature but that’s because we haven’t onboarded the core working groups to this meeting. Bert: in favour of the proposal. _Discussed the pros and cons and agreed to tentatively move forward with experimentation, time slot for the new “project” meeting would either be after the current meeting or the day after that meeting._ ### TSC needs to elect a board representative. [#1697](https://github.com/nodejs/io.js/issues/1697) ***Call ended prematurely due to Uberconference difficulties*** ## Next meeting * node-v4.2.6/doc/tsc-meetings/2015-06-10.md000644 000766 000024 00000027501 12650222326 017474 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-06-10 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-06-10 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/53 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1cn7SKaKYUMYLBiQhE6HAAknnwPabKsYjpOuyQkVikW8 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Add working group state per Project Lifecycle. #1880 * Chrome 43 released; time for V8 4.3! #1735 * TSC needs to elect a board representative. #1697 ### joyent/node * Nominating new collaborators to this repository #25481 * Node should not automatically change rlimits #8704 * Re-purpose previous joyent/node TSC meeting as LTS working group * Releases for logjam - expect new openssl version soon (possibly should be discussed in LTS working group instead) ## Minutes ### Present * Shigeki Ohtsu (TSC) * Colin Ihrig (TSC) * Alexis Campailla (TSC) * Bert Belder (TSC) * Ben Noordhuis (TSC) * Julien Gilli (TSC) * Mikeal Rogers * Michael Dawson (TSC) * Domenic Denicola * Brian White (TSC) * Bradley Meck * Trevor Norris (TSC) ### Quick review of the previous meeting * **Bert**: Discussed adding WG for project life cycle. Don’t remember what the idea was. * **Mikeal**: Need to merge the associated PR. * **Bert**: Discussed upgrading V8 to 4.3. Some contention, much in favor of doing it. Issue is V8 is changing API in 4.3 and 4.4 again. * **Trevor**: Biggest issue is nan 2.0 hadn’t come out yet. There would be a gap in time when no native module would work. * **Bert**: Resolution was that we would try to get nan to update asap. If 4.4 wasn’t done yet we would not upgrade to 4.3 yet. * **Bert**: Mikeal had proposed to split meeting in two different meetings: one technical, one non technical. ### Standup * **Shigeki**: preparing for the next OpenSSL update. * **Michael**: working on triaging issues, made sure V8 beta/stable build properly on PPC. Internally setup some build to build io.js next on PPC, so that we can hook up build machines asap. * **Colin**: mostly just reviewed PRs and triaged issues. * **Brian**: mostly triaging issues, looked at some PRs. * **Julien**: triaged issues, reviewed PRs. Started documenting Node.js’ release process and CI platform. Also started to document breaking changes between v0.12 and the converged repo between io.js and Node.js. * **Alexis**: investigations on native addon WG. * **Bert**: not a lot of technical work. Working on libuv changes to make the multi isolate/workers stuff work. PR #396 in libuv. * **Ben**: reviewed PRs. * **Domenic**: some reviews and tried to gear up for 3.0. * **Trevor**: Lot of reviewing and landing of PRs, prototype for lower-level JS API. Worked on async listeners API. * **Bradley**: here for rlimits discussion on the agenda. * **Mikeal**: launch of the foundation, getting the PR ready and working on nodeconf that starts tomorrow. ### Today’s agenda #### Add working group state per Project Lifecycle * **Mikeal**: pretty much resolved, we just need to close the PR. #### Chrome 43 released; time for V8 4.3 * **Domenic**: not sure if there’s much progress on that. Haven’t seen news from nan. * **Bert**: remove tsc-agenda, someone should put back the tag when there’s news. #### TSC needs to elect a board representative. * **Mikeal**: thought that we had a resolution, and Bert and Rod would both be on the board for a short time. * **Bert**: see if that can stay that way in the long term. Any objection? * **Michael**: have we approached other people from the foundation to see if that’s possible? * **Bert**: haven’t reached out yet. Who is organizing these meetings? * **Mikeal**: Mike Dolan. * **Bert**: Will send an email to see if that’s feasible. * **Michael**: what about voting? * **Mikeal**: we would need to put down just one person who has voting rights. * **Michael**: having two present in meetings, only one who has the vote is fine by me. * **Bert**: I don’t expect to be any kind of contention, trademark is probably the only one I can think of now. * **Mikeal**: It seems that people don’t have a good idea of what will be decided during these meetings, so maybe we can just flip a coin for this short period of time, and then when we know more of what’s discussed in these meetings we can have a vote. * **Michael**: maybe have some sort of alternance between two people in the beginning? * **Bert**: I think it would still be good to have one person who will always be there. * **Bert**: proposed resolution: let’s both (Rod and I) be there and then we’ll reevaluate later. #### Nominating new collaborators to this repository See https://github.com/joyent/node/issues/25481. Main question was: should we add nominated collaborators who are not io.js collaborators too the “collaborators” team in the nodejs organization too? Decision was that it might be confusing at first, so onboarding of these collaborators will be done first in joyent/node only, but they will conceptually be Node.js collaborators (as in collaborators in the nodejs GitHub organization). Shortly after they will be added as io.js collaborators by people familiar with the onboarding process at io.js. #### Node should not automatically change rlimits * **Bradley**: summary is in node v0.10. Node respected soft ulimit for fds. Soft limit is recommended limit, second one called hard limit which is an enforced limit. By default, OSX has a very low soft limit, and that’s the reason why this patch landed. However when running programs, they usually don’t change rlimits, and we started seeing failures after the patch landed. Argument for the side for keeping the patch, you don’t hear people complaining about being out of file descriptors. * **Michael**: did patch change only for OSX? * **Bradley**: did for all platforms. Hard limit becomes soft, soft limit are erased. * **Michael**: fix means you don’t see errors? * **Bradley**: yes, but it has undesirable side effects. Traditionally when you limit resources, you set soft limits to what you want your process to be able to get. Node started to ignore those, so we started seeing things like fds leaks not being caught, etc. * **Ben**: why wouldn’t you set the hard limit to the soft limit? * **Bradley**: This patch completely erases your soft limit, can’t recover it. No option to use soft limits at this point. Cluster would want very high limit, workers would want lower limit. Using soft limit is usually how people do that. You can use hard limits, but once you do that you’re talking about absolute enforcement. * **Bert**: proposal is to revert the patch? * **Bradley**: couple options. Ideal option to me is to revert the patch. I would expect UNIX programs to leave my settings alone. I would at least expect an option to recover the soft limits. Having some way to pass settings via command line maybe? * **Bradley**: either command line flag or environment variable. Problem with command line anything that spawns with something like fork would ignore it. * **Bert**: actually happy that the patch landed. Just works solution seems better, I’ve seen so many problems in production. Two concerns: agree this is a bit weird that node changes limits of child processes. Would not be opposed to use an environment variable. * **Bradley**: argument will come from sysadmins, not people not familiar with EMFILE and rlimits. Usually you see the EMFILE error, you request to someone to bump this limit and the problem is solved. * **Trevor**: what if we added process.resetRlimits and when that process spawns it resets rlimits. * **Bradley**: need to pass that to child processes still. * **Trevor**: if using cluster, then that seems easy. * **Bert**: Don’t like having globals for that kind of stuff, related to multi isolates. Maybe add as an option to child_process.spawn? * **Trevor**: how would that help regarding multi isolates environments? * **Bert**: Yeah, not suggesting to be able to set different limits per isolate. Ben any opinion? * **Ben**: Resetting rlimits when we spawn new process would be fine. Don’t care about environment variable that would make node not touch rlimits. * **Domenic**: Does node change system wide rlimits? * **Bradley**: that depends on how the node process lifecycle. * **Domenic**: Is there any way to ignore rlimits while not changing system wide rlimits? * **Bradley**: it’s a per process setting. Want a way to keep limits to get warnings about file descriptors, and a way to recover limits in child processes. I can write a patch for that. * **Ben**: Keep in mind you’ll probably need to update libuv in some way. Forking takes places in libuv. * **Bert**: summary: node will restore rlimits on spawn.Other thing would be command line switch or environment variable. * **Ben**: How are you going to use that? Are you using sandbox? * **Bradley**: Not using sandbox. When I see EMFILE, I can set a warning that notifies me when things go crazy. ##### Resolution * The current (rlimit-changing) behavior will be maintained. * Node/libuv should restore the ulimit for the child processes it spawns. * Support for leaving the ulimit untouched by setting an an environment variable will be added. * Bradley Meck is going to create patches to node and libuv for this. #### New OpenSSL version about to be released, with fixed for logjam * **Michael**: will need a v0.10 and v0.12 release when OpenSSL release comes out. #### Repurpose previous node.js TSC meeting as LTS WG meeting * **Julien**: timing might not work for anyone. * **Bert**: Rod pinged a bunch of people, haven’t seen a lot of response. Wyatt Preul is involved, you will probably want to reach out to him, Same for ofrobots. * **Michael**: want to make sure that everyone is ok with merging LTS meeting with joyent/node TSC meeting. * **Julien**: discussion ongoing here: https://github.com/nodejs/LTS/issues/6#issuecomment-109352447. ### Discussion items not on the agenda #### 3.0 upgrade documentation * **Trevor**: haven’t seen any doc on how to upgrade to 3.0. Should be put notes about breaking changes there, or somewhere else? * **Domenic**: hard part is C++ side changes. Everything else should be handled by semver-major/minor labels. ### Rebasing on top of the 'next' branch (not on the agenda) * **Trevor**: rebase of next on master is going to be fairly broken. Is there somebody who usually takes those merges? * **Ben**: Not sure I understood. * **Trevor**: Lots of fixes that went into 2.x will not merge cleanly in next. Some of the fixes are minor. Fix in zlib that uses kMaxLength. * **Ben**: what’s the question? * **Trevor**: wondering who’s responsible for the merge? Maybe I can help with that? * **Ben**: most of the time I do that. I usually create a PR and ask people to give a quick sign off on it. ##### Action items * Trevor will document C++ side changes. #### Workers (multi-isolate) PR * **Bert**: decided to take a look at the multi isolates patch. I know that Ben tried to review it and went half-way through. * **Trevor**: tried twice now and haven’t managed to go all the way through. * **Bert**: proposed solution is to just make sure it doesn’t break anything major, put it behind a flag and review it in more details later. * **Trevor**: a lot of stylistic issues, and haven’t got any response. * **Ben**: petka mentioned he’s quite busy at the moment. Maybe someone could address these comments? * **Bert**: ping petka, maybe we can land it in small increments. Do we want it to be perfect before it lands? * **Ben**: not comfortable landing code that hasn’t been reviewed. * **Trevor**: nice thing is that there’s a lot of tests. Didn’t see anything invasive that would make things difficult later. One change that I don’t understand 100%. I would depend on someone else to give the OK. * **Bert**: interesting and valuable change, it needs work to get landed. ## Next meeting Will be held on June 17th, 1pm PST. node-v4.2.6/doc/tsc-meetings/2015-06-17.md000644 000766 000024 00000020102 12650222326 017471 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-06-17 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-06-17 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/56 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1d4mAJgm06rpPWLDqhZcxsRnKMrS92Ip4CW2akOyeIL4 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/node * Create a security team [#48](https://github.com/nodejs/node-convergence-archive/issues/48) ### nodejs/io.js * Nominating Shigeki Ohtsu @shigeki to the TC [#1501](https://github.com/nodejs/io.js/issues/1501) * Nominating Brian White @mscdex to the TC [#1500](https://github.com/nodejs/io.js/issues/1500) * on working with proposals from the API WG [#1993](https://github.com/nodejs/io.js/issues/1993) * zlib: prevent uncaught exception in zlibBuffer [#1993](https://github.com/nodejs/io.js/issues/1811) * Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) ### joyent/node * Nominating new collaborators to this repository [#25481](https://github.com/joyent/node/issues/25481) ## Minutes ### Present * Rod Vagg (TSC) * Colin Ihrig (TSC) * Chris Dickinson (TSC) * Michael Dawson (TSC) * Mikeal Rogers * Steven R. Loomis (TSC) * Bert Belder (TSC) * Alexis Campailla (TSC) * Julien Gilli (TSC) * Shigeki Ohtsu * Jeremiah Senkpiel (TSC) * Brian White * Trevor Norris (TSC) * Domenic Denicola * Fedor Indutny (TSC) ### Review of the previous meeting * Add working group state per Project Lifecycle * Chrome 43 released; time for V8 4.3 * TSC needs to elect a board representative. * Nominating new collaborators to this repository * Node should not automatically change rlimits * New OpenSSL version about to be released, with fixed for logjam * Repurpose previous node.js TSC meeting as LTS WG meeting * 3.0 upgrade documentation * Rebasing on top of the 'next' branch (not on the agenda) * Workers PR from Petka ### Standup: * Rod: build, productive work on improving the ci and build convergence, ci now does linting before running the tests, also improving the io.js make file so that less logic for releases is contained in jenkins * Colin: reviewing issues and pr’s, landed a cluster patch to not use --debug_port on cluster workers by default * Chris: NodeConf, got great feedback there. PR for code coverage incoming soon, spun up the docs WG. * http://neversaw.us/scratch/node-coverage/ – code coverage * https://github.com/nodejs/docs * Michael: Reviewing OpenSSL changes for LogJam; PPC LE & BE work nearly complete, some OpenSSL blockers (EC related)--working towards including PPC in CI * Mikeal: running NodeConf and writing up feedback & foundation work * Steven: getting back on board * Bert: libuv work for multi-worker on Windows (https://github.com/libuv/libuv/pull/396), found a potential libuv/Windows contributor at NodeConf, NF board meeting * Alexis: Working on build & CI convergence with Rod, CI can now automatically decide what options to use for different node versions, and porting node-accept-pull-request CI job. * Julien: time off, launching nodejs.org updates for NF launch, working on changes for 0.10/0.12 releases, onboarded two new collaborators for joyent/node - https://github.com/nodejs/LTS/wiki/Breaking-changes-between-v0.12-and-next-LTS-release * Shigeki: Working on upgrading OpenSSL, the upgrade process is becoming much simpler, landed the CINNIC whitelist * Jeremiah: NodeConf - brought back good feedback, helping spin up the Diversity WG, integrating timers heap impl, struggling with bugs * Brian: not much, triage & PR review * Trevor: reviewing, commenting, merging, PR to next branch allowing passing ArrayBuffers to Buffers constructor * Domenic: reviewing, some work with Trevor, discussing release procedure * Fedor: Reviewing issues(?), working on http/2 in node-spdy ### Nominating Shigeki Ohtsu @shigeki to the TC [#1501](https://github.com/nodejs/io.js/issues/1501) ### Nominating Brian White @mscdex to the TC [#1500](https://github.com/nodejs/io.js/issues/1500) Called for a vote, got +1's for both candidates from each of: Chris, Rod, Bert, Colin, Trevor, Jeremiah, Julien, Michael, Alexis ### on working with proposals from the API WG [#1993](https://github.com/nodejs/io.js/issues/1993) * Trevor: started discussions back in advisory board before io.js existed, large companies wanted “official Node.js compatibility” at both module and JS layer. Some dissenting voices in Joyent that prevented things proceeding. After io.js happened the formal discussion ended but informal discussion continued, e.g. in https://github.com/nodejs/nan/issues/349, aim at the C++ level is to reduce API turn-over. Companies involved have their own VMs and want to maintain them for their own purposes (e.g. Chakra, JVM). * Trevor: interested in starting a WG or piggy-backing Addon API WG. * Domenic: would like more clarity on what this thing could be, is it libuv.js? is it a VM abstraction layer? * Bert: would be good to scope this work * Trevor: there’s one interest group--concerned with binary addons and not having to ship new versions with each new Node release. Another interest group is concerned with something akin to a process.bindings abstraction layer so you could put the Node JS layer on top of whatever runtime chosen. * Bert: standardising the process.bindings API might be easiest but standardising the C++ API has more beneifits because it solves the v8-upgrade-breaks-addons problem. * Rod: https://github.com/nodejs/nan/issues/373 is an issue in NAN for organising a meeting for the various groups interested in exploring C++ API compatibility, specifically for addons. ### zlib: prevent uncaught exception in zlibBuffer [#1811](https://github.com/nodejs/io.js/issues/1811) * Trevor: Issue #1811 is potentially CVE-worthy, it’s been fixed but what is the process for going forward with a CVE if necessary? * Rod: security@nodejs.org has an expanded team and security@iojs.org redirects there as well. That team should be delegated to for discussion--if you have concerns then email them and let them be responsible for deciding how to proceed. * ACTION: Trevor to email summary of potential security concern to security@nodejs.org for further discussion amongst that group. Potentially also backporting to 0.10 and 0.12. ### Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) * Mikeal: - next branch to be released on a more regular timeline need to message to users that are on the “next” branch that there is a tradeoff between new V8 (features + perf) and being able to use native modules - bring next to current, current to LTS * Domenic: - core of the proposal: - pseudo-LTS - maintain V8 version for ourselves - don’t backport any breaking changes from master, only features and patches - release this with name that implies “use this to work with native modules and features” ???? (CD - lost track here) - active dev happens here * Trevor: Naming is confusing; why isn’t it sufficient to say “this release is LTS”? * Mikeal: We don’t want LTS to mean “this is stable”, we want it to mean “I can use this for five years” * Trevor: But that’s the same thing, isn’t it? * Rod: Using the term LTS is counterproductive (leave it to the LTS working group) – it distracts * Trevor: one year span before [V8] is merged – that sounds like LTS * Domenic: This is a new release channel/train * Mikeal: We need “stable for a year” / “new features in V8, no native modules” / “stable for five years” we stick with semver (CD: Mikeal could you fill this out further?) * Domenic: We don’t need to move away from semver for the next branch Yearly releases pick a version that aligns * Mikeal: don’t call it canary, get a codename – increment one, two, three or five over a year – when we merge into master we choose a new name * CD: Could not capture entirety of discussion – moved a bit fast for me. * Bert: there is no ideal answer here. Would like mikeal and domenic to continue discussion and come back with something to vote on. ## Next meeting Next week, 2015-06-24 node-v4.2.6/doc/tsc-meetings/2015-07-01.md000644 000766 000024 00000011663 12650222326 017477 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-07-01 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-07-01 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/60 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1TN3Ks0fC4ciY3jeS0VxXxXRkT_dq8-tfs-bWQqZGRoE ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Policy for PR blocking? [#2078](https://github.com/nodejs/io.js/issues/2078) * International WG * lts: strawman LTS cycle [lts#13](https://github.com/nodejs/LTS/pull/13) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) ## Minutes ### Present * James Snell (TSC) * Bert Belder (TSC) * Steven Loomis (TSC) * Chris Dickinson (TSC) * Mikeal Rogers * Trevor Norris (TSC) * Brian White (TSC) * Jeremiah Senkpiel (TSC) ### Review of the previous meeting * discussion of stability for internal APIs [#2030](https://github.com/nodejs/io.js/issues/2030) * Nominating new collaborators to this repository [#25481](https://github.com/joyent/node/issues/25481) * Use something that’s not uberconference ? ### Standup: * James: continued triaging of joyent/node issues, working on the LTS strawman proposal * Bert: not much on node, some minor libuv and installer stuff * Steven: Intl WG work * Chris: Not too much on node, working on docs tooling * Mikeal: working on a conferencing solution / replacement * Trevor: webassembly discussion, api wg * Brian: not much, triaging io.js issues and PRs * Jeremiah: reviewing PRs and issues, more work on `_unrefActive()` * Rod: busy week, worked on the build & release procedures. New jenkins job for all the types of release builds. v3.0.0 is now blocked on NAN. It’s a very big job. Node-gyp in `next` now works for rc’s and nightlies, and downloads a tarball of just the headers. First LTS WG meeting was also productive. ### Policy for PR blocking? [#2078](https://github.com/nodejs/io.js/issues/2078) * Steven Belanger tagged this issue: can we come up with a policy for dealing with PRs that block each other? * James clarified that this specific issue was about the url parsing changes, there were a couple of PRs that blocked each other * Chris: the PRs here are a “hot stove” situation where they all break url functionality so they are not trivial * Chris listed some of the blocking issues that are mainly held up because people are too busy so we probably need a way to communicate status to the community * James: would like to table this issue until it really becomes a problem * Bert: we could introduce some workflows - e.g. if you introduce an issue that is blocked on something else then you could mention that it’s blocked * Jeremiah: more relevant to communicate when things are in the pipeline and provide feedback for timelines so people are reasonably blocked but can be unblocked if there is no activity * Rod: doesn’t feel like something that needs a policy, perhaps it’s an open source 101 skill * Mikeal: the problem is that often people who are blocking each other don’t have context so need shepherding by someone with context. * Rod: doesn’t seem like there’s actionable items here, come back when there’s something more concrete to discuss * Bert: the workers PR has stalled because of Petka’s lack of time, anything that it’s blocking should just move forward, url changes are unlikely to get in as they are now because they are so _breaking_ ### Internationalization WG (Steven) * https://github.com/nodejs/internationalization (repo) * https://github.com/nodejs/internationalization/issues/4 (README) * https://github.com/nodejs/internationalization/issues/5 (CFP) * Steven introduced the work towards getting this set up * Steven clarified the scope of the work (this is done in the README), it’s different to outreach and user assistance (i.e. the i18n translation stuff that io.js already has). * Jeremiah suggested we name the group after `Intl` so it’s clearer what it’s about. * James: It’s about Intl stuff in the code, unicode, REPL dying because of bad unicode * Mikeal: We’ve talked about starting a formal translation/language group that unifies all of the independent translation efforts. That’s probably why people are showing up for this group thinking it’s the translation group that we’ve talked about setting up. We should set up that separate group and maybe use `Intl` as the name for this separate group. * Bikeshedded naming for a little while. * Conclusion: rename as the Intl WG or similar for clarity. (renamed to Intl) ### lts: strawman LTS cycle [lts#13](https://github.com/nodejs/LTS/pull/13) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) * James walked through the LTS strawman proposal as formulated by the LTS WG * Lots of bikeshedding about releases and LTS trivia * Mikeal: we can probably move the release discussion to a formal proposal ### Next Meeting July 8th 2015 node-v4.2.6/doc/tsc-meetings/2015-07-08.md000644 000766 000024 00000020110 12650222326 017471 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-07-08 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-07-08 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/64 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1HuRtu5ZP7ZlrIp756EbZYo4I26v2RY-7CY1pr_3y1nY ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Default Unhandled Rejection Detection Behavior [#830](https://github.com/nodejs/io.js/issues/830) ### joyent/node * Adding a "mentor-available" label [#25618](https://github.com/joyent/node/issues/25618) ## Minutes ### Present * Mikeal Rogers * Colin Ihrig (TSC) * Ben Noordhuis (TSC) * James Snell (TSC) * Fedor Indutny (TSC) * Bert Belder (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Alexis Campailla (TSC) * Jeremiah Senkpiel (TSC) * Julien Gilli (TSC) * Chris Dickinson (TSC) * Shigeki Ohtsu (TSC) * Trevor Norris (TSC) * Domenic Denicola * Brian White (TSC) * Rod Vagg (TSC) ### Review of the previous meeting * Policy for PR blocking? [#2078](https://github.com/nodejs/io.js/issues/2078) - Resolution was to deal with it on a case-by-case basis for now. * Internationalization WG (Steven) - Steven Loomis is going to kick off the working group. - Steven: no further responses on the github issue. - James: just need to get started * lts: strawman LTS cycle [lts#13](https://github.com/nodejs/LTS/pull/13) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) ### Standup: * Mikeal Rogers: wrote a new confrence call tool for us that uses Twillio * Colin Ihrig: Not much, reviewing PRs, triaging issues. * Ben Noordhuis: reviewed a lot of PRs, upgraded v8 in `next` and `next+1`. * James Snell: Working on the LTS Proposal, triaging issues in joyent/node, investigating stuff for the upcoming openssl fix. * Fedor Indutny: fixed node after v8 upgrade. Exposed critical issues. * Bert Belder: Not much code, had conversations with Mike Dolan and James Snell about the foundation and organizational issues. Working through a laundry list of libuv PRs blocking the next release. * Michael Dawson: Working on getting PowerPC to build on io.js, tested the security fix from last week, joyent/node triage. * Steven R Loomis: Worked a bit on the Intl WG, not much else. * Alexis Campailla: converged CI, almost done. Dealing with windows installer issues. Expect converged CI to work in a week. * Jeremiah Senkpiel: General triaging and reviewing, helped do the release last friday. `_unrefActive` with optimizations with heap timers. At CascadiaJS the next of the week to get people’s feedback. * Julien Gilli: Released 0.12.6 last week, working on setting up other people to do joyent/node releases, joyent/node issue triage * Chris Dickinson: Working on docs more, have a new tool for docs to make sure the links are correct in a tree of docs, started a collaborator check-in on the io.js issue tracker, hopefully will be weekly. Jeremiah: what is that doctool? Chris: “count-docula”, a MDAST-based tool to verify correctness of the docs. * Shigeki Ohtsu: Not much on io.js, preparing to update OpenSSL tonight to get the OpenSSL security fix out. * Trevor Norris: Investigating the UTF8 decoder security issue and working on the fix. Reviewing PRs and being involved in the W3C Web Assembly working group. * Domenic Denicola: Not much on io.js, travelling, stress testing the vm module. * Brian White: Triaging issues, working on the javascript http parser more & benchmarking it. * Rod Vagg: We should discuss the LTS proposal again since there was lots of work done on that. Working on lots, including the security fix from last friday (writing up a post-mortem for it), getting external people involved to review our security processes. ### Default Unhandled Rejection Detection Behavior [#830](https://github.com/nodejs/io.js/issues/830) * Domenic: let’s say there was a magic way to detect when an error in an err-back style callback was not handled, what would we do? Print to stderr? * Bert: We do have a history of printing things to stderr. We should follow browser semantics if we can, in favor of primnting a warning but nothing else. * Discussion about the technicalities of handling unhandledRejections * Rod: not sure we should do anything since detecting this is somewhat arbitrary. * Domenic: there is a proposal for this that chrome implements behind a flag that comes close to how the unhandledRejection hook in node works * Discussion about the technicalities of having a better hook for printing a warning after garbage collection of an unhandled rejection. * See this thread for background detail of options in v8: https://code.google.com/p/v8/issues/detail?id=3093#c1 * Action: nothing now, maybe if v8 adds a hook for when rejections get garbage collected. * Domenic: looking at v8, it seems to have most of the hooks, so this may be possible soon. ### Adding a "mentor-available" label [#25618](https://github.com/joyent/node/issues/25618) * Folks are interested in contributing to larger tasks, need mentors to help them understand the process. Should we add a label? * Julien: Many people are interested in making “deeper” contributions, but they need a mentor. Let people add a mentor-available tag so they can locate these. * … part of the discussion missing here ... * Resolution: let’s try it, one such label has already been added. ### Having more people managing releases for Node.js v0.10.x and v0.12.x * Julien: I will have less time to do releases; it needs to become more of a team effort. * Alexis: in the long term this will be a responsibility of the build team. * Julien: unsure how responsibilities will be decided. LTS will need to sign off and build will need to produce the release. * Jeremiah: the iojs/current releases are already a group effort. It’s just that the “long-term” v0.10/v0.12 releases fall on few individuals now. * Julien: it’s a bit too much to handle for one person. Also people are sometimes unavailable or on vacation. Would like to have a group of about four people. * Ben: more contributors recently signed up. I think Sam Roberts might be interested. * Julien: would like to have a release management team. * Chris: iojs has had the release manager propose other release managers. Open an issue for this. * Resolved as such. ### lts: LTS Proposal https://github.com/nodejs/LTS#proposed-lts)/ Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) * James: when are we cutting over to the converged stream? Thinking of late august, first LTS release in October. Is this a good time? Most users won’t start migrating until next year because of the holidays. * Julien: what are other projects doing, when do they release? * James: looking it into it, some do it in fall. No clear pattern. * Alexis: what is the benefit of being on a fixed release schedule? * James: benefit is it makes planning easier. * Trevor: coming from the enterprise side, not having a predictable release schedule isn’t useful. * Steven: ICU and Unicode has announced that there will be a yearly release. It’s been helpful for planning. * James: It also ties into our regular release schedule and merging next into master etc. The next-to-master merge defines when we can do an LTS release. This should happen at least twice a year. The LTS is cut just before a merge (major bump), so by the time a LTS is cut it should have been stable for half a year. * James: please kick tires on this proposal, get feedback from the user communities you’re connected to wrt the frequency and release date. * Rod: the TSC should consider the timeframe, and the requirement that there should be two next-to-master merge yearly. * Trevor: how does this fit with a 6-week release schedule on master? * James: depends on the schedule. * Domenic: I don’t see the problem. Just take a 6 months old release and turn it into an LTS. * Rod/James/Trevor: because version numbers. The LTS version number needs to be a continuation of a release version. * Rod: fixed date, or part of the month. * Chris, Rod: get feedback, comment on the issue ### Next Meeting July 15th 2015 node-v4.2.6/doc/tsc-meetings/2015-07-15.md000644 000766 000024 00000007261 12650222326 017503 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-07-15 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-07-15 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/67 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1r8boI4E67Cq7PEsYeIpXkFZM0be4Ww5UDlNr_uXOop0 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Intl [#238](https://github.com/nodejs/io.js/issues/238) * TC39 representation [#2153](https://github.com/nodejs/io.js/issues/2153) ### Other * Foundation Discussion * lts: [LTS Proposal](https://github.com/nodejs/LTS#proposed-lts) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) ## Minutes ### Present * Mikeal Rogers * Colin Ihrig (TSC) * James Snell (TSC) * Fedor Indutny (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Alexis Campailla (TSC) * Jeremiah Senkpiel (TSC) * Shigeki Ohtsu (TSC) * Trevor Norris (TSC) * Domenic Denicola * Brian White (TSC) * Angela Brown (Linux F) * Mike Dolan (Linux F) * Laura Kempke (Linux F) * Bert Belder (TSC) ### Review of the previous meeting * Default Unhandled Rejection Detection Behavior [#830](https://github.com/nodejs/io.js/issues/830) * Adding a "mentor-available" label [#25618](https://github.com/joyent/node/issues/25618) * Having more people managing releases for Node.js v0.10.x and v0.12.x * lts: [LTS Proposal](https://github.com/nodejs/LTS#proposed-lts) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) ### Standup: * Steven Loomis: Intl WG - https://github.com/nodejs/io.js/issues/2165 * Mikeal Rogers: Meeting with the Linux Foundation * Colin Ihrig: Issues & PRs, met with Julien & Sam for joyent/node release onboarding * James Snell: Deep diving on a couple issues, looking into TC39 involvement, LTS feedback * Fedor Indutny: some bugs and node-spdy, not too much * Alexis Campailla: build-related things to converge the CI, most of the work is done, trying to get the CI working for 0.10. Also speeding up arm builds. +Windows issues. * Jeremiah Senkpiel: CascadiaJS Feedback was positive for the project convergence, sick from the cascadiajs cold, not much else. * Shigeki Ohtsu: Did the security update for OpenSSL on thursday * Domenic Denicola: Not much, working on the unhandled rejection spec. * Brian White: Mostly working on the JS Http parser, also working on a JSPerf.com-like tool for testing different node versions from the browser. ### Foundation Discussion (@mikeal leading) Security policy best-practices ### Intl [#238](https://github.com/nodejs/io.js/issues/238) Discussion if we can land this into `master` rather than `next`. Action: Check that there is no objection to landing in `master`. Steven, Domenic, James: Should be a direct port from 0.12, we can work on making a PR. ### TC39 representation [#2153](https://github.com/nodejs/io.js/issues/2153) Discussion about the legalities of joining officially and if unofficial representation would be workable. Action: Domenic will invite Mikeal to check out one of the TC39 meetings. ### lts: [LTS Proposal](https://github.com/nodejs/LTS#proposed-lts) / Proposal: Release Process [#1997](https://github.com/nodejs/io.js/issues/1997) Mikeal: We are effectively working under the new release proposal ([#1997](https://github.com/nodejs/io.js/issues/1997)) now with how `next` / 3.0.0 is going. Jeremiah: Only real contested point is how we might version the `next` branch releases. Domenic: Having multiple release train versionings in confusing. Action: Mikeal will update the current PR and separate any contention points into new PRs for discussion. ### Next Meeting July 22nd 2015 node-v4.2.6/doc/tsc-meetings/2015-07-22.md000644 000766 000024 00000013365 12650222326 017503 0ustar00iojsstaff000000 000000 # Node.js Foundation TSC Meeting 2015-07-22 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-07-22 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/69 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1r8boI4E67Cq7PEsYeIpXkFZM0be4Ww5UDlNr_uXOop0 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * doc: add GPG fingerprint for cjihrig [#2217](https://github.com/nodejs/io.js/pull/2217) * Process & Approval for Collab Summit Travel Fund [#2213](https://github.com/nodejs/io.js/issues/2213) * TC39 representation for the Node.js Foundation [#2153](https://github.com/nodejs/io.js/issues/2153) * Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) ## Minutes ### Present * Mikeal Rogers * Rod Vagg (TSC) * Colin Ihrig (TSC) * James Snell (TSC) * Fedor Indutny (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Jeremiah Senkpiel (TSC) * Brian White (TSC) * Ben Noordhuis (TSC) * Trevor Norris (TSC) * Chris Dickinson (TSC) * Mike Dolan (Linux F) * Emily Ratliff (Linux F) ### Security Policy Discussion Emily Ratliff from the LF has joined us to help with our security and disclosure policy. TSC members were sent a briefing prior to the meeting. Discussed ISO 29147 “Vulnerability Disclosure Overview” and ISO 30111 “Vulnerability Handling Processes Overview”. ### Review of the previous meeting * Foundation Discussion (@mikeal leading) * Intl [#238](https://github.com/nodejs/io.js/issues/238) * TC39 representation [#2153](https://github.com/nodejs/io.js/issues/2153) * lts: LTS Proposal (https://github.com/nodejs/LTS#proposed-lts)[ Proposal: Release Process] [#1997](https://github.com/nodejs/io.js/issues/1997) ### Standup: * Mikeal Rogers: preparing for the foundation board meeting * Rod Vagg: working on 3.0 and release candidates / NAN * Colin Ihrig: reviewing issues & PRs, worked with julien to do releases from joyent/node 0.x branches * James Snell: working on smoke-testing npm modules * Fedor Indutny: doing so bug fixes, and reviewing PRs * Michael Dawson: some joyent/node issue triage, PPC build work * Steven R Loomis: some Intl WG work, working on getting the Intl commits from joyent/node into io.js * Jeremiah Senkpiel: reviewing issues + prs, doing work on REPL in light of 3.0; fixing bugs in REPL * Brian White: working more on the in-browser node.js/io.js benchmarking tool, which is now in a usable state. using it now to test current and future performance improvement techniques for the the js http parser * Ben Noordhuis: (no mic) * Trevor Norris: did a fix for the buffer implementation for the 3.0 release * Chris Dickinson: npm work. ### doc: add GPG fingerprint for cjihrig [#2217](https://github.com/nodejs/io.js/pull/2217) * Rod +1 * James +1 * Fedor +1 * Michael +1 * Steven +1 * Jeremiah +1 * Brian +1 * Ben +1 * Trevor +1 * Chris +1 Action: make sure Colin’s GPG key setup is correct on the PR, after we can merge and Rod can add Colin’s credentials to the build server. ### Process & Approval for Collab Summit Travel Fund [#2213](https://github.com/nodejs/io.js/issues/2213) * Mikeal: budget auditing requires that spending be approved by the board - need to approve the budget and the process for expenditure of those funds. Mikeal has a proposal for the process with basic limits and a process for having the TSC approve expenditure beyond that. **Process as outlined** * TSC approves target budget (max amount to spend on travel) and caps on each type of spend (with the possibility that the TSC can approve a specific spend over if need be). * Contributors in need of the fund apply (this will happen in the GitHub thread) but should explicitly state if they need flight, accommodation or both. * If the number of contributors in need of the fund exceeds the target budget the TSC will prioritize the list of contributors applying for the fund. Voting on approving the process stated above: * Rod: +1 * James: +1 * Fedor: +1 * Michael: +1 * Steven: +1 * Jeremiah: +1 * Brian: +1 * Ben: +1 * Trevor: +1 * Chris: +1 Specific proposal for August * 15K max budget (we had previously talked about 10K but I don't think that is enough) * Approve a $900 max spend per person on accommodations. * Approve a $500 max spend on domestic travel * Approve a $1500 max spend on international travel (if someone has to go over it just requires additional TSC approval) * Rod: +1 * James: +1 * Fedor: +1 * Michael: +1 * Steven: +1 * Jeremiah: +1 * Brian: +1 * Ben: +1 * Trevor: +1 * Chris: +1 Approval for extra expenditure for @joaocgreis (from Portugal): $1,742.66 * Rod: +1 * James: +1 * Fedor: +1 * Michael: +1 * Steven: +1 * Jeremiah: +1 * Brian: +1 * Ben: +1 * Trevor: +1 * Chris: +1 Approval for expenditure on @yosuke-furukawa (from Japan) max spend of $2400 * Rod: +1 * James: +1 * Fedor: +1 * Michael: +1 * Steven: +1 * Jeremiah: +1 * Brian: +1 * Ben: +1 * Trevor: +1 * Chris: +1 ### Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) * Rod outlined the state of play: - LTS WG moved from “proposal” to “plan” but are still depending on the stable release branch having a clear process - LTS WG discussed a proposal by Trevor for how to handle next/canary/alpha & master & release branches & LTS branches: https://gist.github.com/trevnorris/7620a64b086e95271197 * Mikeal: it’s more helpful if we think about V8 upgrades as a pull-request to master rather than a separate “next” that has to be separately managed. Much bikeshedding was had in an attempt to move forward. Group agreed in general with Trevor’s proposal, will organise further discussions amongst the group of interested parties at another time. ### Next Meeting July 29th 2015 node-v4.2.6/doc/tsc-meetings/2015-07-29.md000644 000766 000024 00000006317 12650222326 017511 0ustar00iojsstaff000000 000000 # Node.js Foundation TSC Meeting 2015-07-29 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-07-29 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/71 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1FBmDczHD4D8jfffc6A8CW-K9mmT0KI8shG6dm_d3jXI * Previous minutes: https://docs.google.com/document/d/1eCETYn44gAOUp0udl22QxqyxrJ0oEeAFRdWHDCIq9V4 ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. ### nodejs/io.js * Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) * TSC Chair - Election? [#2136](https://github.com/nodejs/io.js/issues/2136) ## Minutes ### Present * Mikeal Rogers * Rod Vagg (TSC) * Colin Ihrig (TSC) * James Snell (TSC) * Fedor Indutny (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Jeremiah Senkpiel (TSC) * Shigeki Ohtsu(TSC) * Ben Noordhuis (TSC) * Trevor Norris (TSC) * Chris Dickinson (TSC) * Alexis Campailla (TSC) * Bert Belder (TSC) ### Review of the previous meeting * Security Policy Discussion * doc: add GPG fingerprint for cjihrig [#2217](https://github.com/nodejs/io.js/pull/2217) * Process & Approval for Collab Summit Travel Fund [#2213](https://github.com/nodejs/io.js/issues/2213) * Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) ### Standup: * Mikeal Rogers: Got ready for the board meeting, working to get the new website spun up based on the iojs.org build system * Rod Vagg: Finished writing NAN 2.0 documentation * Colin Ihrig: Issues & PRs, did the 2.5.0 release (armv6 build had an issue), playing around with the citgm package smoke-testing tool * James Snell: Working on citgm (npm package smoke-testing), halfway done writing up the release plan * Fedor Indutny: ? * Michael Dawson: Triaging joyent/node issues / PRs, looking at AIX build support on the `next` branch, looking at updating some docs * Steven R Loomis: Worked on the Intl converge PR [#2264](https://github.com/nodejs/io.js/pull/2264) * Jeremiah Senkpiel: Issue and PR review, helping to get someone to start contributing to core * Ben Noordhuis: not much, reviewed some PRs this week and did some minor patches * Trevor Norris: Just had time to review some issues and respond to PRs * Chris Dickinson: Not much, did docs work, trying to document streams (again), and the REPL history-paintext change PR [#2224](https://github.com/nodejs/io.js/pull/2224) * Alexis Campailla: Working on CI/Jenkins convergence, and some windows issue triage * Shigeki Ohtsu: Working on the updated crypto module for weak ciphers * Bert Belder: Not much except started reviewing a VS2015 support PR #### Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) Discussion about the release plan (not yet written up, James Snell is working on that.) #### TSC Chair - Election? [#2136](https://github.com/nodejs/io.js/issues/2136) Vote? * Colin: +1 * Chris: +1 * James: +1 * Fedor: +1 * Michael: +1 * Steven: +1 * Jeremiah: +1 * Shigeki: +1 * Ben: +1 * Trevor: +1 * Chris: +1 * Alexis: +1 * Bert: +1 ### Next Meeting Not happening on August 5th (as it usually would). Possibly a (short) TSC meeting will be held during the summit. node-v4.2.6/doc/tsc-meetings/2015-08-12.md000644 000766 000024 00000010660 12650222326 017476 0ustar00iojsstaff000000 000000 # Node.js Foundation TSC Meeting 2015-08-12 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-08-12 * **GitHub Issue**: https://github.com/nodejs/node-convergence-archive/issues/71 * **Minutes Google Doc**: https://docs.google.com/document/d/1q2bFjnf0Y23Ljxoze56Pmrbailaj5-UAqIUqIYVhiIk * _Previous Minutes Google Doc: _ ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. * Travel assistance amendment (no issue for this) * FYI: Collaboration WG: https://github.com/nodejs/collaboration * Summit recap * level-set on repo rename * Future: “project lifecycle” (Mikeal) - process by which top level projects are added (libuv, node-gyp, etc), (conferences…) ## Minutes ### Present * Mikeal Rogers * Rod Vagg (TSC) * James Snell (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Chris Dickinson (TSC) * Alexis Campailla (TSC) * Brian White (TSC) ### Review of the previous meeting * Next branch release versioning [#2215](https://github.com/nodejs/io.js/issues/2215) * TSC Chair - Election? ### Standup: * Mikeal: summit, code & learn project for new collab * Rod: Summit, migrating nodejs/io.js to nodejs/node * James: convergence, joyent/node PRs * Michael: patch for AIX, 0.12 work, Benchmarking meeting * Steven: Summit, 1st Intl meeting, Intl convergence work, VS2015 fixes * Chris: Summit, Docs repo has taken off, [HTTP lifecycle doc by Bryan English](https://github.com/nodejs/docs/blob/master/src/guides/anatomy-of-an-http-transaction.md) * Alexis: Summit, progress on CI convergence, reviewed some PRs. * Brian: Triaging and reviewing PRs and Issues. ### Travel assistance amendment (no issue for this) * Chris Dickinson adding $500 to the travel expenditure * Passed unanimously. ### FYI: Collaboration WG: https://github.com/nodejs/collaboration * Steven: new WG coming out of the Summit, Sean (@snostorm) is taking lead on this. One idea under discussion now is to have a multi-timezone meetings for the language working groups. * Mikeal: is this going to serve as a collaboration point for the language groups? * Steven: https://github.com/nodejs/Intl/issues/9 * Rod: beyond the language groups, what are the aims of this new group? * Steven: trying to address, or having a place to discuss, common items across working groups. * James: filling a need to liaise with the other working groups, acting as an intermediary ### Summit recap * Mikeal: 6 sessions in 2 days, not solid answers to problems but a shared understanding of the common problems, feels like we are on the same page from that * Mikeal: bigger sessions: what is the Node API and what is the Node platform? V8 release cycle. Errors and the inconsistencies. Kept coming back to the collaboration WG, which is why it exists. Talked about expanding the collaborator base, idea was to do some collaboration sprints to bring new folks up to speed, https://github.com/nodejs/code-and-learn comes from that idea (there is foundation budget for that). * Mikeal: there were extensive notes taken, those are being edited now and will be published into the repo(s) and turned into blog posts. ### level-set on repo rename * James: what are the remaining things to do - there’s confusion around the naming - Renaming everything in the documentation (README, docs & other misc docs) - Renaming binary - Alexis: finishing convergence work * Mikeal: preparing a blog post about what’s happening, will be reviewed and posted soon ### Future: “project lifecycle” (Mikeal) - process by which top level projects are added (libuv, node-gyp, etc), (conferences…) * Mikeal: the TSC charter states that we will adopt a project lifecycle that will allow us to bring in other _top level projects_. Additionally, the TSC has had to take on board some non-technical work because of its position in the Foundation (voting on expenditure, etc.), a number of TSC members don’t want to be involved in that kind of activity. Have started drafting a new project lifecycle plan which splits off a “Core TSC” that contains the existing TSC members but with a focus on Node.js Core work while the existing TSC will take on board the higher-level foundation work and members can optionally resign if they aren’t interested in that work and we can expand it to non-Core collaborators. https://github.com/nodejs/TSC/tree/lifecycle ### Next Meeting August 19th node-v4.2.6/doc/tsc-meetings/2015-08-19.md000644 000766 000024 00000011341 12650222326 017502 0ustar00iojsstaff000000 000000 # Node.js Foundation TSC Meeting 2015-08-19 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-08-19 * **GitHub Issue**: https://github.com/nodejs/node/issues/2435 * **Minutes Google Doc**: https://docs.google.com/document/d/1xsj_4UlrLNxahRvC7SpLtFM3D-Ks6CZEqEM5nyj6bjk * _Previous Minutes Google Doc: _ ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests prior to meeting. * Procedure for rolling out node-accept-pull-request [#2434](https://github.com/nodejs/node/issues/2434) * Release procedure changes & nominating @sam-github and @jasnell as releasers [#2416](https://github.com/nodejs/node/issues/2416) ## Minutes ### Present * Mikeal Rogers * Rod Vagg (TSC) * James Snell (TSC) * Michael Dawson (TSC) * Steven R Loomis (TSC) * Chris Dickinson (TSC) * Alexis Campailla (TSC) * Brian White (TSC) * Jeremiah Senkpiel (TSC) * Shigeki Ohtsu (TSC) * Trevor Norris (TSC) * Domenic Denicola * Ben Noordhuis (TSC) * Colin Ihrig (TSC) * Bert Belder (TSC) ### Standup * Mikeal Rogers: Linuxconf, preparing next board meeting agenda, nailing down the foundation conf * Rod Vagg: build work, memory leak testing, progress towards v4 (mainly infra) * James Snell: some joyent/node PR triaging, preparing for nodeconf.eu * Michael Dawson: nodeconf.eu, some AIX build work, talking to the v8 team about security notifications * Steven R Loomis: Intl WG, landed Intl with small-icu by default in nodejs/node * Chris Dickinson: first docs WG meeting, working on streams docs (again), working on docs tooling * Alexis Campailla: working on ci convergence and jenkins jobs * Brian White: not much, looking over issues and PRs, submitted a couple PRs * Jeremiah Senkpiel: not so much, working on 0.10, 0.12 -> v4 upgrade docs, 3.1.0 release which should be ready straight after this meeting. * Shigeki Ohtsu: little time to work on node right now, joined the LTS meeting to discuss OpenSSL LTS * Trevor Norris: reviewing issues and PRs, noticed a bug in asyncwrap * Domenic Denicola: issues and PRs, v8 team has a new Project Manager who is more interested in node; communicated our API stability concerns to him * Ben Noordhuis: fixed a big memory leak, fixed a regression in windows module loading, reviewing PRs, responding to bug reports ### Review of the previous meeting * Travel assistance amendment (no issue for this) * FYI: Collaboration WG: https://github.com/nodejs/collaboration * Summit recap * level-set on repo rename * Future: “project lifecycle” (Mikeal) - process by which top level projects are added (libuv, node-gyp, etc), (conferences…) ### Procedure for rolling out node-accept-pull-request [#2434](https://github.com/nodejs/node/issues/2434) * Discussed some potential concerns, which were alleviated: * Jeremiah: Wondered how to land PRs where nits needed to be fixed. * Bert: Concerns about Jenkins costantly building the wrong PR in the io.js CI infrastructure. * Trevor: asked for a dropdown to pick the reviewers. * Bert: asked whether the job would support landing multiple commits. Alexis confirmed this. * Alexis: mentioned that there is also an node-accept-commit job that is more low-level and advanced. ### Release procedure changes & nominating @sam-github and @jasnell as releasers [#2416](https://github.com/nodejs/node/issues/2416) Votes for @jasnell: * Rod Vagg: +1 * Michael Dawson: +1 * Steven R Loomis: +1 * Chris Dickinson: +1 * Alexis Campailla: +1 * Brian White: +1 * Jeremiah Senkpiel: +1 * Shigeki Ohtsu: +1 * Trevor Norris: +1 * Ben Noordhuis: +1 * Colin Ihrig: +1 * Bert Belder: +1 Votes for @sam-github: * Rod Vagg: +1 * Michael Dawson: +1 * Steven R Loomis: +1 * Chris Dickinson: +1 * Alexis Campailla: +1 * Brian White: +1 * Jeremiah Senkpiel: +1 * Shigeki Ohtsu: +1 * Trevor Norris: +1 * Ben Noordhuis: +1 * Colin Ihrig: +1 * Bert Belder: +1 No objections to combining the a whole "release team" to handle all release branches including 0.10, 0.12, stable and LTS. ### node-gyp is now in our org [#2379](https://github.com/nodejs/node/issues/2379) * Rod: node-gyp has a busy issue tracker and has no tests, needs more eyes * Ben: Zero tests? * Rod: Correct. * Domenic: on Windows Chromium’s depot_tools will automatically download VS community edition and put it in the right place. Someone with copious free time could have node-gyp do similar things. * Discussed maybe looking at `gn` (the eventual replacement for `gyp`) * Domenic: even v8 still uses gyp, don’t worry about it for a good while until noise about it being deprecated gets louder * Rod: issue [#151](https://github.com/nodejs/build/issues/151) in build has a discussion about precompiled native addons. Chime in! ## Next Meeting August 26th node-v4.2.6/doc/tsc-meetings/2015-08-26.md000644 000766 000024 00000014226 12650222326 017505 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-08-26 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-08-26 * **GitHub Issue**: https://github.com/nodejs/node/issues/2560 * **Minutes Google Doc**: https://docs.google.com/document/d/1aB76ClCgdjZUw3p-gHq9j6YwU11zWgJ4pmYPEWk6gjE * _Previous Minutes Google Doc: _ ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### joyent/node * Update README to reflect move to nodejs/node [#25897](https://github.com/joyent/node/pull/25897) ### nodejs/node * doc: merge CHANGELOG.md with joyent/node ChangeLog [#2536](https://github.com/nodejs/node/pull/2536) * (guidance on) rename of "language groups" from iojs-* to nodejs-*? [#2525](https://github.com/nodejs/node/issues/2525) * Node.js v4 Release Timeline [#2522](https://github.com/nodejs/node/issues/2522) ### nodejs/collaboration * How to onboard into WG? [#4](https://github.com/nodejs/collaboration/issues/4) ## Minutes ### Present * Rod Vagg (TSC) * Brian White (TSC) * Steven R Loomis (TSC) * Fedor Indutny (TSC) * Bert Belder (TSC) * Colin Ihrig (TSC) * Ben Noordhuis (TSC) * Mikeal Rogers * Alexis Campailla (TSC) * Trevor Norris (TSC) * Shigeki Ohtsu (TSC) ### Review of the previous meeting * Travel assistance amendment (no issue for this) * FYI: Collaboration WG: https://github.com/nodejs/collaboration * Summit recap * level-set on repo rename * Future: “project lifecycle” (Mikeal) - process by which top level projects are added (libuv, node-gyp, etc), (conferences…) ### Standup: * Rod Vagg: v4 release stuff, got certificates from/for the foundation, new website including CDN offering from CloudFlare * Brian White: continuing work on benchmark app for node.js/io.js, triaging, reviewing/answering issues and pull requests. * Steven R Loomis: Intl for convergence VS2015 * Fedor Indutny: http perf improvement PR, reviewing PRS, looking at issue for shared ports for http cluster * Bert Belder: busy with work, reviewing libuv PRs and responding to issues * Colin Ihrig: Rename from io.js to Node.js, reviewing issues and PRs * Ben Noordhuis: Running native addons as part of CI, libuv bugs, reviewing PRs * Mikeal Rogers: Website ready for release, working on CloudFlare CDN stuff * Alexis Campailla: CI for release, parallelising test runs for ARM, looking at managing dependencies with git * Trevor Norris: reviewing PRs and issues * Shigeki Ohtsu: reviewing convergence tests for SSLv2/3, working on TLS ALPN features before freeze ### Update README to reflect move to nodejs/node [#25897](https://github.com/joyent/node/pull/25897) * Alexis: made changes in CI to prepare for this, we’ll keep PRs in original repo, node-accept-pull-request will land changes in new repo as well, mirroring changes in 0.10 and 0.12 across both old and new repos. Still using the old Jenkins for releases for 0.10 and 0.12 right now and that doesn’t depend on repo name & location. Target ETA for transition: Monday. ### doc: merge CHANGELOG.md with joyent/node ChangeLog [#2536](https://github.com/nodejs/node/pull/2536) * Rod seeking confirmation from this group that this was _not a bad idea_. * Discussion about documentation for people upgrading from older versions of Node and having a linear history. Jeremiah has been working on 0.10 -> v4 documentation. ### (guidance on) rename of "language groups" from iojs-* to nodejs-*? [#2525](https://github.com/nodejs/node/issues/2525) * Steven discussed renaming the language groups * Mikeal: some groups are not in a position to make decisions because they are not active but the ones that are should be given the opportunity to agree or disagree to the move rather than us imposing a move on them. We should post an issue in their repos. * Steven: we should give them a timeline in issues in their repos * Discussed naming, could be “lang” or “community” to make it more clear what they are about. * ACTION: Steven to add a proposal to #2525, let TSC/collaborators add comments, later in the week will reach out to each of the groups. ### Node.js v4 Release Timeline [#2522](https://github.com/nodejs/node/issues/2522) * Rod gave a summary of the proposed release timeline https://github.com/nodejs/node/issues/2522 (and appologised for documenting it as “the” release proposal just for the sake of getting it done). - “feature freeze” Friday, 28th of August, cut v4.x branch - nodejs.org DNS changeover to new website Monday, 31st of August - release Thursday, 3rd of September - RC builds between website and release - backup release date of Monday, 7th of September if absolutely necessary to punt * Discussed the outstanding items in the 4.0.0 milestone: https://github.com/nodejs/node/milestones/4.0.0, some concerning items: - mdb support is late and may not get done, might have to be a semver-minor prior to LTS - vcbuilt.bat needs to use the new build_release target and we have to verify that all builds have Intl enabled - Steven to work with Rod on this - `process.send()` async/sync, Ben said that this is async on all platforms now (was just Windows previously but now it’s cross-platform) but it’s missing a callback so there’s no way of doing back-pressure. No time to add this prior to v4 but could be done as semiver-minor later. Ben agreed to document current behaviour properly in the docs. - `_unrefActive` is in Jeremiah’s hands, he will land the 0.12 changes as the io.js version is terrible. Discussed further perf improvements but agreed to leave those changes till later, ideally till v5 because of the potential for subtle edge-case bugs being introduced. ### How to onboard into WG? [nodejs/collaboration#4](https://github.com/nodejs/collaboration/issues/4) * Discussed GitHub onboarding mechanics ### V8 embedders unified debugger proposal * Trevor raised https://github.com/nodejs/node/issues/2546 which is a proposal for a unified debugger for V8 embedders using Chromium DevTools. * Discussion ensued, agreed to leave it for GitHub discussion unless/until there is something the TSC actually needs to make a decision about. ### Next Meeting September 2nd node-v4.2.6/doc/tsc-meetings/2015-09-02.md000644 000766 000024 00000041775 12650222326 017511 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-09-02 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-09-02 * **GitHub Issue**: https://github.com/nodejs/node/issues/2654 * **Minutes Google Doc**: https://docs.google.com/document/d/1rXBdtsD9PJTExNXgzNZ9bez9oOjW45kLPjun4zdt0dY * _Previous Minutes Google Doc: _ ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * deps: update v8 to 4.5.103.30 [#2632](https://github.com/nodejs/node/pull/2632) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) * Node.js v4 Release Timeline [#2522](https://github.com/nodejs/node/issues/2522) * doc: update COLLABORATOR_GUIDE.md [#2638](https://github.com/nodejs/node/pull/2638) ### nodejs/build * Merge job overwrites metadata [#179](https://github.com/nodejs/build/issues/179) ## Minutes ### Present * Rod Vagg (TSC) * Brian White (TSC) * Steven R Loomis (TSC) * Fedor Indutny (TSC) * Bert Belder (TSC) * Colin Ihrig (TSC) * Trevor Norris (TSC) * James M Snell (TSC) * Chris Dickinson (TSC) * Jeremiah Senkpiel (TSC) ### Standup * Rod Vagg (TSC): node v4 prep, new website * Brian White (TSC): issue/PR reviewing, working on JS DNS implementation some more * Steven R Loomis (TSC): syncing with james, creating text for renaming of language groups (#2525), intl triaging, commenting on joyent/node issues * Bert Belder (TSC): indisposed until end of october * Colin Ihrig (TSC): reviewing issues/prs * Trevor Norris (TSC): prs/issues, finagling the new build pr landing tool * James M Snell (TSC): old prs in joyent/node cleaned up (64 remaining, wow), citgm tool updates, child process arguments pr, nodeconf.eu * Michael Dawson (TSC): AIX support PR, some triage with Devin, preparing for NodeConfEU * Chris Dickinson (TSC): Static analysis work (ongoing), docs (slowly), npm * Jeremiah Senkpiel (TSC): v4 release prep * Fedor Indutny (TSC): v8 arraybuffer perf, patch landed on v8; reviewing PRs ### Jenkins merge jobs always overwrites PR-URL and Reviewed-By [#179](https://github.com/nodejs/build/issues/179) Trevor: currently if you submit a job to land a pr, it will always remove all existing metadata and re-apply it based on the info passed to the jenkins build. from convo, good fix is to let old metadata persist & only append new metadata if it’s entered, if no metadata entered, nothing appended Issue with current state: current system does not work for cherry-picks onto release branch — will wipe metadata and replace it Goal: solidify with TSC that this is a good path forward James: absolutely, +1 Jeremiah: clarification on which branches this applies to Rod: cherry-picks are becoming increasingly difficult on iojs anyway, so the pr landing job may be master-specific James: no mixing of “with pr tool” and “manually”, things go bad quickly that way Trevor: cherry-pick PRs are accumulating too many cherry-picks; runnin it through the system manually doesn’t add useful info Domenic: description of chromium - tests are run after landing - no one is allowed to land commits if the build is broken on a branch - sheriff of the day is responsible for fixing the issue - in practice it’s painful, but it’s important for keeping things sane Trevor: this would make us better about flaky tests, also, admiration for how sporadically our flaky tests break Jeremiah: trying to do this now before v4 seems like a bad idea Rod: we’re smoothing out a little bit; circle back to original topic, we’re kind of talking about the larger issue, let the trial of the tool continue and come back to the discussion later. specifically: ask that metadata not be overridden in a github issue Domenic: addressing jeremiah’s concern: should we not run the trial while releasing v4? Trevor: agreement — have felt pain from this as we march to v4 Jeremiah: stuff that gets released to people is in the release branches, if we’re not using the pr tool on that branch, what is the point of using this tool? Rod: this will become more of a problem as we have more extended and LTS Domenic: clarification: intent of ci is to make sure tests pass everywhere Trevor: this tool only runs a subset Rod: since we branched 3.x there’s 4 commits in the tree that have faulty/missing metadata — like that the pr tool is enforcing this metadata, maybe move to using github status api for telling us whether the metadata is OK Trevor: clarify: contributors have landed commits that lack metadata? Rod: yep Trevor: argh Jeremiah: github suggested we use the status api Trevor: status api autoruns? Rod: you hook it up to webhooks, has in-progress and pass/fail Trevor: TJ can verify that devs destroy jenkins (multiple force pushes explode the jenkins box with so many jobs) Rod: we can cancel on force push (or add a “trevor is pushing, wait half an hour to run the tests” exception, har har) Jeremiah: you can tell if it’s been run on the last commits Rod: multiple statuses — up to 100? — “this pr is passing on these platforms! this pr has the right metadata. this pr lints well.” Rod: let’s move on! James: what’s the action item? Rod: don’t feel that we should cancel the trial Trevor: two prs that prevent segfaults because of other flaky tests that have to be reapplied James: in the 4.x branch do we need to use test-pr job to land commits? Rod: nope, cherry-pick onto those branches, only use the tool on master Jeremiah: it’s weird to use it on the unstable branch. I guess we could make it better for release branches in the meantime * ci-run middle of hte night us time this has a Rod: vote for who whether we’d like to put this on hold Jeremiah: +0 put on hold Rod: who would like to continue it? ...crickets... Trevor: give me another day James: one PR took 8 hours to land last friday Jeremiah: they take about an hour to land right now Rod: they are getting quicker, adding raspberrypis to the cluster. good incentive to make node startup time quicker! arm startup times have gone down over the last month or so Rod: let’s move on ### doc: update COLLABORATOR_GUIDE [#2638](https://github.com/nodejs/node/pull/2638) Jeremiah: Alexis wanted to put the pr tool into the collaborator guide should punt on this right now notifying collaborators on issues is more effective messaging than the docs Rod: let’s hold off ### deps: update v8 to 4.5.103.30 [#2632](https://github.com/nodejs/node/pull/2632) Rod: looking at the possibility of jumping to 4.5 for the v4 release it’s ready to merge. ofrobots has been doing the work, it’s good to go, there are pros and cons whether we stick with 4.4 or 4.5 for this release & associated LTS has anyone done any work on testing NAN? Bert: what breaks? what are the cons? Domenic: looking at v8 by code inspection, there are no breakages, just new deprecations — should *in theory* work — I don’t think anyone’s been testing it though Bert: can this v8 release be supported for LTS? we don’t know if this is better or worse than 4.4? maybe ask goog eng Trevor: they will say “Stay current” Bert: I think I agree with them — with no other info, picking the latest version seems best Michael: Z targets 4.4 — just recently got it fully clean — a move to 4.5 would cause a delay on getting release to community James: that’s just Z, not PPC, yes? Rod: how much work? Michael: going 4.3->4.4 took about a month Jeremiah: 4.3->4.4 breakage delta was much bigger Rod: that’s the external API though Michael: 7-8 patches/week? if we have to upgrade it will be extra work + delay for us James: if we’re sitll looking at LTS in early-mid oct, it’s going to give us a month to prove out v8 4.5 Domenic: we’ve been proving out 4.5 for 12 weeks Rod: we’re talking node here, though we’d have google support for an extra month. my concern is: we need v4 out now, latest by monday, this is a quick change and there’s potential for breakage James: we decided before that we weren’t going to make such a big change so quickly before a release. i agree with rod, but such a big change makes me nervous — making sure that nan et al works with 4.5 is a concern Jeremiah: we’re not going to be the ones to find the flaws in 4.5; want clarification on nan major/minor/patch? Rod: minor Domenic: should require no changes Rod: benjamin (kkoopa) is on the positive side of this, he wants to see us move to 4.5, and is willing to put in the work to do this Trevor: not that it matters much, but node has taken a hit from v8 in terms of perf recently, 4.5 has some improvements, fedor wrote an easily backportable patch as well, there are perf advantages James: it makes me nervous that we’ll have enough time to test things on the node side before LTS — if we’re comfortable saying we have a plan that we think exercises this before going LTS, I’m more ok Jeremiah: technically we have over a month Rod: vote who is leaning sticking to 4.4 James + michael + steven 4.5: fedor, colin, jeremiah, brian, chris Rod: clarifying concerns Michael: share concerns with james, but also Z Rod: longer we have to support our own V8, the harder it is, and another 6 weeks of support would be great great James: I’m -0 Rod: spending some time today testing some existing addons taht have upgraded to nan@2. if there’s breakage, that tells me nan’s not ready, and that should be taken into account Domenic: if nan’s not ready, we don’t upgrade Rod: heading for 4.5, but with final go/no-go coming from nan testing; where are you at on this bert? Bert: I am happy to upgrade if you land it and nothing changes — which sounds like it might be the case (sans deprecation warnings) Rod: want ben’s opinion, but there may be no chance of that? Bert: it seems silly to go with a version that is almost already out of support, but OTOH, on the scale of LTS lifetime, 6 weeks is not really significant I wouldn’t worry too much about actual bugs in v8, about as likely in 4.5 as in 4.4; LTS is not about “no bugs”, it’s about “We support it” Rod: we want a **solid** release, though Bert: the LTS will also have a beta for a while, yes? Rod: the beta period for LTS is the stable line James: first LTS will have a beta of a little over a month, in the future 6 months Bert: realistically a month is a longer beta than we’ve ever had before Rod: 0.12 had a beta of 2 years {zing} :trollface: Bert: a beta with a lot of api changes, which is explicitly what we’re not going to do Bert: we need to move on Jeremiah: 4.5 brings arrow functions and that will make many people very happy Rod: it’s a good sales pitch! Rod: I’ll make the call. ### Node.js v4 Release Timeline [#2522](https://github.com/nodejs/node/issues/2522) Rod: status update: v4 was to get out by Thurs, slipping on that, monday is the release date, cannot afford to slip any further Jeremiah: what’s actually slipping other than mdb? Rod: we’re not going to get mdb into v4, encourage before LTS, but that’s the best we can do, child process argument type checking where are we at on that? Trevor: it’s not ready James: working on that PR right now Rod: great, that feels like a fairly light one, process.send is the other one; ben’s on holiday, where are we at with that pr of his Jeremiah: multiple people have soft signed off on it Colin: weren’t there some strange ci failures with it? Rod: do not know, does someone want to put their hand up for that? Trevor: what’s the PR number? Jeremiah: #2620 Jeremiah: Trevor +1’d it Jeremiah: OH! that’s the one with the weird test failures we could not reproduce the breakage Rod: this seems like it can be run again and it won’t show flaky tests: maybe we should just re-run it Trevor: that really sucks when you’re trying to land 3 tests Rod: test runner should auto-rerun to make sure Trevor: oh, gotcha Rod: that’d be really quick for flaky tests Trevor: I’ve already reviewed and LGTM’d it, I’ll look at running it through the land-ci job James: looked at it earlier today, nothing concerning stood out Rod: no RC’s are out! that’s a problem! we’ve renamed the executable. I wanted to have a period of time where folks could download (with a working node-gyp) — we need this period of time. I’ve been working on that, some bits and pieces to get things to the right place on the server. first build had a broken OS X installer. there are a few yaks yet to shave, so that’s why we can’t get this out by thursday Rod: steven: could you confirm that 3.x has INTL enabled? Steven: will look into, take as action item (confirmed!) Rod: not going to tick that off till we confirm, but I _think_ that one’s done Rod: how’s everyone with the timeline? rcs ASAP + release on monday James: sounds reasonable, yes. will take as much time as possible on monday. several of us will be at nodeconf, so that complicates Rod: I’m using monday in airquotes, it’ll be tuesday for me. other thing: smoke testing, citgm, I’ve been using it, and there are a lot of weird failures, after v4 we’re going to have to switch modes to make the ecosystem happy with it Rod: let’s move ahead with that plan; nodeconf.eu is going to take up a lot of time for a lot of folk. congrats to everyone that contributed to new website, it seems really smooth ### Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) Rod: opened by member of v8 team, extracting debugger code from blink and making it so all embedded v8 projects can use it Trevor: gist is: devtools team is considering pulling inspector out of blink into its own project so we could consume it; domenic can correct me wherever I’m wrong here, Domenic: “making node work the same as android” able to point chrome dev tools at node processes to debug ‘em ???: only works with chrome Trevor: OTW API we consume have remained fairly stable, even if the API does change, chrome dev tools is capable of pulling in a previous version, making sure it’s possible to use with LTS releases OTW wire is generic, consumable by anyone, chrome dev tools is a key consumer, but anyone can consume (new consoles can compete!) cons: APIs going to need to be tightly integrated — needs to know about all async events add conditionals to e.g. nextTick + timers Domenic: add something to MakeCallback? Trevor: we have to add it to that + on the way back in Domenic: this is for async stack traces Trevor: we don’t have to have it Bert: that’s awesome, because we have to grow a single entry point (opposite MakeCallback) Trevor: not going touch nextTick/timers, though — need to wrap each (because those APIs don’t roundtrip to C++ for each callback) Bert: we don’t have to do that immediately though, but eventually it’d be a good idea Domenic: could also move to microtask for nexttick — integrating with domains sounds hard, then we get those events for us Trevor: would you be able to do unhandledRejections? Domenic: we already have this for promises Rod: if we could use this as a good justification for removing domains, that’d be awesome Trevor: next point is pro and con: importantly, we’d have to support websockets natively in node Jeremiah: we could just keep ‘em private Trevor: that would just anger people Domenic: you could bundle them and hide them while you’re not clear on the api, iterate and expose later Rod: that’s a good point Trevor: the interesting flip to this: they need to be running off the main thread, in a debugger thread — it can all be written in C++ mscdex: any way to avoid websockets? Trevor: no Bert: is the protocol really that complicated? I don’t think so — especially sans full HTTP and WSS — just websockets though is probably not difficult Trevor: necessary because it’s the protocol that chrome dev tools uses Rod: decision points: are we being asked to get on board? Trevor: them removing the inspector from blink depends on whether we’ll use it if they do it. Rod: debugging in node sucks, we are shipping with substandard debugging in v4, we don’t have the contributors + collaborators to make this better, so if we can lean on v8 to do this, I’m +1 debugging is important enough to override “small core” Bert: we’re not adding the full inspector, _just_ the protocol Trevor: wasn’t completely clear on how much API we’d need to implement Domenic: we should get clarification on this Trevor: if we can implement this in segments — if we’re all +1 on this, we need to create a new isolate, but … Domenic: would the workers pr solve this? Trevor: probably overkill. I’m +1 on the debugger Bert: I propose we don’t vote {broad assent} Rod: trevor + domenic: you’ve got enough input Domenic: only worry is finding someone to devote some of their daytime hours to implement websockets Rod: nodesource could contribute, related to our interests Trevor: even if we don’t say yes today, taking inspector out of blink is a complicated process and will take time Rod: anything else? ### Next Meeting September 9th node-v4.2.6/doc/tsc-meetings/2015-09-16.md000644 000766 000024 00000012506 12650222326 017504 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-09-16 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-09-16 * **GitHub Issue**: https://github.com/nodejs/node/issues/2898 * **Minutes Google Doc**: https://docs.google.com/document/d/1RCR2pGOc2d80NNusaX5DZaktWvHEsDUqfEZP-tvexBk * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (TSC) * Brian White (TSC) * Steven R Loomis * Fedor Indutny (TSC) * Bert Belder (TSC) * Colin Ihrig (TSC) * Trevor Norris (TSC) * Shigeki Ohtsu (TSC) * Chris Dickinson (TSC) * Jeremiah Senkpiel (TSC) * Ben Noordhuis (TSC) * Alexis Campailla (TSC) * Domenic Denicola * Michael Dawson ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node-v0.x-archive * Deprecate Array#values() in 0.12.x [#25877](https://github.com/nodejs/node-v0.x-archive/issues/25877) * Deprecate smalloc in v0.12 [#25784](https://github.com/nodejs/node-v0.x-archive/issues/25784) ### nodejs/node * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) * util: Remove p, has been deprecated for years [#2529](https://github.com/nodejs/node/pull/2529) ## Minutes Due to IBM’s acquisition of StrongLoop, IBM is over the TSC 25% company limit rule. Michael Dawson and Steven Loomis have stepped down from TSC, but they are here as observers. ### Standup * Rod Vagg: Released 4.0.0, also 3.3.1 maintenance release. Getting the build system ready for building/publishing 0.10 and 0.12 binaries. * Brian White: not much, triaging issues and PRs, some work on dns parser * Steven R Loomis: tsc resignation for IBM/SL merge, some issue triage, working on a more robust download for ICU (ICU server was overloaded, fixed to ICU again redirects to sourceforge, discussed longer term discussions) * Fedor Indutny: v8’s ArrayBuffer fixes, reviewing PRs, fixing issues * Bert Belder: very few reviews/issue comments. Some libuv work on rwlocks. * Colin Ihrig: not much, some issue tracker work * Trevor Norris: Trying to make things (including Buffers) faster, some issue/PR review * Shigeki Ohtsu: Just a few reviews of issues. * Chris Dickinson: Working on shoving static npm analysis data into a database, slowly * Jeremiah Senkpiel: NodeConf.eu, issues and PRs, 4.1.0 release * Ben Noordhuis: only PR review and responding to bug reports, a patch or two upstreamed to v8 * Alexis Campailla: ARM cross-compile for CI. Misc fixes for VS 2015 / Win10 * Domenic Denicola: some issue and PR review, talking with v8 team * Michael Dawson: landed the build updated for AIX, also updating the tests for AIX where necessary. Looking into PPC failures. Working on getting us hooked into v8 security notifications. ### Previous meeting’s agenda * Jenkins merge jobs always overwrites PR-URL and Reviewed-By [#179](https://github.com/nodejs/build/issues/179) * doc: update COLLABORATOR_GUIDE [#2638](https://github.com/nodejs/node/pull/2638) * deps: update v8 to 4.5.103.30 [#2632](https://github.com/nodejs/node/pull/2632) * Node.js v4 Release Timeline [#2522](https://github.com/nodejs/node/issues/2522) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) ### Deprecate Array#values() in 0.12.x [#25877](https://github.com/nodejs/node-v0.x-archive/issues/25877) ### Deprecate smalloc in v0.12 [#25784](https://github.com/nodejs/node-v0.x-archive/issues/25784) Jeremiah: Are these things that we think we can do? Should we go ahead with that? Is it a good idea to deprecate these things? Ben: How are we going to deprecate? Literal `util.deprecate`? Jeremiah: Probably? Trevor: They’re already floating a patch Rod: I’m fine with deprecating smalloc Trevor: Is there a deprecation cycle between LTS? I’m not sure how this would work? (i.e., if we deprecate now, LTS -> LTS upgraders will not see a deprecation warning.) Rod: Maybe punt to LTS WG? It could be quite a lot — it could be that we decide between stable versions to remove things (or we’re forced to), do we backport the deprecation to LTS? Jeremiah: I think it should be only for things we’re _forced_ to remove Action: Punt to LTS WG ### Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) Trevor: Have an 80% understanding of the work needed: WebSocket support in core (though not necessarily exposed publicly), API injection points. Are we ok with including web sockets support one way or another? Rod, Domenic, others: +1 ### util: Remove p, has been deprecated for years [#2529](https://github.com/nodejs/node/pull/2529) Discussion of Buffer “raw{s,}” encoding as well — undocumented, deprecated, inconsistently implemented in core. Action: Remove util.p (Jeremiah to respond.) Bert: Perhaps we should bulk remove? Rod: util.p is relatively trivial, has a deprecation warning, etc. Jeremiah: Brought this up because these things have been deprecated forever. util.exec has been deprecated for a while, as well. Trevor: raw/raws are deprecated in name only, no warnings, but C++ layer does not know about them (falls back to utf8) — maybe should be removed as a bugfix, because it does not work consistently. Action: Chris to list “least used stuff” (with apologies for how longs its taken!) ### Next Meeting September 23 node-v4.2.6/doc/tsc-meetings/2015-09-30.md000644 000766 000024 00000017073 12650222326 017504 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-09-30 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-09-30 * **GitHub Issue**: https://github.com/nodejs/node/issues/3126 * **Minutes Google Doc**: https://docs.google.com/document/d/1RkLAWTIrhD3BTB2rs9_FahWI0C7lt9F8xnQXaueJPIE * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (TSC) * Brian White (TSC) * Chris Dickinson (TSC) * James Snell (TSC) * Michael Dawson * Ben Noordhuis (TSC) * Steven R Loomis * Bert Belder (TSC) * Alexis Campailla (TSC) * Domenic Denicola * Seth Thompson ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) ### nodejs/TSC * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) ## Minutes ### Standup * Rod Vagg (TSC) - Lots! Pass. * Brian White (TSC) - DNS PR (querying NSS modules like mDNS works now, continuing work on other getnameinfo/getaddrinfo compat issues) * Chris Dickinson (TSC) - Static Analysis * James Snell (TSC) - Review of the HTTP module, going in depth with spec compliance * Michael Dawson - AIX, contributing changes from IBM repos, node-gyp, all related to getting native modules working on AIX, submitted PR to core, benchmarking — bare metal machine for benchmarking group, backporting test fix to 0.12, FIPS-compat work on the test suite, getting hooked into v8 security reporting * Ben Noordhuis (TSC) - Review PRs, bug reports, fixed 1-2 bugs, sent a few patches upstream to V8 and gyp, fixed a few bugs in node-gyp. * Steven R Loomis - Review PRs, bug reports. Looking into alternatives to packaging full ICU data. Might be able to `npm install` ICU data. * Bert Belder (TSC) - * Alexis Campailla (TSC) - working on Node-serialport on Windows in Jenkins, looking into native module build service * Domenic Denicola - v8-extras are starting to appear in Chrome, maybe use them in Node for startup performance. ### Review of previous meeting * Deprecate Array#values() in 0.12.x [#25877](https://github.com/nodejs/node-v0.x-archive/issues/25877) * Deprecate smalloc in v0.12 [#25784](https://github.com/nodejs/node-v0.x-archive/issues/25784) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) * util: Remove p, has been deprecated for years [#2529](https://github.com/nodejs/node/pull/2529) ### Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) (Chris: apologies, I did a bad job here.) Ben: Plan is to ship the first LTS release with v8 4.5, not 4.6 Rod: Yes. Ben: Is there a pressing reason to do so? Rod: LTS comes off the v4.x branch, we committed to not bump V8 in stable releases. Ben: It basically means that the first LTS release is going to ship with an outdated release. James: Yes, we knew this was a strong possibility. Michael: The model is that we give the community time to catch up. In the future that’s 6 months, so we’re never going to be on a supported version. Ben: V8 moves quickly. If we stick with 4.5, we’re going to have to manage a bigger delta between our copy and upstream. James: Yes, this was always going to be the case. We’re committed to supporting the V8 for 36 months. Ben: Yes, my point is that we could be starting with a smaller delta. Rod: One of the reasons we had this LTS delay on 4 is to shake out some of these concerns, like the buffer changes. Normally this shakeout will be 6 months, but this time it’s only been a month. Alexis: Is v5 going to be LTS also? Rod: We are having discussions about the overlap between v5 and v6, whether there’ll be a strict cutoff or some overlap. No decision yet. That’ll happen in April. It sounds like most folks are leaning towards making the two releases (v4 LTS + v5) independent — option 1 [here](https://github.com/nodejs/node/issues/3000#issuecomment-144026295). Ben: We still haven’t come up with a way to maintain V8 going forward. James: We do need a good process there, you are absolutely right about that. Rod: I vote for IBM to hire someone dedicated to this. (Laughter) Michael: I can’t promise that at this point. Rod: As the delta increases between versions this becomes more concerning. James: make sure this is on the LTS WG agenda for next week. Rod: We tried to tackle this once before, came up with job description but nothing concrete. Michael: We stopped short of telling the foundation that this is a position that we need to staff. James: I would agree. We’re at the point where bringing someone in at the foundation level is probably a good idea. Rod: Noted. OK. We’ve got resolution there. Michael: James: Make sure it’s on the LTS agenda for going back to the foundation for resources. Rod: LTS is meeting this Monday (issue 43 on the repo). There’s some discussion around codenames and how to expose LTS info. We’ve committed to first week of October for LTS releases, so timing is going to be a little awkward with 4.1.2 coming out monday. Version 5 will be shipping when we have a stable V8, presumably mid-to-late october (1-3 weeks with no stable release line.) Rod: We’ll be pulling in semver minor and patch changes, we’ll continue to have bugfix releases for version 4, ### Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) Rod: Trevor is lead on this, but isn’t present. Does anyone else have any updates? Ben: Wasn’t the last contentious issue putting WS in core? I think we agreed that if it’s not exposed to user-land, it's fine. Alexis: (discussion of another WS issue) Bert: we decided on this Ben: We agreed that if it was internal, non-exposed to core, (Talk about native deps for WS, buffer-util can be ) Ben: if this is a private dependency, we don’t need it to be fast, so we don’t necessarily need the native deps. Chris: (Hopped into discussion from minute-taking, hence the bad minutes) https://github.com/nodejs/node/pull/1202 - add mask/unmask https://github.com/nodejs/node/pull/1319 - add utf8 validator ### Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) Ben: it’s basically a template for describing projects that are under the umbrella of the node foundation. It doesn’t look that controversial to me. Rod: it also doesn’t look that complete. Ben: Indeed. I suggest we discuss next week when mikeal is on the call. Seems like a rubber-stamp LGTM to me. Rod: We should think about what projects we want to introduce to the organization, including what happens to competition in the ecosystem when we pull in things (like build tools) Domenic: This is for things like libuv, yes? Rod: There are already npm projects knocking on the door. One such project is request. It has its own org right now, but could work under the auspices of the node foundation. However it exists in an ecosystem where there is competition — is it okay for us to bless one project over others? NAN is sort of in the same position, it _could_ have competition. Another example is the npm client possibly. If the foundation were in a position to take npm would we even want it? ### renaming of “language groups” from iojs-\* to nodejs-\* [#2525](https://github.com/nodejs/node/issues/2525) Steven: Looking for buyoff on this. Ben: Seen the approach and it looks good. Rod: You should take this as “you have authority to move ahead”. Steven: Will do. ### Next Meeting October 7th node-v4.2.6/doc/tsc-meetings/2015-10-07.md000644 000766 000024 00000011566 12650222326 017501 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-10-07 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-10-07 * **GitHub Issue**: https://github.com/nodejs/node/issues/3126 * **Minutes Google Doc**: https://docs.google.com/document/d/1LIrTCdTUjKtb_GGecrJ3Es0rPOpVdpkV5kefJ_p5FGU * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (TSC) * Brian White (TSC) * Steven Loomis (observer) * Trevor Norris (TSC) * Shigeki Ohtsu (TSC) * Ben Noordhuis (TSC) * Mikeal Rogers (observer) * Michael Dawson (observer) * Seth Thompson (observer) * Jeremiah Senkpiel (TSC) ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * lib,test: deprecate _linklist [#3078](https://github.com/nodejs/node/pull/3078) * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) ### nodejs/TSC * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) ## Minutes ### Standup * Rod Vagg: 4.1.2 release, security procedures surrounding that * Brian White: Working on javascript dns resolver, regular PR + Issue work. * Steven Loomis: Working on ICU 56 Release. TC 39 & emca spec work for Intl WG. Working on Intl build issues. * Trevor Norris: Focused on fixing async_wrap, writing tests and preparing for it to become more official * Shigeki Ohtsu: No works for node project, I spent all time to my internal works. * Ben Noordhuis: Nothing to report—the usual * Mikeal Rogers: Looking into stalled Wgs and seeing how to help out. Working on the umbrella program. Lots of conference things. * Michael Dawson: Added a benchmarking machine to the CI, working on some tests issues. Working on PPC for the CI. * Seth Thompson: Working on v8 4.7, scheduled soon * Jeremiah Senkpiel: vacation, some issue catch-up ### Review of previous meeting * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) * renaming of “language groups” from iojs-\* to nodejs-\* [#2525](https://github.com/nodejs/node/issues/2525) ### WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * Discussed the HTTP WG based on James’ comments @ https://github.com/nodejs/node/issues/3234#issuecomment-146293038 * Generally positive, only concerns are regarding decision making power—TSC may not want to hand that off as this is not quite like Streams (in that few people grok the code!) and there are philosophical questions to be resolved about HTTP that the TSC should be involved in. ### lib,test: deprecate _linklist [#3078](https://github.com/nodejs/node/pull/3078) * Userland modules exist that could be used instead * Ben suggested straight removal, Jeramiah raised the matter of process that we have committed to adding a warning before removal, so we could remove in v6 but probably shouldn’t in v5 * No disagreement with moving forward for deprecation ### Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Recap of the latest LTS meeting [LTS#43](https://github.com/nodejs/LTS/issues/43) * Aim to have LTS / v4.2.0 out tomorrow, backup date of Monday if we miss that. LTS starts then for v4.x, v5.x has to wait until V8 4.6 to be stable mid to late October. ### Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) * Shigeki, Ben: It would be quite hard to support 1.0.1 since we are using 1.0.2 APIs. * Discussion on the possible difficulty of using 1.0.2 on varied Linux distros * ubuntu wily (not released) seems to use 1.0.2 - work has been done to package. 1.0.2 is only in Wily - https://launchpad.net/ubuntu/+source/openssl/1.0.2d-0ubuntu1 - https://answers.launchpad.net/ubuntu/+source/openssl/+question/263725 - “My guess is that we will see openssl 1.0.2 from Ubuntu 15.10 onwards (or eventually only starting with 16.04)” * Concern that allowing 1.0.1 would result in a substandard (insecure?) & untested binary. * Some discussion about the fact that we don’t test building with shared / static dependencies * feedback to issue: No appetite to do the work from the TSC, maybe someone could do it but we wouldn’t support. ### Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) _skipped discussion_ ### Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) _skipped discussion_ ## Next Meeting October 14th, 2015 node-v4.2.6/doc/tsc-meetings/2015-10-14.md000644 000766 000024 00000013677 12650222326 017504 0ustar00iojsstaff000000 000000 # Node Foundation TSC Meeting 2015-10-14 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-10-14 * **GitHub Issue**: https://github.com/nodejs/node/issues/3363 * **Minutes Google Doc**: * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (TSC) * Domenic Denicola (observer) * Brian White (TSC) * Steven Loomis (observer) * James Snell (TSC) * Michael Dawson (observer) * Ben Noordhuis (TSC) * Jeremiah Senkpiel (TSC) * Trevor Norris (TSC) * Alexis Campailla (TSC) * Mikeal Rogers (observer) ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * V8 security reporting [#3348](https://github.com/nodejs/node/issues/3348) * doc: add information about Assert behavior and maintenance [#3330](https://github.com/nodejs/node/pull/3330) * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) ### nodejs/TSC * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) ## Minutes ### Standup * Rod Vagg: Not quite as involved, took a bit of time off. Getting back up to speed on build * Domenic: Nothing this week * Brian: PRs & Issues * Steven: Worked on getting ICU 56.1 out and into v4.2.0 LTS, working on making the ICU [install better](https://github.com/nodejs/node-v0.x-archive/issues/8996#issuecomment-89411193). Also shepherding iojs-* rename to nodejs-* [#2525](https://github.com/nodejs/node/issues/2525) * James: Worked on the 4.2.0 and 4.2.1 releases. Working on the cgitm smoke-testing tool and http WG. * Michael: Worked on adding pLinux to the CI. Looking into running the tests on fips-compliant mode. Investigated some AIX issues. * Ben: PRs & Issues, doing some work on the debugger and memory bugs in libuv * Jeremiah: PRs & Issues, working on resolving the timers in beforeExit bug: https://github.com/nodejs/node/pull/2795 * Trevor: Helped Jeremiah with the beforeExit thing, worked on PRs and Issues. Looking into AsyncWrap improvements. * Alexis: Looking into a native module build service. Worked on the Ci a bit. * Mikeal: Worked on the Umbrella Program proposal. Helping set up the Node.js Interactive conference. ### Review of previous meeting * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * lib,test: deprecate _linklist [#3078](https://github.com/nodejs/node/pull/3078) * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) * Inspecting Node.js with Chrome DevTools [#2546](https://github.com/nodejs/node/issues/2546) * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) ### V8 security reporting [#3348](https://github.com/nodejs/node/issues/3348) Michael: Proposal is to add one or more TSC members to the V8 security list. Not all issues will actually be V8 issues, but there shouldn’t be too many. * Concerns about too many issues Michael: Let’s go back and ask if a handfull means only 4-5 a week. Mikeal: Part of the Umbrella Program is to make a top-level security group that all security issues are funneled through. This group may not need to be TSC members. Ben: How would this group know an issue is relevant to us? Rod: We are talking about a Chromium security list, so we would probably need someone with enough knowledge to filter out which issues affect us. Mikeal: They would only be an initial filter. Rod: Some chromium issues will not be recognizable as V8 issues without prior understanding. Rod & others: Suggest to add Ben and Fedor to add to the Chromium/V8 security list. Discussion about the current Security repo / group, and current mailing lists ### doc: add information about Assert behavior and maintenance [#3330](https://github.com/nodejs/node/pull/3330) Discussion about what assert is intended to do, and how we want to deal with additions and breaking changes in the future. Discussion about the stability index in the docs. Resolution: Lock the assert module. Possibly re-evaluate in the future. Close existing open PRs/issues against it after landing doc change. ### WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) James: having scheduling problems for an initial hangout but are getting a lot of interest from outside of core, including Doug Wilson and Eran Hammer. Discussion about the WG’s goals and how we should possibly think about handing over authority of the http module to this WG in the future. (At charter time or later on) ### Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) James: recommended that we adopt a general rule that commits must go through at least one stable release before going into an LTS. Exceptions to this are security problems and changes that can’t go on to stable. ### Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) Conclusion was that this would be difficult and would result in a build that had some features disabled. The TSC is not going to undertake this work and would have reservations officially supporting a build that cripples some crypto features. However, pull requests for this work are welcome and would be considered. ### Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) Mikeal sought a vote from the TSC to adopt the Project Lifecycle document and the Core TLP document. Resolution: there were no abstentions from voting and no disagreement amongst TSC members present, additional TSC members have registered their +1 on the PR so the motion is passed. ## Next Meeting October 21st, 2015 node-v4.2.6/doc/tsc-meetings/2015-10-21.md000644 000766 000024 00000022530 12650222326 017466 0ustar00iojsstaff000000 000000 # Node Foundation Core Technical Committee (CTC) Meeting 2015-10-21 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/tsc-meeting-2015-10-21 * **GitHub Issue**: https://github.com/nodejs/node/issues/3464 * **Minutes Google Doc**: * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (CTC) * Brian White (CTC) * Steven R. Loomis (observer) * James Snell (CTC) * Michael Dawson (observer) * Chris Dickinson (CTC) * Ben Noordhuis (CTC) * Jeremiah Senkpiel (CTC) * Trevor Norris (CTC) * Alexis Campailla (CTC) * Mikeal Rogers (observer) * Shigeki Ohtsu (CTC) * Seth Thompson (observer) * Bert Belder (CTC) * Fedor Indutny (CTC) ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * governance: add new collaborators #VIII [#3472](https://github.com/nodejs/node/issues/3472) * detect "full-icu" module [#3460](https://github.com/nodejs/node/issues/3460) * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * node: deprecate public access to `process.binding` [#2768](https://github.com/nodejs/node/pull/2768) ## Minutes ### Review of previous meeting * V8 security reporting [#3348](https://github.com/nodejs/node/issues/3348) * doc: add information about Assert behavior and maintenance [#3330](https://github.com/nodejs/node/pull/3330) * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * Discussion: LTS & v5 release planning [#3000](https://github.com/nodejs/node/issues/3000) * Compiling node v4.0.0 with OpenSSL 1.0.1 fails [#2783](https://github.com/nodejs/node/issues/2783) * Umbrella Program [#2](https://github.com/nodejs/TSC/pull/2) ### Standup * Rod Vagg: index.tab and index.json updates (nodejs.org/dist/index.*) including an “lts” field, also made consistent directories for ancient Node tarballs with shasums files so nvm and other tools can simplify their access. v5 and other build yak shaving. * Brian White: usual triaging and PR and Issues commenting, not much else * Steven R. Loomis: Intl meeting, "full-icu" npm module [will be away until Nov 11 meeting, Unicode conf/Unicode-TC] * James Snell: Working on localization for the node runtime [#3413](https://github.com/nodejs/node/pull/3413) * Michael Dawson: Working through PPC and AIX PRs and issues, LTS WG discussions, Benchmarking WG, working with Stefan on agenda items for API WG meeting. * Chris Dickinson: was busy with vacation and conferences, but looking into the WhatWG Streams spec, next up is static analysis server * Ben Noordhuis: The usual. Looking into make the debugger better. The test suite is in bad shape * Jeremiah Senkpiel: issue and PR work — going back through the backlog now, helping with v5 release + npm@3 * Trevor Norris: flurry of AsyncWrap PRs, trying to get it to a point where people could more reliably use it, it can’t be hidden forever. * Alexis Campailla: Sick, traveling; CI progress on flakiness, some progress on native module build service * Mikeal Rogers: Foundation resources for v5 release: PR folks wrote a blog post, expectation setting, make sure enterprises are still using LTS, if you’re a dev here’s what to be excited about, etc. * Shigeki Ohtsu: Worked semver-major fix to limit DH key size [#1831] (https://github.com/nodejs/node/pull/1831) and some works for root certs. * Seth Thompson: Security mailing list stuff went through this week, working on v8 side of things to create a new version of the octane benchmark, excited about the benchmarking WG * Bert Belder: nothing * Fedor Indutny: reviewing PRs, helped fix a beforeExit bug, fixing yet another V8’s ArrayBuffer issue - Discussed the ArrayBuffer issue in detail * (Aside: Shigeki and Fedor were asked to look at [#3406](https://github.com/nodejs/node/issues/3406) - “p1/p2” issue ) ### governance: add new collaborators #VIII [#3472](https://github.com/nodejs/node/issues/3472) - Discussed onboarding. - Action: Jeremiah to schedule and run another onaboarding, Chris to tune in. ### detect "full-icu" module [#3460](https://github.com/nodejs/node/issues/3460) Stems from conversation from the 0.X days about whether Node should ship other languages separately. This is a module published on npm as an alternative to shipping with Node proper. Whether node can detect a full-icu install in a special place (node_modules/full-icu, global/node_modules/full-icu) Nathan7 commented with a concern about coupling npm to node Currently have to start node with ICU_DATA_PATH=some/path/to/file Rod: Couple it to `execPath` James: globally installed could install into a well known global location Rod: Does this have to be done at startup? Stephen: Yes. V8 has to have the data available before starting. James: Happens right after parsing args Rod: Could use HOME? Stephen: Could use NODE_PATH? Rod: Trying to move away from NODE_PATH Ben: Might just bite the bullet and include ICU? Stephen: I would like that, but I am sympathetic to folks running on OpenWRT Ben: I can see that, but all this installing in special paths leaves a lot of margin for error. James: Full ICU will double the size of the Node binary. Hard pill to swallow. Rod: We could offer alternative downloads? Stephen: Two downloads would work as well. We could do this all from build infra. Bert: I would not be in favor of that. We end up with “oh my module doesn’t work” “oh you didn’t download the right flavor of Node” Jeremiah: It’s going to make it confusing no matter what ... [I missed this] Chris: could we offer better error messages? Rod: it peeks through in a lot of places — the ICU object, strings, etc. Maybe best to leave to module authors? Include a process.versions.icu object? James: small-icu is the default build running locally — CI doesn’t run with ICU enabled? Trevor: even if small-icu is there, it means less data, but not less build time. I would like to see how that affects the raspberry pi’s build time. Ben: we could avoid rebuilding ICU on rasppis Stephen: or use a precompiled ICU Jeremiah: Assumes an internet connected machine Rod: If we go with small-icu we should make it available Ben: should we add it to the repo? Alexis: I think so, it’s causing problems [???]: It’s about 80mb Rod: How big is it? Stephen: The source size & binary size was comparable to Node. We could have a non-standard source checked in. Mikeal: we could use the large file storage stuff GH just added. Stephen: 25mb uncompressed, 130mb for source tree Mikeal: if we say “you need ICU to build” we need to make it available Trevor: How’s this going to work with bouncing between branches? Alexis: What about keeping it as text? Ben: Steven: We have a 25mb compressed zip of source, that itself contains a 25mb compressed zip. We could strip that down — what would it take to delete the tests, etc — a subset Mikeal: so could we just install this 25mb file? Rod: This adds a dep on Git LFS Mikeal: Let’s try to solve one problem at a time — fix downloading, not making the default Rod: I’m happy with how the CI does it … Stephen: The first time you hit something ICU-based it loads it. Rod: I’m just wondering if this could be turned into a proper npm module. Stephen: I’m not sure — it looks pretty deeply enmeshed into V8 Seth: I don’t have answers off the top of my head on that one, I responded on the thread; we don’t currently have a priority to mess around with localization. If there’s a design doc that proposes cleaning things up we’d be interested James: Resource bundle mechanism — [Note: didn’t get all of this] “using the same startup sequence as Intl.. so needs to be configured at start time” (https://github.com/nodejs/node/pull/3413 uses ICU’s resource bundle mechanism, which uses the same init path as the core data. ICU does not allow multiple initializations. Alexis: If the only reason we’re trying to package it is to use npm to install it, maybe we’re complicating this unnecessarily Rod: On the iojs side we decided not to go with ICU. It’s in core because it has to be initialized before v8 is started, my question is this something that could be changed upstream in v8? Ideally this should not be in core. Steven: It didn’t look like it could be split off easily. Chris: JS proxies Steven: Possible, but _very_ tricky [Moving conversation to GH] ### WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) HTTP WG first meeting is tomorrow at 1pm Pacific, nothing to discuss yet ### node: deprecate public access to `process.binding` [#2768](https://github.com/nodejs/node/pull/2768) Lots of discussion, focused on `process.binding('natives')`. Summary: We should at least try to make it read-only first. Ben said he would follow up with a PR. ### node: make listen address configurable [#3316](https://github.com/nodejs/node/pull/3316) Fedor: Ben suggested commandline argument to submit hostname and port. Fedor concerned about the amout of code required to parse and separate the two parts of the option. Would be better to have a separate argument for hostname. Discussion about usability vs simplicity of code. Quick vote on whether to move forward with the PR in its current form, no objections. ## Next Meeting October 28th, 2015 node-v4.2.6/doc/tsc-meetings/io.js/000755 000766 000024 00000000000 12650222326 017137 5ustar00iojsstaff000000 000000 node-v4.2.6/doc/tsc-meetings/io.js/2014-10-09.md000644 000766 000024 00000006215 12650222326 020517 0ustar00iojsstaff000000 000000 - Contribution Policy was merged last week. - Concerns about https://github.com/node-forward/node/issues/2 have been brought up, it effects almost every line and will make merges with Joyent unnecessarily painful in the short term. The consensus was to put it on the back burner. - It's a little difficult to work in the fork at the moment: - It's hard to contextualize what to fix without having a release in mind - We'll start doing source-only releases ASAP so that we can create a work scope. - Someone will be in charge of keeping their head around and driving each release. This should probably rotate, Bert will take on the first one with the goal of releasing before the end of the month. - For now tagging will create a GitHub "release." Eventually the build infra can attach binary installers to that GitHub release. - It's hard to keep a list of issues that are being tackled from the backlog in joyent's repo - Bert will maintain a list of TODO checkbox items in a GitHub Issue for a release the references the PRs and Issues in Joyent's repo. We'll also be on the lookout for other tools that might make this easier. - The build stuff is coming up a lot and the discussion about how releases work should include someone from the build project. - Invite whoever is leading the build effort (current @rvagg) to the TC meeting to participate (non-voting). - Eventually we'll need a better support structure where community members can triage issues and respond to all the incoming requests. - @mikeal created a "community" group and a repo for larger community issues. Once there is some momentum there we can bring problems like this to the community but the repo we currently control write access to doesn't have all of the issues in it so this can wait. - @indutny suggested a bot that auto-responds. @isaacs thought an autoresponder was a little inhuman. It was agreed that the best thing to do is have a bot that comments on the issue *once a tag is added* that is specific to that tag and run in concert with humans tagging issues. - @piscisaureus really wants to find a way for him to tell if someone already looked at an issue so that him, trevor, ben, and fedor don't independently look at every issue. - @indutny wants to get a newer v8 in. this work is slated to be finished for the first release. - @trevnorris mentioned that there are some new features in v8 that we may want to use to replace certain parts of node down the road. - @trevnorris and @isaacs want a "commit script" that people can run which automates a lot of the manual cleanliness we currently require for all commits. v8 has as simliar one. this will be written in javascript by @isaacs and @trevnorris . - When pulling in joyent/node commits we should use no-fast-forward commits. - If people want to talk to the TC in a more "chatty" way we should use the `#node-forward` IRC channel on freenode. We need to add logging. - The video of TC meetings doesn't include the chat so we need to be aware of that when using it during the calls. Video of the call is https://www.youtube.com/watch?v=fNW_tu2QnpA node-v4.2.6/doc/tsc-meetings/io.js/2014-10-15.md000644 000766 000024 00000006500 12650222326 020511 0ustar00iojsstaff000000 000000 # node-forward TC Meeting 2014-10-15 ## Agenda * Openssl upgrade / openssl 1.0.1j, disabling SSL3 support * Status of the build system & release automation * https://github.com/node-forward/node/pull/14 - refine TC percentage rules - CONTRIBUTING.md * Items preventing node-forward from releasing v0.12. * Node Forward release cycle/schedule. * (Maybe discuss v8 3.29 in node-forward vs 3.28 in joyent/node, and merging them? ...just a suggestion) * Performance situation * Node Forward website, non-core stuff, help repo. ## Links * **Google Hangouts Video**: https://www.youtube.com/watch?v=aRBuu2m5xbI * **Original Minutes Google Doc**: https://docs.google.com/a/vagg.org/document/d/18l01PO2Rb3OZXWMcIkZ_sU4f1JKP2LKOwjuiENkg37M ## Minutes ### Present * Rod Vagg (facilitator, build representative) * Mikeal Rogers (facilitator) * Ben Noordhuis (TC) * Bert Belder (TC) * Fedor Indutny (TC) * Trevor Norris (TC) ### Discussion * Fedor: **OpenSSL upgrade to 1.0.1j done in a branch**, build bots reporting OK, ready to merge. SSLv3 disabled completely in joyent/node 0.12 because the protocol is broken--attack comes from downgrade request from TLS to SSLv3. 0.10 has a runtime flag to enable it via process arguments (`--enable-ssl3`). * Rod (representing the build group): tried Jenkins and BuildBot. Neither are great, but right now they’re working on getting something to work now, although eventually they’d like a great build system. There are build bots running for most platforms right now, except OS X (but there’s commitment from voxer to sponsor machines). Building branches works, but PRs doesn’t. This week some basic useful stuff should be available. - https://github.com/graydon/bors - rust - Benchmarks? Make a CI target just for benchmarks so we can track it over time. Not run on every PR, perhaps manually triggered, perhaps time triggered. http-simple? Fedor: large nightly benchmarks would be nice. Start with Linux, a single consistent box running the suite (doing a release too). * **Refine TC percentage**: pull node-forward/node#14. TC is short two people without Joyent & is small. 2 of 6 people are from Strongloop. #14 allows changing to 33% to allow the current TC to not be in violation for the time being and then change it back to 20% when we can. Consensus has been relatively easy, no votes have been needed thus far so there isn’t much concern. * **Release cycle**: time based releases? node-forward discussion have strong consensus for a desire to move to semver and also a quicker release cycle. - **General agreement on semver**, minor releases backward-compatible, major releases can break. - Discussion on **native API compatibility**, NAN or NAN-like or something more brave like having ABI compatibility. Ben: “You can’t forecast the future, the abstraction will break”. - **Supporting old versions**: deal with it when the project has “prior releases”. Defer discussion on exactly the model until the project is ready to make proper releases. Move discussion to GitHub. * **V8 3.29**, Fedor: joyent/node has 3.28, node-forward/node has 3.29. Trevor & Fedor agreed to put 3.29 in joyent/node pending agreement with TJ. * **node-forward website**, Mikeal: there is a website, http://nodeforward.org/ - Forrest suggests a help repo to replace what the mailing list works, he has offered to help support that. node-v4.2.6/doc/tsc-meetings/io.js/2014-10-29.md000644 000766 000024 00000003460 12650222326 020520 0ustar00iojsstaff000000 000000 * Update on Build * @rvagg is working on getting the builds consistently green before moving on to more complicated things. * @issacs brought up the Joyent Advisory board * Some confusion out there about Node Forward vs. Advisory Board * @mikeal updated the messaging on the website to be clearer * The website has clearer calls to action for the community * Libuv move * The libuv contributors want to move to the libuv org. * @mikeal will email @indutny and other libuv contributors to ask them to log an issue about this on their repo for transparency and so that this is not a surprise to Joyent * Update on "release buckets" * doesn't make sense while we're private, we'll wait until it is public again * `node-forward/node` going public * when we made the repo private it was messaged as only being for "four weeks" * "four weeks" is up on November 8th * someone on the Advisory Board needs to remind Joyent of this in the next advisory board meeting so they aren't suprised by it even though it was communicated to them when it was first made public. * @mikeal will work on the messaging in the README to make it clear this is a "soft" fork and not a "hard" fork. * ramifications of going public will be discussed in next week's TC meeting as well * @mikeal proposed a change in TC meeting process * it's impossible to schedule all the timezones involved in every meeting * every Monday create a "Weekly TC Agenda" Issue people can contribute to * the TC members who care about that Agenda will state they want to be in the meeting * @mikeal will work to schedule the TC members who care for a hangout * people are using and liking gitter * we'll consider moving from IRC to gitter once the repo is public again * yes, gitter has IRC integration (you can login to gitter from an IRC client) node-v4.2.6/doc/tsc-meetings/io.js/2014-12-10.md000644 000766 000024 00000016417 12650222326 020516 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2014-12-10 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * @chrisdickinson nomination to TC https://github.com/nodejs/io.js/issues/51 * Move readable-stream to iojs org and make authoritative source for io.js to pull _from_ https://github.com/nodejs/io.js/issues/55 * Deprecate domains https://github.com/nodejs/io.js/issues/66 * Decide how to go forward with caine https://github.com/nodejs/io.js/issues/117 * Is it io.js, IO.js, or something else? https://github.com/nodejs/io.js/issues/118 * Build automation update * extending options from a prototype https://github.com/nodejs/io.js/issues/62 * Separate I/O tests from simple, so simple tests can be run in parallel * Statement / stance from TC on exposing a Promises API https://github.com/nodejs/io.js/issues/11 ## Links * **Google Hangouts Video**: https://www.youtube.com/watch?v=otE4IRMVUMo * **GitHub Issue**: https://github.com/nodejs/io.js/issues/112 * **Original Minutes Google Doc**: https://www.youtube.com/watch?v=otE4IRMVUMo ## Minutes ### Present * Rod Vagg (facilitator, build representative) * Ben Noordhuis (TC) * Bert Belder (TC) * Chris Dickinson (nominee to TC) * Fedor Indutny (TC) * Trevor Norris (TC) ### @chrisdickinson nomination to TC https://github.com/nodejs/io.js/issues/51 **Unanimous decision to add Chris to TC** ### Move readable-stream to iojs org and make authoritative source for io.js to pull _from_ https://github.com/nodejs/io.js/issues/55 * Chris expressed concerns on doing this, but a -0 for now, give it a go and see how it works * Discussed the potential difference with joyent/node * Trevor discussed concerns about the tight coupling of streams to core * Rod talked about organisational and community concerns * No -1’s on moving the source of authoritative code and moving readable-stream into iojs * Need to experiment with the flow: code, issues, docs, etc. * **Consensus reached on moving readable-stream to iojs and flipping the authoritative code and doc flow** * Chris and Rod to work on the process in GitHub ### Deprecate domains https://github.com/nodejs/io.js/issues/66 * Trevor: domains are horrible but we don’t have a good alternative yet * Ben: +1 on removal but don’t have a good story on what to tell people to use * Bert: -1, would rather clean up docs to be honest about how it doesn’t do what it was hoped to * Trevor: domains inhibit progress because of their invasiveness * Discussed how to document concerns etc. * Discussed https://github.com/nodejs/io.js/pull/15 which adjusts the domain.run() API * Agreed: - Accept PR #15 - **Document that domains are on the way out: soft deprecation** (no util.deprecate()) ### Decide how to go forward with Caine (bot) https://github.com/nodejs/io.js/issues/117 * Fedor talked about _what_ caine is and _why_ it exists: too many emails from the repo, want to set up a system where relevant people are pulled into particular issues rather than having to subscribe to the repo for all notifications * Chris: primary concern with having an automated bot is the incoming experience for users (like having a join bot on IRC) * Discussed notifications / labels / etc. * Bert discussed using a “new” label for triage--automatically add to incoming issues and remove when the issues have been looked at / dealt with by a contributor. * Trevor voted to **move the discussion to GitHub** ### Is it io.js, IO.js, or something else? https://github.com/nodejs/io.js/issues/118 * Ben: lowercase is “objectively superior” (j/k) * No disagreements, the name is “io.js” * Ben: binary name suggestion “iojs” with symlink to “node”, lots of discussion in https://github.com/nodejs/io.js/issues/43 * **No disagreements, binary name will be “iojs”** * Ben: how do we handle it on Windows? .bat file (problems with arg forwarding), small .exe * Agreed to open a new issue to discuss Windows compat (Ben) ### Build automation update Rod gave a summary of build project status: - Containerized build system is being improved by an active team in the https://github.com/nodejs/build-containers repo, on target to enable automatic PR tests and status reports back to GitHub (will likely just be Linux distros for the forseeable future) - Next step is to enable committers to be able to trigger full builds across the build cluster - Aiming for more automation for a mid-January release, have concerns about Windows and OSX signing and the need for signing keys and how complex they are. - Chris Lea is working towards nightly builds for .deb-based systems (RHEL / Fedora based systems could come later but the assumption is that people running those systems are _less_ likely to want nightlies) - https://github.com/nodejs/io.js/issues/13 is an ARM build failure that still needs attention to have ARM part of the build mix and not constantly fail (see https://jenkins-node-forward.nodesource.com for some ARM failures) ### Extending options from a prototype https://github.com/nodejs/io.js/issues/62 * Chris is asking for input * Ben: we’re currently only looking at the object’s own properties, and ignoring properties on the prototype. * Fedor: in general there’s no reason to explicitly check whether properties are on the object or on the prototype chain. * Ben: **continue in the issue tracker** * Bert: be consistent. Slightly agree with fedor. ### Separate I/O tests from simple, so simple tests can be run in parallel * Fedor: discussed the possibility of moving out net and possibly fs tests so the rest can be parallelized. There may be problems with many of the fs tests because they use fixtures. * Fedor: **agreed to try it out** * Bert: preference for the “tests” target to run the current test target ### Statement / stance from TC on exposing a Promises API https://github.com/nodejs/io.js/issues/11 * Rod: can we come up with some kind of statement from the TC regarding the possibility of adding a Promises API to core, even if it’s vague * Bert: there’s a convergence of functionality around Promises that are making them more useful in conjunction with other ES6/ES7 features, TC should be _open_ to adding a Promises API in the future * Trevor: would like to simplify the current API so that it’s easier to extend and add abstractions on the top * Ben: when simplifying, it would be good to have a target for how the simplification can be used, Promises could be one of those * Bert: It would be weird for Node to go its own path if the rest of the JS ecosystem were to go that way * Rod & Bert: suggested a statement along the lines of: **Promises doesn’t make sense right now, so it’s not going to happen in the short-term, but the TC is open to change as things evolve in ES6 and ES7 and practical issues are worked out, TC is open to experimentation, a _callback API is unlikely to ever go away_** * Ben: a +0 * Trevor: pending practical concerns * Fedor: a -0 * Chris: +0 ### Working with nvm, nvmw and similar installation managers https://github.com/nodejs/io.js/issues/40 * Ben: suggested a dist.iojs.org for hosting binaries * Ben: suggested a release.txt * Rod: **leave it up to the build team to work out the mechanics of releases and release.txt and/or release.json and come back to TC for approval or adjustments prior to formal release** (i.e. no need to bikeshed on this here right now) node-v4.2.6/doc/tsc-meetings/io.js/2014-12-17.md000644 000766 000024 00000011754 12650222326 020524 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2014-12-17 ## Links * **Google Hangouts Video**: https://www.youtube.com/watch?v=7s-VJLQEWXg * **GitHub Issue**: https://github.com/nodejs/io.js/issues/163 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1PoqGfxpfTFKv5GcKmhMM2siZpPjT9Ba-ooBi-ZbYNi0 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * Bundle tick processor with iojs #158 https://github.com/nodejs/io.js/issues/158 * Release Cycle Proposal #168 https://github.com/nodejs/io.js/issues/168 * Module search security #176 https://github.com/nodejs/io.js/pull/176 * Dealing with feature requests ## Review of last meeting * Move readable-stream to io.js and flip authoritative flow of code, docs and issues * Soft deprecation of domains, accept PR #15 as last feature addition * Caine, discussion continued on GitHub * Project name is “io.js”, binary name is “iojs” * Extending options from prototype, discussion continued on GitHub * Promises statement for issue #11 * Working with nvm, etc. ## Minutes ### Present * Bert (TC) * Chris (TC) * Trevor (TC) * Isaac (TC) * Rod (build, facilitator) ### Bundle tick processor with iojs #158 https://github.com/nodejs/io.js/issues/158 * Bert: important because it’s tied to the version of V8, not practical to put it in npm because one is needed for each version * Isaac: this is minimal and shouldn’t set a standard for just adding more stuff to core (i.e. keep core minimal), so +1 +1 from Isaac, +1 from Bert, **no disagreement amongst group, consensus has been reached on bundling a tick processor with releases.** ### Release Cycle Proposal #168 https://github.com/nodejs/io.js/issues/168 * Bert & Isaac discussed how this feeds into the ability to have frequent releases. Discussed semver plays into this. * Rod: consensus seems to be around having stability, predictability, lead-time but more frequent releases. * **Bert: Move discussion to #168. Still premature to discuss here.** ### Module search security #176 https://github.com/nodejs/io.js/pull/176 * Limiting node_modules search path to $HOME as a top-level * Isaac ~ -1 on this because EACCES already happens when you don’t have permission * Isaac and Bert bikeshedded Windows C:\ writability and security on Windows. i.e. if someone can install code on a shared system above where a node application is running (e.g. C:\) then you could have untrusted code run by your application. * Isaac: this PR is only addressing projects running in the home directory. * Rod: module system is locked-down, TC needs to come to consensus that this is a _security_ issue and therefore warrants breaking it. * Chris: `useradd node_modules` is a situation this could be a problem * Isaac: not convinced this is a security problem, even the `useradd` situation requires root access on a system. * Bert: this is an academic issue, it may _feel_ wrong but that doesn’t mean it’s strictly a security issue. * Isaac: proposed the issue be closed as not a security issue. * **No consensus that this is a security issue. Move discussion back to GitHub, potentially close issue, potentially bringing discussion back here. Encourage users to bring examples of real problems.** ### Dealing with feature requests * Bert: asking for discussion about what to do with feature requests that come up but aren’t clearly something that are wanted. * Bert: should we put a time limit on feature requests? Would like some guidelines for how to deal with these. * Chris: have already been putting a 4-6 day window before closing them. If there is no code then it’s easier to close. If there is code then there could be more discussion. * Isaac: this is a broader problem about the roadmap-setting process. * Rod & Isaac: It’s up to someone on TC (or elsewhere) to start coming up with a roadmap, or at least start the discussion. * **Agreed to start a GitHub discussion on roadmap and soliciting feedback from the community.** * Rod: in an open model, it’s up to TC and those with commit access to take the initiative to just close things, given enough warning and chance for discussion and better arguments. * Isaac: builtins (like Blog of FileReader) are TC39 / WhatWG groups out there that are doing this at the language & V8 level and we pull from there. It should be straightforward to close those issues. * Bert: the roadmap shouldn’t be about locking down the dev process and tightly limiting scope of what’s added. * **Agreed that feedback to all contributors (including TC), regarding closing issues: close issues that are instinctively bad and worth closing (close can be undone), anything potentially controversial can be flagged with a “will close” but give ~ 1 week for discussion, disagreement, lobbying etc.** ### Logos * **Agreed that the release is the only _technical_ blocker from the TC’s perspective to a logo, so deferring discussion till then. Encourage interested parties from discussing this further on GitHub issue #37.** ### Next meeting * Bert proposed 2014-12-30 as next meeting time node-v4.2.6/doc/tsc-meetings/io.js/2014-12-30.md000644 000766 000024 00000006261 12650222326 020514 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2014-12-30 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=O60sOsesjOo * **GitHub Issue**: https://github.com/nodejs/io.js/issues/211 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1KLfX2MZQbVSIaD2lBVqOFK0Kap4uFz9cTGihnpTuvPE ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * sys: Remove after 3 years of deprecation #182 https://github.com/nodejs/io.js/pull/182 * module: force require('process') to return a reference to process #206 https://github.com/nodejs/io.js/pull/206 * File copyright policy #216 https://github.com/nodejs/io.js/pull/216 * Rename v0.12 to v1.0.0 https://github.com/nodejs/io.js/issues/218 * Merge strategy (v0.10 and joyent/node) ## Minutes ### Present * Rod (build, facilitator) * Ben (TC) * Bert (TC) * Chris (TC) * Fedor (TC) * Trevor (TC) ### sys: Remove after 3 years of deprecation #182 https://github.com/nodejs/io.js/pull/182 * Ben: what sort of strategy to take? Deprecated only in the docs but no warning. Looking for an official deprecation policy. * Bert: suggest we could properly deprecate but not a good case for removing it completely, Chris agreed * Fedor: suggested a policy that removal of deprecated features should be done where there is a maintenance overhead, but otherwise if there is little/no cost then "who cares" * Discussed a deprecation message on `require(‘sys’)` * Ben: -0 * Fedor: +1 * Chris: +1 * Trevor: -0 * Bert: +1 * No disagreement to adding a deprecation message, **ask initial PR submitter to change to just adding a message** ### module: force require('process') to return a reference to process #206 https://github.com/nodejs/io.js/pull/206 * #157 has a long discussion on this: https://github.com/nodejs/io.js/issues/157 * Chris: +1 on a PR adding this * Trevor: it just returns a global, no point * Bert: not the way that JS adds new features; discussed the new Intl addition to joyent/node, in favor of making more things requirable rather than adding new globals all the time * Tangential discussion on the Intl object being added in joyent/node * Collected votes: * Bert: +0 * Ben: +0.5 * Trevor: -0 * Fedor: +1 * Chris: +1 * **Ben to handle the merge / resolution** ### File copyright policy #216 https://github.com/nodejs/io.js/pull/216 * Rod asked if there are any strong opinions about how to handle this * **Group agreed that Rod will take this issue and seek legal advice to find a way forward** ### Rename v0.12 to v1.0.0 https://github.com/nodejs/io.js/issues/218 * Trevor: concerns about 1.0 vs 1.x branch naming with maintaining semver releases while also doing LTS, 1.x effectively becomes master until a 2.0 comes along. * Bert: -1 * Ben: +1 * Chris: +1 * Fedor: +1 * Trevor: 0 Action: **Rename to "v1.x", Ben agreed to make the change** ### Merge strategy (v0.10 and joyent/node) * _Much_ discussion about merge strategies, patches, branches, etc. * Agreed to merge regularly * **Bert agreed to monitor the situation and propose a merge strategy when the time is right** ### Next meeting * Agreed to meet again on the 7th of January UTC * Agreed to have mini-stand-up at the beginning of each meeting node-v4.2.6/doc/tsc-meetings/io.js/2015-01-07.md000644 000766 000024 00000016517 12650222326 020524 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-01-07 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=hWDSToC9EV8 * **GitHub Issue**: https://github.com/nodejs/io.js/issues/230 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1j7Sdui5DqHE8GZHxuoAaoIQ4jlntacZI285OCfVa-Eo ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * Invite Colin Ihrig to the TC #223 https://github.com/nodejs/io.js/issues/223 * File copyright policy #216 https://github.com/nodejs/io.js/issues/216 * Doc: clarified & split up contribution docs #233 https://github.com/nodejs/io.js/pull/233 * Governance: Add new Collaborators #234 https://github.com/nodejs/io.js/issues/234 * deps: upgrade v8 to 3.31.74.1 #243 https://github.com/nodejs/io.js/pull/243 * Build * Intl - defaults * Merge v0.10 * npm upgrade _(did not get to this)_ ## Minutes ### Present * Bert (TC) * Ben (TC) * Chris (TC) * Fedor (TC) * Isaac (TC) * Colin (for voting as addition to TC) * Mikeal * Rod (facilitator) ### Mini stand-up * ben: integrating tick processor, rename binary to “iojs”, upgrade v8, and plenty of libuv features/bug fixes. * bert: libuv: readdir on windows, build with clang, plan for next unstable libuv, use similar ev loop impl on windows as unix first tentative patches available for review. * chris: streams - solving failure on v1.x branch for npm, zlib patch breaks stuff, streams visualization stuff doc/writeup of node streams and whatWG streams * fedor /few-dir/: no updates, working on non-iojs stuff and holidays * colin: triaging issues in io.js and joyent/node. helping with merge of 0.12 to 0.10 * isaac: no io.js, vacation * mikeal: nada * rod: build build build ci ci ci. re-did all the build slaves on Jenkins, introduced a bunch more. Ansible scripts for linux machines (CentOS 5,6,7, Ubuntu all LTS + Current 14.10 +32bit versions, 2 ARM v7s one virtual one physical, 2 of each Windows 2012,2008, a couple interim OS X machines more permanent ones coming from Voxer soon). https://github.com/nodejs/build Still lacking specific Jenkins setup and secrets. Working on release process. mikeal: issue re release? rod: not yet, a lot of little bugs to get CI working consistently. No grand plan for what’s in release yet. ### Review of last meeting * sys: Remove after 3 years of deprecation #182 * module: force require('process') to return a reference to process #206 * File copyright policy #216 * Rename v0.12 to v1.0.0 * Merge strategy (v0.10 and joyent/node) ### Invite Colin Ihrig to the TC #223 https://github.com/nodejs/io.js/issues/223 Asked for vote Passed unanimously Some discussion about TC member addition process ### File copyright policy #216 https://github.com/nodejs/io.js/issues/216 * Rod: got feedback from NodeSource GC on this, recommendation is to keep the copyright but removal of the license notice is acceptable * Mikeal & Isaac: removing the copyright should be OK because we have full git record of who made & edited the file, it’s a PITA * Asked for vote on removing copyright and license from the top of each source file, moving it a single top level file. **Nobody objected**. * Agreed to table further discussion on modifying the license and copyright. * isaacs will submit PR to remove license blocks from files. ### Doc: clarified & split up contribution docs #233 https://github.com/nodejs/io.js/pull/233 * Rod: discussed changes introduced in #233, this is in TC because there are some minor modifications to the governance structure. Recommended that we deal with further changes to governance as a separate discussion. * Fedor: remove caine block from CONTRIBUTING.md * Mikeal: take PR as is, move the rest to further discussion & PR * No objections, agreed to move changes to governance and other adjustments such as moving docs into the docs dir to separate pull requests. * Isaacs and Chris will review and +1 the PR. ### Governance: Add new Collaborators #234 https://github.com/nodejs/io.js/issues/234 Rod discussed the generation of the list of proposed collaborators. Long discussion: * Isaacs, Chris, Bert suggest throttling new contrib additions to 5/week, bump up to 10/week if it goes well, etc. * Ben 50/50 on “add everyone now” or “throttle new additions” * Bert to review list and see if there’s any contributors that seem we should not add. * Other TC members can review list this week. * Two issues to vote on at next TC meeting - Issue 1: a. Add everyone b. Add everyone except some that are not added - Issue 2: a. Create a queue of people to add, throttle per week b. Add immediately ### deps: upgrade v8 to 3.31.74.1 #243 https://github.com/nodejs/io.js/pull/243 * Ben: clean compile, apparently a clean upgrade. It does break postmortem support so Ben removed it completely. Asked who was using it. * Ben: adds new features: - numeric literals - string methods - block scoping - classes (strict mode) - object literal extensions - template literals. * Fedor: Voxer using postmortem support, so it’s not just Joyent. Would prefer to fix it. * No disagreement about merging this. * Ben and Fedor to take discussion about details to GitHub. ### Build & release Rod rambled on about build & release: * Lots of minor test failures to take care of and make sure there are no serious blockers: https://jenkins-iojs.nodesource.com/job/iojs+any-pr+multi/ * is osx 32-bit necessary? group agreed to leave it out. * binary naming: Ben currently taking care of renaming, Bert will help out with a solution for windows * release blobs: - source - windows 32, 64 - osx 64-bit, built on 10.10 - specify minimum requirement in XCode (apparently) - linux, centos 5, libstdc++ static - Ben says we shouldn't have to, although Rod found it necessary when built with Debian Weezy, give Ben access to CentOS box to try it out - linux armv7 (built on Ubuntu 14.04) (perhaps armv6 for rpi, but compile should not hold up a release--drop in later?) - Windows bare files, Bert explained the files currently released in nodejs.org/dist/*/ - node.lib downloaded by node-gyp for compile - node.pdb contains debug information (may not be needed, not used by the group, perhaps someone asked for it?), leave it out - node.exe is useful where an .msi is a problem to run (no admin access) - Rod proposed to move to a .zip for these for 32 and 64, but this may be a problem to get ready for release, discuss further with Bert * Version number - all agreed to go with 1.0.0, but it should be clearly labeled as an initial “beta”-type release for the project. * Website for blog/announce/news, Rod proposed Mikeal take responsibility for now until we find a better owner / team, Mikeal agreed. * Dist folder structure - Agreed to keep iojs.org/dist/ to mirror nodejs.org/dist, other things via symlinks and html hyperlinks. - Maybe have a iojs.org/downloads/v1/1.0.0/… and perhaps a text/html thing with links to each relevant release * Bert: Node still merging in 0.10 to 0.12, is there anything that should be merged in 0.10 that we really need? * intl: Bert kind of hates this patch. joyent/node is moving towards building with small icu, you get intl object, but only supports english. CAN build with another icu to add other intls. Bert to open an issue to discuss further. May leave out ICU completely from 1.0.0. ### Next meeting * Bring a day forward to bless a release, i.e. 2015-01-13 node-v4.2.6/doc/tsc-meetings/io.js/2015-01-13.md000644 000766 000024 00000011663 12650222326 020516 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-01-13 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=Z0KHYPlFI3E * **GitHub Issue**: https://github.com/nodejs/io.js/issues/300 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1HDUayYxTjolYZhu_hGm9hc-6MGAwWrHlNGT2Zo708ck ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * File copyright policy #216 https://github.com/nodejs/io.js/issues/216 * governance: Add new Collaborators #234 https://github.com/nodejs/io.js/issues/234 * The state of ES6 on io.js _(re V8 upgrade policy)_ #251 https://github.com/nodejs/io.js/issues/251 Quick recap: - Whether if it is ok to release 1.0.0 with V8 3.31.74 minus ES6 Classes and Object Literals Extensions, considering that the initial version of io.js will be "beta" quality and probably the stable version will coincide with the stable release of V8 3.31 (~6 weeks), which will have these features reinstated. - How to handle V8 updates with semver so that if the same issue arised with a different timing it could mean a bump to 2.0.0. - Community suggestions: * Different version naming (e.g. 1.x+v8beta, 1.x+v8dev, 1.x+v8canary) * Avoid BC by moving from tip-of-stable-Chrome-branch to the next tip-of-stable-Chrome-branch (~6 weeks release cycle) - How do nightly builds fit into the process. * 1.0.0 release checklist https://github.com/nodejs/io.js/issues/302 ## Minutes ### Present * Trevor (TC) * Chris (TC) * Ben (TC) * Bert (TC) * Rod (facilitator) ### Mini stand-up * Ben: 1.0.0 work * Bert: 1.0.0 work (and other things) * Chris: Docs mainly, made a new repo for it * Trevor: Stuff * Rod: tons of 1.0.0 release prep work, tidying up test slaves, preparing fresh release slaves and configuring release builds & installers ### Review of last meeting * Invite Colin Ihrig to the TC #223 https://github.com/nodejs/io.js/issues/223 * File copyright policy #216 https://github.com/nodejs/io.js/issues/216 * Doc: clarified & split up contribution docs #233 https://github.com/nodejs/io.js/pull/233 * Governance: Add new Collaborators #234 https://github.com/nodejs/io.js/issues/234 * deps: upgrade v8 to 3.31.74.1 #243 https://github.com/nodejs/io.js/pull/243 * Build & release (& Intl) ### File copyright policy #216 https://github.com/nodejs/io.js/issues/216 Rod: prepared a proposed new LICENSE file, needed for release, adds a new license block for io.js at the top, shifts the Joyent copyright block down but still acknowledges their claim on inherited work. https://github.com/nodejs/io.js/pull/294 Group agreed to merge for now until a better (or more legally appropriate) solution is proposed. ### governance: Add new Collaborators #234 https://github.com/nodejs/io.js/issues/234 Rod asked if we should punt to next meeting since the group was small and we’re 1.0.0 obsessed. Group agreed. ### The state of ES6 on io.js _(re V8 upgrade policy)_ #251 https://github.com/nodejs/io.js/issues/251 Rod: this is about V8 version matching and V8 version stability. We’re going live with 3.31. Discussion with the V8 team suggests that 3.31 is probably not appropriate because of stability concerns. We have already had to disable class support because the V8 team announced their intention to disable it in the next release anyway. Group agreed to stick with 3.31, too late to do otherwise. Come up with a more solid stability policy later. ### v1.0.0 release checklist https://github.com/nodejs/io.js/issues/302 * Rod will land LICENSE change after meeting * Bert spoke about the v0.10 and the things that remain unmerged - abort on uncaughtException for domains not landed, so may be missed; feature used by Hapi / Walmart Labs for postmoretem debugging - private buffer object patch not landed, repl will crash if you do this currently - sslv2 & sslv3 fixes -- we have agreed to disable these completely - re timers slowness - Bert and Ben don’t like the 0.10 fix, need to find our own - not landing in 1.0.0, probably our own fix in 1.0.1 * Bert spoke about node.exe, has code for it but it’s crashy, could release with a symlink for 1.0.0. Asked for input on the approach. * Discussed node-gyp - Ben to PR node-gyp (and maybe land a modified version in io.js codebase) for iojs.org/dist/vx.y.z/... for source tarball. - discussed process.versions.iojs property, https://github.com/nodejs/io.js/issues/269 - group agreed to do nothing on this. Rod to find discussion or create issue to have discussion on this. - discussed visual assets not being in the repo, currently copied by CI manually into src, Rod to land a PR with them * Rod: Changelog, we don’t have one. - https://github.com/joyent/node/wiki/API-changes-between-v0.10-and-v0.12 - Rod: is it a blocker? Ben: not per-se but very good to have. - Rod: proposed to come up with something on GitHub and ask for people to take work. Trevor will do Buffer, Chris streams, Bert child processes. ### Next meeting * Back to normal schedule next week node-v4.2.6/doc/tsc-meetings/io.js/2015-01-21.md000644 000766 000024 00000015764 12650222326 020523 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-01-21 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=OUoWlIshY9s * **GitHub Issue**: https://github.com/nodejs/io.js/issues/509 * **Original Minutes Google Doc**: https://docs.google.com//document/d/1yOS17cUt7QUHJXxdVmEpS1ZS_N32HMO9QTHb2qL-KHk ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * Invite Domenic Denicola to the TC Meetings (https://github.com/nodejs/io.js/issues/403) * Governance: Add new collaborators (https://github.com/nodejs/io.js/issues/234) * Stabilization and Release Cycles and Process (https://github.com/nodejs/io.js/issues/405) * also: the state of ES6 on io.js (re: V8 upgrade policy) (https://github.com/nodejs/io.js/issues/251) * doc: bump punycode api stability to ‘stable’ (https://github.com/nodejs/io.js/issues/470) * Working group reports * Streams * Website * ICU ## Minutes ### Present * Bert (TC) * Ben (TC) * Chris (TC) * Colin (TC) * Fedor (TC) * Isaac (TC) * Mikeal * Rod * Domenic ### Mini stand-up * Bert: Release, polish, Windows installer, Windows XP, ICU * Ben: Fixing bugs, reviewing PRs, maintenance * Chris: Cleaning up points where core reaches in to private state of streams, TLS bug with New Relic * Colin: Reviewing PRs, moving vars to ES6 consts * Fedor: Commenting, working on replacement for GYP, written in C: https://github.com/indutny/pyg * Isaac: npm stuff, some streams discussing * Mikeal: Website WG, social media accounts, facebook, G+, etc. * Domenic: Changelog & Release, clarifying V8 stuff * Rod: Release, etc. ### Review of last meeting * File copyright policy #216 - LICENSE file * governance: Add new Collaborators #234 - Deferred to this meeting * The state of ES6 on io.js _(re V8 upgrade policy)_ #251 - Only discussed V8 upgrade policy, re 3.31 vs 3.30 * 1.0.0 release checklist ### Invite Domenic Denicola to the TC Meetings (https://github.com/nodejs/io.js/issues/403) Enough agreement on GitHub and in private communications amongst TC. **Done.** ### Governance: Add new collaborators (https://github.com/nodejs/io.js/issues/234) * Mikeal: Proposed Chris leads an onboarding process, do a Hangout with a group of people from the original list who are willing to go through the process and take them in the first week and iterate from there. * Bert: +1 for an onboarding process, more interested in handing out voting rights to a larger group. * Mikeal: Would rather separate the voting rights issue from adding contributors, make a separate issue for this with ideas and come back to it at next meeting. * Ben: is an onboarding process necessary? New contributor should pick it up fairly quickly. * Chris: How we review code and deal with issues (cultural things) is hard to get across with just a written process. * Isaac: Basically apprentice model for joyent/node but faster and more inclusive. Some brief instruction on how to do things. * Mikeal: adding collaborators gives us an informal voting process, +/-1s on issues with the “collaborator” badge * Bert: would like to widen and formalise the voting process * Mikeal: wants to tackle the issue by bringing org to the roadmap repo, will bring Bert in on the process Discussed whether onboarding should be mandatory. Proposal: **take anyone proposed that +1s in that thread, mandatory onboarding process by Chris, limited by how many he can take.** Passed ### Stabilization and Release Cycles and Process (https://github.com/nodejs/io.js/issues/405) #### V8 * Mikeal: - how to align with V8 process and increase collaboration - semver + V8 introduces some challenges * Domenic: V8 is synced to Chrome releases, Beta should ship with the version that ships with release * Ben: is the proposal to stick with stable V8 release that’s in stable Chrome? * Domenic: ideally some “beta” version of io.js that uses a Beta V8 * Mikeal: we need more releases to get experience with this, assumption is that at some point we say “this is stable” and have a stable and unstable branch. * Discussed current release patterns, how they map to minor/patch * Domenic: we are in a “danger zone” * Mikeal & Domenic discussed how you might achieve a “canary” * Bert: proposal: - io.js track stable V8, bump minor and possibly major as required - have a pre-release that tracks the Beta * Domenic: would like to keep V8 version upgrades as a separate concern to other experimental additions to io.js, decouple from io.js releases / semver? * Ben: happy with stable proposal, want to move discussion on unstable to an issue for further discussion. * Action: **Ben file an issue to discuss how unstable works** * **Agreement: V8 should track stable** #### Logo * Discussed logo-per-release * Mikeal: we need a versatile logo to use across all web / social presences. Having a logo to designate a release would be good. * Mikeal: ideally website team would like JSON file containing release info to be checked in to the website repo upon completion. #### Releases * Rod: patch releases should be frequent, there have been 4 so far, it seems to be working well but we should monitor * Domenic: frequent releases should be normal, patch & minor should just be part of the normal process * Bert: would be good to have API change notes into the git log * Discussed further about how to deal with API changes minor/major, unstable branches, etc. * **Agreement: patch and minor releases are merged as part of normal business, a release then is either a patch or minor bump depending on what was merged.** * Move discussion about tagging vs git log recording for patch/minor/major to GitHub. * **Punt on discussions about who can release and how that happens** * **Punt on discussions about synchronizing with important ecosystem projects (NAN, node-gyp, nvm, etc.)** ### also: the state of ES6 on io.js (re: V8 upgrade policy) (https://github.com/nodejs/io.js/issues/251) Part of previous discussion ### doc: bump punycode api stability to ‘stable’ (https://github.com/nodejs/io.js/issues/470) * **Agreement** ### Working group reports * Mikeal and Chris to semi-formalise the model * Mikeal: 6 people actively engaged and growing, “could not be going better” * Chris: streams group has initial set of members, some discussions going on, first meeting pending * initial set of members: https://github.com/nodejs/readable-stream/issues/97#issuecomment-70399923 * Rod: - The Docker sub-group is going great and has even got the docker-iojs images accepted as the official Docker "iojs" images. - Other "build" efforts are all release-focused for now, trying to streamline the process to make it possible to have multiple people able to cut releases. ### ICU * Bert: - joyent/node has small-icu enabled by default making `Intl` work - can get it working but it makes the binary twice as big (~8M more) * Domenic: ideally we would track browsers and just include it * Ben: V8 adds ICU by default but you need to opt-out, which we do * Action: **Invite Steven Loomis to the next TC meeting to discuss further** ### Next meeting * 28th January 2015 node-v4.2.6/doc/tsc-meetings/io.js/2015-01-28.md000644 000766 000024 00000020272 12650222326 020520 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-01-28 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=k27NObxy0ps * **GitHub Issue**: https://github.com/nodejs/io.js/issues/565 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1IIfubVivCORgP0nQfo8Mf4gXhwBrndRm9cwmNGBXmtE ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * governance: Add new Collaborators [#234](https://github.com/nodejs/io.js/issues/234) / feedback and more contribs / @chrisdickinson * Stabilization and Release Cycles and Process [#405](https://github.com/nodejs/io.js/issues/405) / further discussion / @iojs/tc - doc: add releases document detail release cycle [#630](https://github.com/nodejs/io.js/issues/630) / proposal from @chrisdickinson * dgram: implicit binds should be exclusive [#325](https://github.com/nodejs/io.js/issues/325) / minor version bump / @bnoordhuis * buffer: implement `iterable` interface [#525](https://github.com/nodejs/io.js/issues/525) / minor version bump / @bnoordhuis * replace util.isType() with typeof [#607](https://github.com/nodejs/io.js/issues/607) / general use of util.is*() in core re perf * docs: lower the maximum stability level to "stable" [#633](https://github.com/nodejs/io.js/pull/633) * maintain our own package registries for io.js related packages [#640](https://github.com/nodejs/io.js/issues/640#issuecomment-71882645) * Working Groups PR [#599](https://github.com/nodejs/io.js/pull/599) * Remove “unstable” from messaging [#108](https://github.com/nodejs/website/issues/108) ## Minutes ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Colin (TC) * Fedor (TC) * Isaac (TC) * Mikeal * Rod Apologies from: * Trevor (TC) * Domenic ### Mini stand-up * Ben: Reviewed/landed pull requests, fixed bugs, the usual * Bert: Same as Ben, but not as much * Chris: On-boarding stuff * Colin: * Fedor: working on pyg (gyp alternative in C) * Rod: ARMv6 builds, fixing persistent bug on Ubuntu 10.04, yay! * Isaacs: Only doing npm CEO stuff * Mikeal: social media stuff for io.js, PR, roadmap, feedback from Big Cos. ### Review of last meeting * Invite Domenic Denicola to the TC Meetings (https://github.com/nodejs/io.js/issues/403) * Governance: Add new collaborators (https://github.com/nodejs/io.js/issues/234) * Stabilization and Release Cycles and Process (https://github.com/nodejs/io.js/issues/405) * also: the state of ES6 on io.js (re: V8 upgrade policy) (https://github.com/nodejs/io.js/issues/251) * doc: bump punycode api stability to ‘stable’ (https://github.com/nodejs/io.js/issues/470) * Working group reports * Streams * Website * ICU ### governance: Add new Collaborators [#234](https://github.com/nodejs/io.js/issues/234) / feedback and more contribs / @chrisdickinson * Chris: Onboarded 2 groups of 4 new collaborators last week. (first group: @vkurchatkin, @micnic, @seishun, @brendanashworth, second group: @evanlucas, @Fishrock123, @Qard, @thlorenz) - 30 min summary of how everything works, gov, git, etc. - took exit poll to get reactions - notes here: https://gist.github.com/chrisdickinson/80df88b9089c19e0459e * Rod: how do we iterate? * Chris: Do it again next week with ~4 more * Discussed timezones and how that works ### Stabilization and Release Cycles and Process [#405](https://github.com/nodejs/io.js/issues/405) / further discussion / @iojs/tc ***Also:*** doc: add releases document detail release cycle [#630](https://github.com/nodejs/io.js/issues/630) / proposal from @chrisdickinson Moved straight to Chris’ proposal: * Chris discussed thoughts in his proposal @ https://github.com/nodejs/io.js/issues/630 * Mikeal: would rather not have a static number/list of supported versions, let that be dynamic as people & companies step up to help support them * Ben: “stable” and “next” would be easiest to reason about * Chris: “dev” is for ad-hoc semver releases, replaces nightlies with a better train system. * Chris: branches will be “master” - development happens here, maintain “v1.x”, “v2.x” etc. for major releases. Ideally LTS would be from major versions. * Fedor asked about communication to users and how much fragmentation this would cause * Ben: how do you keep the delta between dev and stable from getting too big * Chris: at most there would be a 2-week lag between something hitting dev and something going out on stable * Bert: suggested that we need a better batching mechanism, particularly for breaking changes, so we’re not constantly bumping major. ### dgram: implicit binds should be exclusive [#325](https://github.com/nodejs/io.js/issues/325) / minor version bump / @bnoordhuis * Ben: this is about minor version bump, that’s been decided and we’re doing a 1.1.0 so this is being merged and released ### buffer: implement `iterable` interface [#525](https://github.com/nodejs/io.js/issues/525) / minor version bump / @bnoordhuis * Ben: same as previous issue, resolved ### replace util.isType() with typeof [#607](https://github.com/nodejs/io.js/issues/607) / general use of util.is*() in core re perf * Bert: find with direct comparisons and checks where it makes sense (undefined, simple stuff) * Isaac: hate it all, they are difficult to inline so manually inline--pick one and use it across all * Colin: working on a PR to do the replacement already * Chris volunteered to PR a style-guide into docs * Isaac: better linter would be great ### Doc-tool - Should we merge with the joyent/node version? * Isaac: Robert Kowalski reached out to me to ask about this. - Seems silly to have two nearly-identical tools for this. - Delegate to doc working group? - Suggested that he just pick one from io.js or joyent/node and send a PR for that * Mikeal: Website WG is meeting next week, will pull in Robert to that discussion ### docs: lower the maximum stability level to "stable" [#633](https://github.com/nodejs/io.js/issues/633) * General disagreement about this * Mikeal suggested moving things that are likely to change into vendored packages (like streams) * Motivation was to set some things (frozen/locked) as unchangable because they would break too much stuff * Bert: we effectively have 4 levels: strict-deprecation, soft-deprecation, moving, pretty-much-done * Mikeal: proposed punting this for a few weeks * Isaac: the labels are useful for guiding people on where best to contribute and where to not bother ### maintain our own package registries for io.js related packages [#640](https://github.com/nodejs/io.js/issues/640) * Mikeal: each distro (Homebrew, Debian, etc.) has their own conception of “stable”, suggestion is to maintain them under io.js and instruct people how to do this. e.g. using our own custom Homebrew end-point and instruct people how to use it with `brew`. Also could bring in complicated packages from the community. * Mikeal: Should come under the Build WG for now, ideally a single repo where external projects can put in a single PR to update their stuff. ### Working Groups PR [#599](https://github.com/nodejs/io.js/issues/599) * Mikeal introduced his proposal: if you’re going to do the work in a WG then you can spin that up as a separate concern * Ben asked for clarification about whether WGs get a free-pass in core - Mikeal: no, they are isolated from core * Rod: clarification about relationship to TC - TC has charter-revocation powers, beyond that they don’t have control over the activities of a WG * Consensus reached, Mikeal will put in the suggested fixes (in the PR) into the docs and merge ### Remove “unstable” from messaging [#108](https://github.com/nodejs/io.js/issues/108) * Remove “unstable” from the website but not say it’s “stable” * Bert: big +1, use semver, don’t try and message something else, only concern is the version of V8 we are using * Discussed V8 4.1 and how “stable” it is ### Node.js and io.js should not break each other (no, they shouldn't) [#631](https://github.com/nodejs/io.js/issues/631) Rod brought this up for quick discussion and draw attention to TC members for possible input. * Mikeal suggested that this should be taken to the website WG for better documentation ### Working group reports * Streams - first WG meeting this week * Website - meeting next week ### Next meeting * 4th of February node-v4.2.6/doc/tsc-meetings/io.js/2015-02-04.md000644 000766 000024 00000011624 12650222326 020514 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-02-04 ## Links * **Google Hangouts Video**: http://www.youtube.com/watch?v=k27NObxy0ps * **GitHub Issue**: https://github.com/nodejs/io.js/issues/509 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1IIfubVivCORgP0nQfo8Mf4gXhwBrndRm9cwmNGBXmtE ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * assert: don't compare object `prototype` property [#636](https://github.com/nodejs/io.js/pull/636) _and_ assert: introduce `deepStrictEqual` [#639](https://github.com/nodejs/io.js/pull/639) / @vkurchatkin * Release PGP key strategy and policy [#709](https://github.com/nodejs/io.js/issues/709) * If time: vm bugs? [#548](https://github.com/nodejs/io.js/issues/548), [joyent/node#9084](https://github.com/joyent/node/issues/9084) ## Minutes ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Colin (TC) * Fedor (TC) * Isaac (TC) * Trevor (TC) * Mikeal * Domenic * Rod ### Mini stand-up * Bert: Lots of commenting, still working on ICU, investigating binary size and memory size minimisation, playing with transforming the data to C * Chris: Integrating ESLint, held first Streams WG meeting * Colin: Issues and codez, removed all util.is type functions * Isaac: “Real job” stuff * Domenic: Streams WG * Mikeal: Starting Tracing WG, lots of org stuff, roadmap work, early feedback from reaching out to companies is that there is concern about version number conflict between io.js and Node, and debugging/tracing. * Trevor: moving house, tracing * Rod: build collaboration stuff ### Review of last meeting * governance: Add new Collaborators [#234](https://github.com/nodejs/io.js/issues/234) / feedback and more contribs / @chrisdickinson * Stabilization and Release Cycles and Process [#405](https://github.com/nodejs/io.js/issues/405) / further discussion / @iojs/tc - doc: add releases document detail release cycle [#630](https://github.com/nodejs/io.js/issues/630) / proposal from @chrisdickinson * dgram: implicit binds should be exclusive [#325](https://github.com/nodejs/io.js/issues/325) / minor version bump / @bnoordhuis * buffer: implement `iterable` interface [#525](https://github.com/nodejs/io.js/issues/525) / minor version bump / @bnoordhuis * replace util.isType() with typeof [#607](https://github.com/nodejs/io.js/issues/607) / general use of util.is*() in core re perf * docs: lower the maximum stability level to "stable" (https://github.com/nodejs/io.js/pull/633) * maintain our own package registries for io.js related packages (https://github.com/nodejs/io.js/issues/640#issuecomment-71882645) * Working Groups PR (https://github.com/nodejs/io.js/pull/599) * Remove “unstable” from messaging (https://github.com/nodejs/website/issues/108) * Node.js and io.js should not break each other (no, they shouldn't) * Working group reports ### assert: don't compare object `prototype` property _and_ assert: introduce `deepStrictEqual` / @vkurchatkin @vkurchatkin questions: * the future of assert module; * relationship between assert and CommonJS Unit Testing spec; * particular #636 bug; * what "deep equality" means and how it should deal with prototypes; * [#639](https://github.com/nodejs/io.js/pull/639) proposal * Isaac: CommonJS is gone & dead, good ideas have to stand on their own * Mikeal: assert probably shouldn’t be in core * Isaac: it’s useful for testing Node itself and useful for runtime asserts * Rod asked if anyone had any objections to the changes because perhaps Validmir should just be given a blessing to go ahead and improve it. * Domenic: medium risk, low reward, perhaps slate this for a 2.0 release. * Lots of discussion about the technical merits * Ben: the `a.prototype !== b.prototype` is clearly a bug in the initial implementation, it should have been checking `__proto__` * Rod: new deepStrictEqual() does that check properly Conclusion: accept both of - [#636](https://github.com/nodejs/io.js/pull/636) - [#639](https://github.com/nodejs/io.js/pull/639) (Contrast #636 with [#621](https://github.com/nodejs/io.js/pull/621), which is a more ambitious change and probably not a good idea.) 1. deepEqual = No prototype checking 2. deepStrictEqual = proper prototype checking Passed without objection ### Release PGP key strategy and policy / @rvagg [#709](https://github.com/nodejs/io.js/issues/709) * Rod summarised how the current release key strategy works and is documented on the README. Asked for feedback on: - Which keyserver(s) to use - Whether to go with a master/sub key design for the project * No strong opinions, nothing actionable here ### VM bugs? [#548](https://github.com/nodejs/io.js/issues/548) / @domenic [joyent/node#9084](https://github.com/joyent/node/issues/9084) * Domenic introduced #548, some odd VM bugs that seem to be V8 bugs, * Isaac encouraged Domenic to follow this up with the V8 team to get feedback on how this works ### Next meeting * Skipping a week due to Node Summit * Feb 18th 2015 node-v4.2.6/doc/tsc-meetings/io.js/2015-02-18.md000644 000766 000024 00000020334 12650222326 020517 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-02-18 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=jeBPYLJ2_Yc * **Google Plus Event page**: https://plus.google.com/events/ccrkam8uup1k8qbo0fmcea0n2v4 * **GitHub Issue**: https://github.com/nodejs/io.js/issues/509 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1JnujRu6Rfnp6wvbvwCfxXnsjLySunQ_yah91pkvSFdQ ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * util: fixed behavior of isObject() [#822](https://github.com/nodejs/io.js/issues/822) / @chrisdickinson / major version release * Translate installers for OS X and Windows [#819](https://github.com/nodejs/io.js/issues/819) / @rvagg / maintenance overhead * lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * Implement unhandled rejection tracking [#758](https://github.com/nodejs/io.js/issues/758) / @rvagg / how can we help this land * Logo / Brand Treatment [website/181](https://github.com/nodejs/website/issues/181) @ mikeal https://www.behance.net/gallery/23269525/IOJS-logo-concept * Stability Policy/Statement & Roadmap [#725](https://github.com/nodejs/io.js/issues/725) / @mikeal [roadmap/14](https://github.com/nodejs/roadmap/issues/14) / @mikeal ## Minutes ### Present * Bert (TC) * Chris (TC) * Colin (TC) * Isaac (TC) * Trevor (TC) * Mikeal * Domenic * Rod * Apologies for Ben and Fedor ### Mini stand-up * Bert: NodeSummit and company stuff, Windows io.js stuff * Chris: styleguide work, wrangling ESLint, slow week * Colin: busy with work, porting joyent/node work to io.js * Domenic: having fun with VM stuff in jsdom, have a release coming soon * Rod: not as much as usual, preparing for 1.3.0 * Isaac: Node Summit, npm stuff * Mikeal: i18 groups, >160 new people doing translations, press inquiries because of Node Foundation news, lots of website stuff (i18n & build), roadmap and stability * Trevor: Some critical stuff on joyent/node, work, moving house ### Review of last meeting * assert: don't compare object `prototype` property _and_ assert: introduce `deepStrictEqual` / @vkurchatkin * Release PGP key strategy and policy / @rvagg * VM bugs? [#548](https://github.com/nodejs/io.js/issues/548) / @domenic ### util: fixed behavior of isObject() [#822](https://github.com/nodejs/io.js/issues/822) / @chrisdickinson / major version release * Chris: Requires semver-major, what’s the vibe on bumping major at this stage? * Chris: isObject() would now return true when checking for functions * Mikeal: interested in separating “things that break” and “API breakage” * Chris: consider this a “fix” but is also an API change that could break people’s downstream code * Isaac: probably want to put off a 2.x release until we have more substantial changes, not to wait for 2 years but have some time frame, like 6 months * Bert: messaging is off for a 2.0 bump just for this * Domenic: versions shouldn’t mean the same as they used to, major version bumps should be more casual * Rod: are we stopping saying that this is compatible with “Node”? * Mikeal: compatible with past-Node, not joyent/node 0.12+ because we have no control over that * Mikeal: release channels - standard semver & canary which is everything else * Chris: +1 for release channels, but not so much on substance of the proposal. * Rod: concerned about the emotional energy we’re still investing in version numbers when we should be just doing semver * Mikeal: ignore version numbers, have a “canary” type branch and start releasing on that until we’re confident to merge back in * Chris: difference between Mikeal’s proposal and the original proposal is having a “canary” branch that stuff gets merged in to and eventually is merged in to master, original proposal merged new stuff in to master and used the time delay as “canary” (like Chrome) * Rod: proposal is to tag this issue as a milestone for now and punt until we have more substantive changes - no disagreements, passed ### Translate installers for OS X and Windows [#819](https://github.com/nodejs/io.js/issues/819) / @rvagg / maintenance overhead * Rod: concern here is the maintenance overhead in keeping all of the translations in sync, are we happy to have that headache in core? * Mikeal: let English be the default and let the translation teams be responsible for watching for changes and making updates as appropriate * Bert: installer framework is largely out of our control for how the mechanics of translations and fallbacks work, -1 on this because it’s just an installer and there are probably better targets for translation * Mikeal: the translation teams will prioritise for themselves what gets translated. * Domenic: enable the community as long as it doesn’t add friction * Bert: if there is no technical issue then OK with landing this, the responsibility for translation will have to be with that community * Resolution: allow this to land unless there are going to be technical blockers to future installer changes needing to wait for translations to be updated ### lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * Ben’s issue, punt till next meeting, note in “known issues” for releases ### Implement unhandled rejection tracking [#758](https://github.com/nodejs/io.js/issues/758) / @rvagg / how can we help this land * Rod: Brought to TC to get some more engagement and help get this landed unless there are any major objections * Domenic: PR looks good, it’s mainly a matter of code quality, doesn’t add any default handlers which is a good incremental way of adding this * Trevor discussed concerns about how V8 runs the events, synchronously vs on the micro-task queue * Trevor: OK with the change because there is almost no overhead if you’re not using Promises or this event, concerned about the disconnect between the V8 API vs what we expect it to be--the PR compensates for V8 behavior. * Domenic: user-exposed semantics of this PR are good * Mikeal: concerned about behavior change in the future leading to a * Rod: proposed resolution is to give the TC’s blessing to that PR for it to land when everyone in there is happy with it - No objections ### Logo / Brand Treatment [website/181](https://github.com/nodejs/website/issues/181) @ mikeal https://www.behance.net/gallery/23269525/IOJS-logo-concept * Mikeal discussed the proposed website changes and logo choice @ https://www.behance.net/gallery/23269525/IOJS-logo-concept * Some discussion about choice of logo, no strong opinions on design * Rod: may be best to let the website group make this choice because they are more qualified from a design perspective * Chris: design group could be asked to come up with a few options and present them for selection * Mikeal: design by committee sucks, everyone knows this * Chris: can we come up with some standards and assert them ack to designers - such as number of colors, needs to look good at 16x16 all the way up * Rod: maybe this group isn’t qualified to even do that, perhaps push it on to the WG * Discussion on the process of selecting a logo and brand treatment * Agreed to delegate to the website WG to make this decision ### Stability Policy/Statement & Roadmap [#725](https://github.com/nodejs/io.js/issues/725) / @mikeal [roadmap/14](https://github.com/nodejs/roadmap/issues/14) / @mikeal * Mikeal: none of this is fixed in stone, we can change it in the future if we decide it won’t work - one change still to go in is that the wording on stability should be that “we won’t remove an API” - people are terrified that we’re going to break compatibility and go off in new directions, this is a way of dealing with that * Bert: concerned about this being a reflection of the way we work rather than enforcing new behaviors * Discussion around breaking / removing APIs and how firm this policy is going forward * Rod asked for specific things that need to be resolved now vs punting to a later meeting * Mikeal: https://github.com/nodejs/roadmap/commit/190690a1b5f206c22f64adc3d29d10c4b08cb8cd * Group discussed presentations, no major objections so the blessing was given for Mikeal to move forward with ratifying that, expect further discussion on the broader topic next meeting. ### Next meeting * Next week, 25th Feb 2015 node-v4.2.6/doc/tsc-meetings/io.js/2015-03-04.md000644 000766 000024 00000020050 12650222326 020506 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-03-04 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=vxX2CkFPEtk * **Google Plus Event page**: https://plus.google.com/events/c9ijr7edl14im7dspk5njktmjq4 * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1053 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1RoIE68l8B2iWLdEPM7ApSN2FxFDd3OY0wfTeqUh-K9w ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * iojs: introduce internal modules [#848](https://github.com/nodejs/io.js/issues/848) / @chrisdickinson / @trevnorris / (@vkurchatkin) * url: significantly improve the performance of the url module [#933](https://github.com/nodejs/io.js/issues/933) / @mikeal * Ship websockets in core [#1010](https://github.com/nodejs/io.js/issues/1010) / @piscisaureus * RFC: upgrade to V8 4.2? [#1026](https://github.com/nodejs/io.js/issues/1026) / @bnoordhuis * Colin resigning from TC [#1056](https://github.com/nodejs/io.js/pull/1056) ## Minutes ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Domenic * Fedor (TC) * Mikeal (meeting lead) * Isaac (TC) * Trevor (TC) * Rod ### Mini stand-up * Ben: PRs, bugs, perf improvements, same old awesome Ben * Bert: talking, child process bugs, looking further in to Windows bugs that are still outstanding, no coding * Chris: reviewing PRs, onboarding Julian, Christian, Brian, Robert, Ben. Code for core module discovery / use in packages in npm. * Domenic: Streams work WHATWG sync with io.js streams ideas. * Fedor: fixing bugs, PRs * Isaac: coding for fun, node-tap rewrite, global/window alias discussions, node_modules flattening, Windows stuff. Looking in to TLS issues for io.js and 0.12, TLS over Pound causes problems, possibly OpenSSL problem. * Mikeal: Website and Evangelism WG work, lots of new collabs and work, getting things in sync * Rod: Releases, Windows bug / Jenkins drama, ARMv8 support * Trevor: Buffer.indexOf(), nextTick perf improvement ### Review of last meeting * util: fixed behavior of isObject() [#822](https://github.com/nodejs/io.js/issues/822) / @chrisdickinson / major version release * Translate installers for OS X and Windows [#819](https://github.com/nodejs/io.js/issues/819) / @rvagg / maintenance overhead * lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * Implement unhandled rejection tracking [#758](https://github.com/nodejs/io.js/issues/758) / @rvagg / how can we help this land * Logo / Brand Treatment [website/181] https://github.com/nodejs/website/issues/181 @ mikeal https://www.behance.net/gallery/23269525/IOJS-logo-concept * Stability Policy/Statement & Roadmap [#725](https://github.com/nodejs/io.js/issues/725) / @mikeal [roadmap/14](https://github.com/nodejs/roadmap/issues/14) / @mikeal ### Colin resigning from TC [#1056](https://github.com/nodejs/io.js/pull/1056) ### lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * Ben: @orangemocha did some work on Windows for libuv, unsure if this helps. * Bert: process.send() has been made sync on *nix because otherwise it’s a breaking change, but on Windows it’s always been async so changing it to sync would also be a breaking change. So the situation is crazy. * Isaac: ideal is that they behave the same and behave well * Discussion about whether this would be a breaking change or a bugfix * Bikeshed, moving to GitHub * Bert: proposed that we revert Unix behaviour and leave Windows as it is * Ben: current fix adds blocking on Windows ### iojs: introduce internal modules [#848](https://github.com/nodejs/io.js/issues/848) / @chrisdickinson / @trevnorris / (@vkurchatkin) Chris: lets us have modules that can’t be required from outside of core. I’m in favor; it’s a nice insurance policy, especially in light of the stability policy that we will try not to make any breaking changes to the JavaScript API. Mikeal: this doesn’t change the existing pseudo-internal modules to become truly internal, right? Chris: correct, that is separate. Domenic: but, doing that operation would be a good thing to do in a major version bump. Isaac/Mikeal: yes, but don’t do that for `util._extend`, too many people use it. Chris: *gives example of how this would have been helpful for a recent refactor* Ben: how will the test suite test internal functions from then on? Chris: there would be a flag, e.g. --allow_internal_modules. Mikeal: I like it. Bert: I like it too. However I am concerned about products that do monkeypatching; would that still be possible? Chris: I think so, as long as they monkeypatch the public APIs… Ben: not sure that’s quite sufficient… Domenic: seems like a pure win because it allows you not to have to put everything in one file to keep things private. ### url: significantly improve the performance of the url module [#933](https://github.com/nodejs/io.js/issues/933) / @mikeal This will get rolled in to the major version issue Chris is putting together. ### Ship websockets in core [#1010](https://github.com/nodejs/io.js/issues/1010) / @piscisaureus Bert: I’m not sure I believe in this any more; the major reason I wanted this was that building native addons is terrible, but people brought up that the native part of the web socket implementations only do some bitwise buffer stuff and so we could probably just add *those* to core. Discussion of how we should probably just add more Buffer methods to core. Bert: there’s another aspect of this. At some point Node was really modern, but we’ve fallen behind. We can’t even get HTTP/2 or web sockets, we’re in trouble. Domenic: we’ve learned a lot over the last few years that pushes us to userland code instead of in core. But we need to have some things be “official.” Trevor: I would like the infrastructure for HTTP/2 to be similar to HTTP/1, with http-parser etc. Ben: is there any reason HTTP/2 couldn’t be done in pure JS? Discussion of http-parser and current HTTP/1 implementation strategy and speed. Bert: I think as a TC what we should say is “we would like to support HTTP/2, but want to see some userland ideas first.” We don’t need to actually start implementation progress right now. Ben: does anyone on the TC want to write a userland HTTP/2 module? Discussion of how Fedor already has a SPDY implementation. Trevor: are we going to do TLS-only HTTP/2? Mikeal: we probably don't want to, because our HTTPS is not as fast as terminators. Conclusion: We should start an issue in NG about the core modules/modernity stuff. We should publicly state that we’re interested in supporting HTTP/2 in the related issue thread, although we’re not sure about implementation strategy and want to see experiments. ### RFC: upgrade to V8 4.2? [#1026](https://github.com/nodejs/io.js/issues/1026) / @bnoordhuis * Ben: V8 4.1 has gone gold/stable so we should probably upgrade by un-floating a revert we placed on top of it. I propose we revert that revert, so that we get 4.1-as-shipped-in-Chrome. [#952](https://github.com/nodejs/io.js/pull/952) for details on the floating revert. * Domenic: do we have clarity about ABI vs. API implications for io.js major version? * Ben: ABI change means everyone has to recompile their add-ons so we should bump the minor. * Fedor: this feels more like a major version? * Domenic: do we consider forcing people to run “npm rebuild” a breaking change? * Chris: I think I agree that users should not expect to have to rebuild within the same major version. * Mikeal: how often does a V8 ABI change happen *after that V8 gets into stable Chrome*? * Domenic: not sure, but would suspect not often at all. Maybe we should check with V8. * Ben: yes, not often. * Fedor: having a call with V8 might be helpful. * Mikeal: if it doesn’t happen, then we won’t end up in this situation again. Conclusion: Work with V8 team to make sure this doesn’t happen again Add “un-revert” to the growing list of issues that would trigger a minor version bump. ### Next meeting * node-v4.2.6/doc/tsc-meetings/io.js/2015-03-18.md000644 000766 000024 00000013026 12650222326 020520 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-03-18 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=tQwVcuYCiZ4 * **Google Plus Event page**: https://plus.google.com/events/cneon2drmol62u4drm8aegjnrkk * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1187 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1It6PTEBQ7OjW8P88hCLoXvcWKA3Q8dY2eYEHIF6FvS4 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * [#1134](https://github.com/nodejs/io.js/pull/1134) Add Docker working group * [#1140](https://github.com/nodejs/io.js/pull/1140) Revert stream base / @piscisaureus / merge policy questions * [#1130](https://github.com/nodejs/io.js/pull/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC * [#1077](https://github.com/nodejs/io.js/pull/1077) Pass args to process.nextTick() / @trevnorris ## Minutes ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Fedor (TC) * Trevor (TC) * Rod ### Mini stand-up * Ben: reviewing bugs, fixing pull requests * Bert: debugging Windows issues (related to #1005), working on a more helpful CI dashboard * Chris: working on tools to inspect amount of ecosystem breakage that changes cause * Fedor: working through PayPal leak issue, working on net.socket() changes * Rod: .. * Trevor: misc PRs, process.nextTick(), timer bug ### Review of last meeting * lib: fix process.send() sync i/o regression [#774](https://github.com/nodejs/io.js/issues/774) / @bnoordhuis * iojs: introduce internal modules [#848](https://github.com/nodejs/io.js/issues/848) / @chrisdickinson / @trevnorris / (@vkurchatkin) * url: significantly improve the performance of the url module [#933](https://github.com/nodejs/io.js/issues/933) / @mikeal * Ship websockets in core [#1010](https://github.com/nodejs/io.js/issues/1010) / @piscisaureus * RFC: upgrade to V8 4.2? [#1026](https://github.com/nodejs/io.js/issues/1026) / @bnoordhuis * Colin resigning from TC [#1056](https://github.com/nodejs/io.js/pull/1056) ### [#1134](https://github.com/nodejs/io.js/pull/1134) Add Docker working group * Rod: originally conceived to be a “sub-WG” of Build WG but this makes sense because there is little overlap with the Build team or skills required for the Build team. * Rod: this group is already maintaining official Docker images or io.js located at https://github.com/nodejs/docker-iojs which are also the “official” Docker images for io.js. ### [#1140](https://github.com/nodejs/io.js/pull/1140) Revert stream base / @piscisaureus / merge policy questions * Bert: in favour of stream_base now and don’t want it reverted given the fixes that have been made. The real problem was the introduction of a major change that lead to a lot of breakage and a lot of fix commits. Proposed that we have a “ng” (or similar) branch with releases for testing before merging. * Chris: agree that we need a canary policy of some kind to deal with this * Bert: feature flags are a good way of dealing with this and letting them test changes * Ben: time-based releases like Rust and Chrome * Fedor: main problem is that we didn’t have enough tests for this feature when it was merged. * Rod: there’s awkwardness around releasing given that we only have one tip and we can’t cut patch releases once we have semver-minor changes are merged. * Trevor: should have semver-minor branches where patch fixes go in and minor changes go in to master/whatever. * Discussion about git process * Discussion about semver * Discussion about minor/patch and what it communicates * Discussion about test coverage * Rod asked OpenSSL fix: agreed to punt on a release until OpenSSL fix has been released and go immediately after that. ### [#1130](https://github.com/nodejs/io.js/pull/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC * Rod: there was some off-record discussion about TC membership process related to #1130 and #1131. - Neither individual was asked and it would be good to at least have it passed by them first - Would be good to have a smooth on-boarding mechanism to bringing someone on to meetings before officially making them TC, agreed to invite Jeremiah to next TC _if_ he’s interested in being involved. - Generally agreed that increasing the size of the TC is a good thing (minus the meeting-overhead added by more people) ### [#1077](https://github.com/nodejs/io.js/pull/1077) Pass args to process.nextTick() / @trevnorris * Trevor: passing arguments / context through process.nextTick() in core is common and would be significantly faster if we use a setArgs() feature. * Chris: needed in readable-stream * Discussed API concerns and how underscored methods still become defacto in userland * Chris: could land the internal-module PR and use a Symbol for setArg * Trevor: major speed increase comes from flattening the call-structure, there’s no additional stack entries for passing arguments. Particularly in crypto, nextTick() is called a lot. * Rod: we need perf numbers from a user-experience perspective, perhaps that will make it more compelling to merge or perhaps it will make this look trivial that it’s not worth the cost of introducting ugly API * Trevor: will go off and come back with numbers ### Major version bump * Ben: proposed making a new integration branch to merge all of the semver-minor features, plus a V8 upgrade, we can start pushing out nightly-style releases for playing around and punt the decision on _how_ to do a major release down the road a little. * Group agreed, Rod agreed to help come up with a release mechanism for nightlies to couple with this. ### Next meeting * 25th March 2015 node-v4.2.6/doc/tsc-meetings/io.js/2015-04-01.md000644 000766 000024 00000012060 12650222326 020506 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-04-01 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=B1pTT60E73M * **Google Plus Event page**: https://plus.google.com/events/cneon2drmol62u4drm8aegjnrkk * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1311 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1iEzSiQpB3me-x1R0_FzlMtGuPmgxR2x7NMITp779690 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * reconciliation update (Mikeal and Bert) * doc: add NAN WG [#1226](https://github.com/nodejs/io.js/issues/1226) * Proposal: Authorise @Fishrock123 to create releases [#1225](https://github.com/nodejs/io.js/issues/1225) * governance: Raise the bar for changes in membership and governance policy [#1222](https://github.com/nodejs/io.js/issues/1222) * Nominating Rod Vagg @rvagg to the TC [#1134](https://github.com/nodejs/io.js/issues/1131) ## Minutes ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Domenic * Fedor (TC) * Jeremiah * Mikeal * Trevor (TC) * Rod ### Mini stand-up * Ben: rewriting the timers module * Bert: making it possible to rename node.exe/iojs.exe (made it into 1.6.3); governance documents for Node Foundation * Chris: building a UTF-8 consumer that can validate/skip invalid glyphs; working on a tool around control flow analysis * Domenic: not much io.js related * Fedor: rewrote io.js in Go, deciding whether it should be go.io or io.go * Jeremiah: managing issues, reviewing PRs, investigating timers bugs * Mikeal: io.js charter / Linux foundation work * Trevor: looking into beforeExit/timer unref/uv_loop_alive interactions; Node API compliance working group docs (not io.js ... might be fed into the Foundation) * Rod: released 1.6.3; GitHub DDOS and CI errors/timeouts are frustrating ### Review of last meeting * [#1134](https://github.com/nodejs/io.js/pull/1134) Add Docker working group * [#1140](https://github.com/nodejs/io.js/pull/1140) Revert stream base / @piscisaureus / merge policy questions * [#1130](https://github.com/nodejs/io.js/pull/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC * [#1077](https://github.com/nodejs/io.js/pull/1077) Pass args to process.nextTick() / @trevnorris * Major version bump ### Reconciliation update (Mikeal and Bert) * Mikeal: getting close to a really good position where the governance structures can be merged between io.js and joyent/node. New working group structure and relationship with “TSC”. People can engage @ https://github.com/joyent/nodejs-advisory-board/ with active PRs @ https://github.com/joyent/nodejs-advisory-board/pull/30 & https://github.com/joyent/nodejs-advisory-board/pull/33 * Bert: discussed why this is good for io.js: - io.js still has a very low profile, merging would be good for everyone - budget from corporate backers, including the ability to travel * Mikeal: added to those comments: institutional backing would be very helpful at this stage * Ben: current PR seems to give the board more influence than originally suggested * Mikeal: the intent is the board is not to make technical decisions, the TSC is * Trevor: counterpoint example is IBM maintaining their own fork of V8 so they may want influence on the release process * Mikeal: they will be taken care of by an LTS schedule * Bert: IBM agrees that there should be a fast-moving tip and they just use an LTS. Board could also assert influence by way of a corporation threatening to withdraw backing. ### doc: add NAN WG [#1226](https://github.com/nodejs/io.js/issues/1226) * Rod: discussed proposed move of rvagg/nan and rvagg/node-addon-examples to iojs to be governed by an “Addons API Working Group” Bert: +1 Chris: +1 Fedor: +1 Ben: +1 Trevor: +1 ### Proposal: Authorise @Fishrock123 to create releases [#1225](https://github.com/nodejs/io.js/issues/1225) * No disagreement, lots of +1s, good to go ### governance: Raise the bar for changes in membership and governance policy [#1222](https://github.com/nodejs/io.js/issues/1222) * Mikeal: the PR is a bit stale because of a miscount, just want to make sure that there are no concerns with this even though it may not end up being required given the movements with the TC. * Rod: requested that we not hold up progress in io.js pending movement on the JNAB / Foundation process and we should treat that as a separate thing that may or may not happen. * Bert: happy with the changes but can’t +1 because of the TC company proportion counting * Mikeal: just a miscount, needs to be changed, wanted to test if people are OK with this once we have more people on the TC. Main point was to flush out any concerns about raising the bar. * Ben: suggested that it become 2 PRs, make the 2/3rds thing a separate issue. ### Nominating Rod Vagg @rvagg to the TC [#1134](https://github.com/nodejs/io.js/issues/1131) * Rod: fine with this * Discussed meeting facilitation, agreed that it wasn’t a strictly defined role but it would be good to share it around a bit. Bert: +1 Chris: +1 Fedor: +1 Trevor: +1 Ben: +1 ### Open to QA from IRC _Nothing clear to discuss, but we’ll keep trying this_ ### Next meeting * 8th April 2015 node-v4.2.6/doc/tsc-meetings/io.js/2015-04-08.md000644 000766 000024 00000021754 12650222326 020527 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-04-08 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=OjlK8k10oyo * **Google Plus Event page**: https://plus.google.com/events/c1c3234uog6svplgrapqucb557k * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1369 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1EsDjfRGpVKFABH4LcNXNxsAsBTnHsU-i5cehmAcp1A8 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * [#1101](https://github.com/nodejs/io.js/pull/1101) http: allow HTTP to return an HTTPS server / @silverwind / the use of a `tls` option to trigger `https` module functionality * [#1301](https://github.com/nodejs/io.js/pull/1301) Util(.is*) Deprecations / @Fishrock123 & @brendanashworth / [this comment](https://github.com/nodejs/io.js/pull/1301#issuecomment-90829575) asking for an opinion from the TC on how to move forward * Discuss https://github.com/jasnell/dev-policy [[comment by @mikeal]](https://github.com/nodejs/io.js/issues/1369#issuecomment-90955688) * Discuss / Review the `require(‘.’)` situation [[comments by @silverwind and @Fishrock123]](https://github.com/nodejs/io.js/issues/1369#issuecomment-90933134) ### Present * Bert (TC) * Domenic * Trevor (TC) * Ben (TC) * Fedor (TC) * Jeremiah * Mikeal * Chris (TC) ### Review of last meeting * reconciliation update (Mikeal and Bert) * doc: add NAN WG [#1226](https://github.com/nodejs/io.js/issues/1226) * Proposal: Authorise @Fishrock123 to create releases [#1225](https://github.com/nodejs/io.js/issues/1225) * governance: Raise the bar for changes in membership and governance policy. [#1222](https://github.com/nodejs/io.js/issues/1222) * Nominating Rod Vagg @rvagg to the TC [#1134](https://github.com/nodejs/io.js/issues/1131) ### Quick stand-up * Ben: fixing bugs, reviewing PRs. Looked into adding `Generator.prototype.return()` in V8, but more complicated than expected (crashes and can’t figure out why). Fedor might help. * Bert: working on a CI status dashboard. Reviewing a patch that makes Node use Chakra instead of V8 (!) * Chris: worked on a patch to add a UTF8 consumer to utils, for the purposes of eventually adding UTF8 validation as well as being able to externalize buffer-strings. Talked about standardizing destroy() behavior on streams * Domenic: Not much on io.js, reviewed some dev policy stuff especially with regard to V8 * Fedor: bugs and PRs * Jeremiah: bugs and PRs and 1.6.4 release * Mikeal: worked on dev policy for the foundation, continuing to iterate; distilling feedback from worried-about-reconciliation thread, but had to lock it in the end with links to other places to address such things. * Trevor: code reviews ## Minutes ### [#1101](https://github.com/nodejs/io.js/pull/1101) http: allow HTTP to return an HTTPS server ***@silverwind / the use of a `tls` option to trigger `https` module functionality*** Jeremiah: two options we have (that we’ve discussed) are a tls option, or just auto-detect if you provide appropriate options. Ben: why is this a TC issue? Jeremiah/Domenic: three or four weeks without consensus. Mikeal: related to issue in NG, where you could pass options to listen() instead of createServer(). Chris/Jeremiah: there is a PR for it in joyent/node; not merged yet. Fedor: to me the problem is `http.request` vs. `https.request`. Mikeal: (advocates for .listen again) Trevor: -1 for doing it .listen; it’s too complicated internally; there is lots of weirdness going on here already. Fedor: would be harder to share a server among workers in a cluster. DD: but this particular PR is just a simple change to allow you to avoid having to decide between require('http') vs. require('https'). Bert: I kind of like the version where you put the options in listen(). Ben: what happens when iojs is compiled without TLS support? **Conclusion**: punt on this. Initial feedback is that if we were to go down this route, we would slightly prefer the explicit tls option; however, there needs to be a discussion about the listen() idea, and also about compilation without TLS. ### [#1301](https://github.com/nodejs/io.js/pull/1301) Util(.is*) Deprecations ***@Fishrock123 & @brendanashworth / [this comment](https://github.com/nodejs/io.js/pull/1301#issuecomment-90829575) asking for an opinion from the TC on how to move forward*** Bert: what’s the point? Trevor: that we won’t really fix bugs in these. Mikeal: this is just in the docs? Ben: also util.deprecate to log a warning Mikeal: that just sounds annoying Trevor: it’s supposed to be; fix your code Mikeal: yeah but it’s not always your code… Bert: we already have two levels of deprecation, warning and not warning Domenic: however we only use the latter for domains, since we don’t have an alternative for them Mikeal: can we do staged deprecations, marking things in the docs for one major release cycle, then in the next major release cycle start warning Domenic: could we add an option to show the deprecation warnings for people who are contentious? Mikeal: I don’t think anyone would actually turn that on… Chris: I might be able to run my tooling over all of npm to detect uses Bert: we need a better strategy in general for moving things out of core. The reason we want to deprecate these is that we don’t really want to fix it because that would be backward incompatible, so this is really too big to be in core. Any ideas for making these better? Maybe if you install a module called util it can take precedence over the one in node? So then we can release the fixed one on npm? Mikeal: that does sound better than versioning core modules … we hit a flag that lets you replace the core one with a new one. Over time we’ll be able to get data. Bert: there were some talks about doing this in browsers? Domenic: not really, nobody wants to ship two versions. **Conclusions: mark util.isXYZ deprecated in the docs, but do not show a warning in the console this version** ### [Dev Policy](https://github.com/jasnell/dev-policy) Chris: looking good to me, on the right path, some minor issues still being worked out. E.g. around using priority tags and ways to funnel work to smaller number of contributors in joyent/node vs. just adding more contributors as we do. Jeremiah: Node has a CI Jenkins PR integration thing that they are in favor of using Domenic: honestly anything that prevents people from committing things that turn the build red would be awesome… Bert: agree. Bert: there’s an issue about version numbers Mikeal: if we merge, it’ll be a 2.0.0, and we’ll bring in the backward incompatible changes we’ve been sitting on for a while Mikeal: more on this tomorrow, audio will be public after it happens (due to technology being used it won’t be live). Please review dev policy beforehand. ### Isaac Ben: Isaac doesn’t seem to be involved anymore. What do we do when a TC member goes AWOL? Mikeal: well, we cancelled two meetings he was ready to attend, and then he went on vacation for two weeks, so AWOL isn’t quite the right characterization… But yeah, he’s not doing too much. We can just ask if he wants to be there, or we can vote it off. Bert: I asked him and didn’t get an extremely clear answer; we’ll probably get more clarity when he’s back from vacation. I would not suggest throwing him off right now. Ben: yeah, there’s no urgency, just… Bert: yes, but I agree that if you’re on the TC you should show up to meetings Fedor: what if we made votes exponentially decay in power based on attendance… ### `require('.')` Mikeal: if we knew the impact of this change would we have done a major? Chris: if we would have done a major we wouldn’t have done it at all because the API is locked and only bugfixes are allowed. Jeremiah: that being said the only thing that breaks is a strange workflow from an undocumented feature. Ben: I am not very sympathetic to that argument; we broke someone’s workflow, and that’s bad. Domenic: I don’t think that’s fair. Every change is breaking to someone; even changing error messages will break people who parse error messages. The question is what side of the line this is on. Mikeal: it seemed weird… Domenic: I always thought NODE_PATH was deprecated. Should we warn about people using it? Ben: I understand that someone is already using the new require behavior, so reverting it would be backward-incompatible. So we have a few options: 1) add a hack that makes NODE_PATH interactions with require('.') work as they used to; 2) say “sorry” and keep as-is Bert: I’m sympathetic to adding the hack and a warning. Domenic: agree. And maybe try to kill NODE_PATH in 3.x. **Conclusion: hack plus a warning that shows up in this hacky case (“hey, you’re using the require-dot trick with NODE_PATH; we made it work because we’re nice people, but we want to take it away in 2.x, so gear up”). In 2.x, probably warn on any use of NODE_PATH at all.** ### Bert shows off his CI prototype It’s pretty cool. It groups tests in interesting ways that are useful. (OS, flakiness, …) ### Next meeting * 2015-04-15 node-v4.2.6/doc/tsc-meetings/io.js/2015-04-15.md000644 000766 000024 00000010301 12650222326 020507 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-04-15 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=lsRu_of0Xp8 * **Google Plus Event page**: https://plus.google.com/events/cdinisa9mlisv81um91h71g3css * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1431 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1zlYeYS0LCyIjN4KsjXh9d46hNjp302M6L1K_-_OckzQ ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? * [#1413](https://github.com/nodejs/io.js/issues/1413) combining TC and Node core call * [#1416](https://github.com/nodejs/io.js/issues/1416) io.js diff node.js foundation ### Present * Ben (TC) * Bert (TC) * Chris (TC) * Domenic * Isaac (TC) * Jeremiah * Mikeal * Rod (TC) ### Review of last meeting * [#1101](https://github.com/nodejs/io.js/pull/1101) http: allow HTTP to return an HTTPS server * [#1301](https://github.com/nodejs/io.js/pull/1301) Util(.is*) Deprecations * [Dev Policy](https://github.com/jasnell/dev-policy) * Isaac * [#1365](https://github.com/nodejs/io.js/issues/1356) `require('.')` ### Quick stand-up * Ben: will be working less on io.js in the coming weeks * Bert: come clang hacking but not much else * Chris: some review/work on dev-policy * Domenic: did some review of the URL work * Isaac: on vacation and busy re fundraising, probably have less time for io.js into the future, will likely be moved out of the role * Jeremiah: some issue management, working with dev-policy * Mikeal: dev-policy and readable summary of the foundation documents * Rod: lots of build WG work including auto Jenkins runs, write-up on “the state of the build” ## Minutes ### [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? * Ben: `next` branch should be ready to go though needs to be upgraded to 4.2.77.14, C++ changes are fairly minimal. * Discussed potentially bumping major: - Mikeal: there was a meeting where it was generally agreed that an ABI change would warrant a version bump - Rod & Isaac suggested that ABI changes shouldn’t bump major - Discussion came around to most members agreeing that ABI change _should_ bump major. Rod voted 0 on this, everyone else apparently +1. - Discussed semver-major changes including process.send() sync regressions, agreed that https://github.com/nodejs/io.js/milestones/2.0.0 represents the best info on what’s mergable * Discussed git, agreed that we should move back to master, Chris to handle git changes * Discussed RC build, could use nightly or next-nightly but officially link it off the website and maybe label it differently. Rod to figure this out. Actions: - Isaac to further review url changes, aside from his review and Domenic’s feedback in there it should be ready to merge - Chris to handle git and a move back to master - Ben to PR next branch back into master - Rod to figure out how to do and publish an RC build that’s not just “nightly-xxxxxxxxxxxxxx” - Chris will test packages against URL PR and write up results ### [#1413](https://github.com/nodejs/io.js/issues/1413) combining TC and Node core call * Mikeal: last dev-policy call brought up the suggestion of combining TC calls for both projects, with an eye on merging it would be good to understand what both groups do. Single meeting for both would be good. * Discussed timing - we span more timezones than they do so our slot of 1pm PST makes more sense to get Rod and Fedor in at the same time. Could either be Tue or Wed UTC, they have a meeting the day before us. * No strong disagreement ### [#1416](https://github.com/nodejs/io.js/issues/1416) io.js diff node.js foundation * Mikeal: Foundation doc is huge compared to ours and also contains some formalisation of our process that we just haven’t formalised yet. The diff contains a lot of those and some _actual_ changes too. Open for discussion amongst the community. * Rod: LTS discussion starting next week. ## QA on Freenode/#io.js * Paused for input, nothing this week, will continue to offer a time for this. ## Next meeting * FluentConf is on next week, Bert, Mikeal and Isaac will be at that. Agreed to go ahead and schedule one anyway. * 2015-04-22 node-v4.2.6/doc/tsc-meetings/io.js/2015-04-22.md000644 000766 000024 00000013735 12650222326 020523 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-04-22 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=s7LIMsTFaps * **Google Plus Event page**: https://plus.google.com/events/co7i7pv2a51270jat7jvkfcue64 * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1502 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1G4aJ2OwiW2WphW7Vz2OW56VRot8xRBFitluKsuYPxk0 ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * [#1130](https://github.com/nodejs/io.js/issues/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC * [#1481](https://github.com/nodejs/io.js/issues/1481) Nominating @mikeal to the TC * [#1500](https://github.com/nodejs/io.js/issues/1500) Nominating Brian White @mscdex to the TC * [#1501](https://github.com/nodejs/io.js/issues/1501) Nominating Shigeki Ohtsu @shigeki to the TC * [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? * [#1413](https://github.com/nodejs/io.js/issues/1413) Combined node.js/io.js TC/Core Call * [#1416](https://github.com/nodejs/io.js/issues/1416) Diffing io.js and the Node.js Foundation ### Present * Ben (TC) * Bert (TC) * Brian * Chris (TC) * Domenic * Fedor (TC) * Jeremiah * Shigeki * Trevor (TC) * Rod (TC) ### Review of last meeting * [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? * [#1413](https://github.com/nodejs/io.js/issues/1413) combining TC and Node core call * [#1416](https://github.com/nodejs/io.js/issues/1416) io.js diff node.js foundation ### Quick stand-up * Ben: Not much, company stuff * Bert: Playing with clang and FFI, FluentConf * Brian: JS HTTP parser, optimising and messing with regex * Chris: URL changes, looking for breakage, checked on newSession/resumeSession, 1.8.x release * Domenic: Not much, some work on V8 extensions with possible news next weeks * Fedor: Looking at the “debugger is slow” in WebStorm issue, possible fix to V8 soon, working on using the OpenSSL 1.0.2 hello parser, HTTP parser patch review * Jeremiah: Not so much work on io.js, helped get 1.8.1 out and looking into moving npm out of our git repo. * Rod: CI cluster dramas around 1.8.x release, new Raspberry Pis * Shigeki: OpenSSL upgrade, ALPM enabling PR coming this week * Trevor: Has been testing re-implementing Buffers using ES6 and TypedArrays. Some trickiness but seems doable and with patches that avoid zero-filling, performant. ## Minutes ### [#1130](https://github.com/nodejs/io.js/issues/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC Voted: * Ben: +1 * Bert: +1 * Chris: +1 * Fedor: +1 * Rod: +1 * Trevor: +1 **Action: Jeremiah Senkpiel is now a member of the io.js Technical Committee!** ### [#1481](https://github.com/nodejs/io.js/issues/1481) Nominating @mikeal to the TC * Bert, Rod: Discussion regarding the potential consequences of expanding the TC and how that might work if a merger with node happens. Discussed consequences of expansion for merger and for the practicalities of meeting. ### [#1500](https://github.com/nodejs/io.js/issues/1500) Nominating Brian White @mscdex to the TC _See above_ ### [#1501](https://github.com/nodejs/io.js/issues/1501) Nominating Shigeki Ohtsu @shigeki to the TC _See above_ ### [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? Rod: no formal “RC” builds yet but master is now going out on nightlies, they have a 2.0.0-pre version string now. Discussed whether we want formal RC builds or not. No strong opinions. Chris: `master` should be active for dev now, `next` should be used for ongoing V8 upgrade builds. Asked if the V8 changes were ready in `next` to merge - Ben confirmed - Chris to merge. Trevor: would like to get started on the upcoming V8 Buffer-related breakage and whether we should go to a 2.x branch and work on `master`. Chris: we should work on new stuff on `next` instead and leave `master` intact for now. Rod: status of URL parser changes? Chris: would like to test against candidate modules in npm that may cause breakage but otherwise seems good to merge. Domenic: would like there to be getters and setters for all data properties for completeness and future-proofing - still to be done Rod: any other breaking changes worth discussing? Ben: process.send() ready but not merged, any objections? - no objections. Chris: https://github.com/nodejs/io.js/milestones/2.0.0 new label “land-on-master” to indicate PRs that are still targeting the v1.x branch. Ben & Bert discussed Ben’s possible timers rewrite - Ben implemented a heap and red-black tree in JS, turned out to be a bit faster but not complete yet and Ben has been distracted on other projects. ** ### [#1413](https://github.com/nodejs/io.js/issues/1413) Combined node.js/io.js TC/Core Call Bert: probably not this week, intent is for next week. Jeremiah: there had been discussion around forming a convergence WG to handle some of this so as to not require everyone’s time except when necessary. ### [#1416](https://github.com/nodejs/io.js/issues/1416) Diffing io.js and the Node.js Foundation _Nothing new to discuss_ ## Open QA on Freenode/#io.js Discussion on merger and how the possibility of merging may hold up progress in io.js. Generally agreed that we shouldn’t stop doing what we are doing, nor slow down progress. Bert would like us to be conscious of activities in the Foundation and how they may impact on what we are doing. Discussion about “production ready” - recommendation is to use latest, we follow semver so that should be enough information. Rod suggested not jumping straight on to 2.0 when it lands, just because of potential edge-cases around internal changes like the url parser. Discussed module integration testing to test certain modules that we would test with each release - Chris working on some tooling around being able to inspect what modules are impacted by changes - no specific work on actually running tests on modules but this could be a TODO for Build WG (Rod to make an issue for this). ## Next meeting * 2015-04-29, UTC 20:00 node-v4.2.6/doc/tsc-meetings/io.js/2015-04-29.md000644 000766 000024 00000010063 12650222326 020521 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-04-29 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=-e675TT4WEA * **Google Plus Event page**: https://plus.google.com/events/cei87pqnichrtt4qggbbo656bpk * **GitHub Issue**: https://github.com/nodejs/io.js/issues/1557 * **Original Minutes Google Doc**: https://docs.google.com/document/d/1C9nfm_5EhNz1jifITbtQcnGBX4R9vktoZ9KsFiCU7sQ ## Agenda Extracted from https://github.com/nodejs/io.js/labels/tc-agenda prior to meeting. * Release Proposal: v2.0.0 [#1532](https://github.com/nodejs/io.js/pull/1532) * Forward-port from v1.x [#1559](https://github.com/nodejs/io.js/pull/1559) * Convergence plan (https://github.com/jasnell/dev-policy/pull/66) * Combined node.js/io.js TC/core call about convergence doc [#1413](https://github.com/nodejs/io.js/issues/1413) ### Present * Ben (TC) * Bert (TC) * Brian * Chris (TC) * Domenic * Fedor (TC) * Jeremiah * Shigeki * Trevor (TC) ### Review of last meeting * [#1130](https://github.com/nodejs/io.js/issues/1130) Nominating Jeremiah Senkpiel @Fishrock123 to the TC * [#1481](https://github.com/nodejs/io.js/issues/1481) Nominating @mikeal to the TC * [#1500](https://github.com/nodejs/io.js/issues/1500) Nominating Brian White @mscdex to the TC * [#1501](https://github.com/nodejs/io.js/issues/1501) Nominating Shigeki Ohtsu @shigeki to the TC * [#1393](https://github.com/nodejs/io.js/issues/1393) Ready to upgrade to V8 4.2? * [#1413](https://github.com/nodejs/io.js/issues/1413) Combined node.js/io.js TC/Core Call * [#1416](https://github.com/nodejs/io.js/issues/1416) Diffing io.js and the Node.js Foundation ### Quick stand-up * Ben: nothing * Bert: nothing * Brian: finished optimizations for JS HTTP parser, posted a few questions; other miscellaneous improvements in core HTTP. * Chris: upgraded V8 and documented the process; also did some work on the REPL so that classes (and let/const) work * Domenic: PR reviews for v2.0.0, starting on V8 extension work to improve startup time * Fedor: worked on fixing some TLS memory issues, so far appears to be a large improvement in memory usage. * Jeremiah: issue management; discussions on moving npm out of the repo, which seems to have converged toward a helper tool instead of moving it out of the repo * Mikeal: connection too bad to stand up. * Shigeki: working on SSL issues; root cert updates. Chrome and Firefox do whitelist of CNNIC cert hashes. * Trevor: looking at bugs, streams compliance ## Minutes ### Release Proposal: v2.0.0 [#1532](https://github.com/nodejs/io.js/pull/1532) * Domenic: - v8 changes merged - worried that we’re getting into a bad cycle of “wait a few more days” for things to land - process.send - open an rc, add to website for a few days, ship by friday * Bert/Ben: - talk of process.send - Ben: should not hold up release, windows tests break right now - less of a regression than a change * Domenic: - these releases are a train - don’t hold up the train for features - make sure it’s ready for 3 * url updates from petka: might be ready - ci run passes on all platforms but arm7 * Domenic recalls in the runup to 1.0 – “nobody tests rc's” was the consensus Chris, Trevor: discussion about how the `master` and `next` branches are used. * process.send changes will slip for v2.0 * waiting for Petka’s comment and review on url changes (https://github.com/nodejs/io.js/pull/1561) * release 2.x asap (friday) After the release: * the master branch will contain version 2.x. * api-breaking changes will land on the ‘next’ branch alongside v8 upgrades. master will be merged into next regularly * fixes are backported to the maintenance (v1.x) branch ### Forward-port from v1.x [#1559](https://github.com/nodejs/io.js/pull/1559) Discussed current plan for backporting patches to maintenance patches. * Consensus that we should give the “land in master and backport” plan a go and see how it works out. ### Convergence plan (https://github.com/jasnell/dev-policy/pull/66) ### Combined node.js/io.js TC/core call [#1413](https://github.com/nodejs/io.js/issues/1413) ## Next meeting * April 6th node-v4.2.6/doc/tsc-meetings/io.js/2015-05-13.md000644 000766 000024 00000016242 12650222326 020520 0ustar00iojsstaff000000 000000 # io.js TC Meeting 2015-05-13 ## Links * **Public YouTube feed**: http://www.youtube.com/watch?v=UbYiFLf7MpU * **Google Plus Event page**: https://plus.google.com/events/cu606mlllfehl11u8kcj7q2407k * **GitHub Issue**: https://github.com/iojs/io.js/issues/1689 * **Original Minutes Google Doc**: https://docs.google.com/document/d/15Y_kJlYm-8cIf-alniaqUWMM-TjGISCqLf40G3pv4sM ## Agenda Extracted from https://github.com/iojs/io.js/labels/tc-agenda prior to meeting. * V8 4.4 to remove indexed properties via external data [#1451](https://github.com/iojs/io.js/issues/1451) * NODE_PATH deprecation [#1627](https://github.com/iojs/io.js/issues/1627) * Join the Node Foundation? [#1664](https://github.com/iojs/io.js/issues/1664) * Put `*Sync` methods behind a flag in some future major version [#1665](https://github.com/iojs/io.js/issues/1665) * TC Nominations - Shigeki Ohtsu @shigeki [#1501](https://github.com/iojs/io.js/issues/1501) - Brian White @mscdex [#1500](https://github.com/iojs/io.js/issues/1500) - @mikeal [#1481](https://github.com/iojs/io.js/issues/1481) * Public QA via #io.js channel on Freenode ### Present * Ben (TC) * Bert (TC) * Brian * Chris (TC) * Domenic * Jeremiah (TC) * Mikeal * Rod (TC) * Shigeki * Trevor (TC) ### Quick stand-up * Ben: Upgraded V8, upgraded cares for the first time in 2 years, reviewed pull requests * Bert: Played Keen, not much io.js stuff; last Monday met with James, Mikeal about convergence * Brian: looking over potential optimizations in the JS codebase, started working on a DNS resolver as a potential replacement for cares * Chris: fixing race conditions in the REPL, poking at adding Ctrl-R history searching to readline * Domenic: working with V8 team in Munich, working on v8-extras feature, putting large portions of things into snapshot to speed up startup and other things: https://groups.google.com/forum/#!topic/v8-users/D6FmTwlvCgk * Jeremiah: issue management, working on tooling for automatic dependency upgrades, see [#1688](https://github.com/iojs/io.js/pull/1688) * Mikeal: Foundation stuff, getting ducks in a row * Shigeki: holiday in JP, fix TLS bug involving edge-case, needs review * Trevor: Helped with re-enabling snapshots, looking at changing the Buffer APIs to use TypedArrays * Rod: Been doing lots of little things, working on the CI and build cluster ### Review of last meeting * Release Proposal: v2.0.0 [#1532](https://github.com/iojs/io.js/pull/1532) * Forward-port from v1.x [#1559](https://github.com/iojs/io.js/pull/1559) * Convergence plan (https://github.com/jasnell/dev-policy/pull/66) * Combined node.js/io.js TC/core call [#1413](https://github.com/iojs/io.js/issues/1413) ## Minutes * Discussed creating a more formal deprecation policy, chris to open an issue. ### V8 4.4 to remove indexed properties via external data [#1451](https://github.com/iojs/io.js/issues/1451) * ‘smalloc’ has to go away when we land this V8, thankfully it’s not been around for long but this is a forced deprecation & removal. * currently usage of ‘smalloc’ gives a deprecation warning, as of v2.0.0 * @jeisinger has been backporting some APIs needed for Buffer, NAN will have to catch up but @kkoopa is involved * Domenic: V8 4.3 will be next week, 7 weeks from now will be 4.4 (~1 week behind Chrome release) * Trevor: no major problems with JS API, most problems will be in the C++ API, should be able to shim to ease it ### NODE_PATH deprecation [#1627](https://github.com/iojs/io.js/issues/1627) * Jeremiah: there was a suggestion to deprecate NODE_PATH entirely, debate is over deprecation or not, lots of people appear to be finding novel uses of it. * Domenic: maybe we should document it * Chris: it is documented, Googling shows that it’s been ingrained into the Node background, there’s lots of info out there about how it’s used * Domenic: https://iojs.org/api/modules.html#modules_loading_from_the_global_folders * Mikeal: maybe write docs about how it exists but you shouldn’t use it **Action: Mikeal to open an issue to change the docs to talk about how you probably shouldn’t use them** (note: it might be as simple as styling!) ### Join the Node Foundation? [#1664](https://github.com/iojs/io.js/issues/1664) * Mikeal: Mostly a consensus in the issue about joining * Mikeal: Next step is to move the “iojs” org to “nodejs”, then move the convergence repo in to be “node” to be the new tip: https://github.com/jasnell/node.js-convergence Lots of discussions about process and what needs to happen & when, Mikeal pushing for a vote to get the org moved. **Voting Question**: The io.js TC agrees to: 1. have the io.js project join the Node Foundation 2. rename the entire “iojs” GitHub org to be “nodejs” 3. invite the the current Node.js TC on to our TC to form the basis of a Node Foundation TSC under the policies of the Node Foundation 4. moving the io.js Working Groups to be under the Node Foundation **Voting Results**: * Fedor: 0 * Ben: +1 * Bert: +1 * Chris: +1 * Jeremiah: +1 * Trevor: +1 * Rod: +1 Action: Mikeal to make the move happen in a coordinated way so we get redirects and whatnot ### Put `*Sync` methods behind a flag in some future major version [#1665](https://github.com/iojs/io.js/issues/1665) * Ben: some people feel that `fs.*Sync()` methods are harmful and would like to see them go away and be behind a flag * Bert: don’t agree with deprecating but agree with a flag * Rod: agree with Bert, but would like to see doc changes * Trevor: working on a flag to print a stack trace ### TC Nominations * Shigeki Ohtsu @shigeki [#1501](https://github.com/iojs/io.js/issues/1501) * Brian White @mscdex [#1500](https://github.com/iojs/io.js/issues/1500) * @mikeal [#1481](https://github.com/iojs/io.js/issues/1481) * Mikeal: joining * Rod: timing is awkward with convergence but I’d like to make sure that Shigeki and Brian have a path to join the TC and not have that delayed too much ### Public QA via #io.js channel on Freenode * ` After the converged release, will io.js/node still be semver? for example, the history would be node 0.10, 0.12, iojs 1.x 2.x then the converged one would be node 3.x?` - Mikeal: the dev policy says so, there’s nobody advocating not to * ` Are there plans to symlink node to iojs in the installers after the first converged release?` - Bert: undecided. We should figure out a way to allow users to “node lts” and “node bleeding edge” side by side. - Mikeal: part of the above is covered by a thread in NG about localizing the node installation to global modules. * ` will members of the core team be able to revive io.js if they disagree with the direction of the project in future` - (Group) Yes * ` any plans for nan resolution?` - Rod: it’s just a header file and you need it for older versions of Node so it doesn’t make sense to _not_ use it from npm - Ben: current NAN isn’t suitable for bringing in - Trevor: would support bringing in something that would provide proper ABI support - Action: Trevor to open an issue on the NAN repo to talk about a stable C++ layer ## Next meeting * May 20th, invite joyent/node TC members, figure out who that is and if this timeslot works for them when we have a combined call tomorrow (14th) node-v4.2.6/doc/ctc-meetings/2015-10-28.md000644 000766 000024 00000036613 12650222326 017464 0ustar00iojsstaff000000 000000 # Node Foundation CTC Meeting 2015-10-28 ## Links * **Audio Recording**: https://soundcloud.com/node-foundation/ctc-meeting-2015-10-28 * **GitHub Issue**: https://github.com/nodejs/node/issues/3561 * **Minutes Google Doc**: * _Previous Minutes Google Doc: _ ## Present * Rod Vagg (CTC) * Brian White (CTC) * James Snell (CTC) * Chris Dickinson (CTC) * Ben Noordhuis (CTC) * Jeremiah Senkpiel (CTC) * Trevor Norris (CTC) * Alexis Campailla (CTC) * Mikeal Rogers (observer) * Shigeki Ohtsu (CTC) * Seth Thompson (observer) * Bert Belder (CTC) * Fedor Indutny (CTC) * Ben Noordhuis (CTC) * Colin Ihrig (CTC) ## Agenda Extracted from **tsc-agenda** labelled issues and pull requests in the nodejs org prior to meeting. ### nodejs/node * Load JSON-LD in the same way as JSON [#3502](https://github.com/nodejs/node/pull/3502) * fs: decode filenames using UTF-8 in fs.watch [#3401](https://github.com/nodejs/node/pull/3401) * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) ## Minutes ### Review of previous meeting * governance: add new collaborators #VIII [#3472](https://github.com/nodejs/node/issues/3472) * detect "full-icu" module [#3460](https://github.com/nodejs/node/issues/3460) * WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) * node: deprecate public access to `process.binding` [#2768](https://github.com/nodejs/node/pull/2768) * node: make listen address configurable [#3316](https://github.com/nodejs/node/pull/3316) ### Standup * Rod Vagg (CTC): Traveling, rc for v5.x, going to put another rc out today, comfortable with it getting released tomorrow. If it slips we’ll put it off until next week. Just need to do more smoke testing on this. * Brian White (CTC): Not a whole lot this week — triaging, responding to issues. * James Snell (CTC): Getting HTTP parser up to v2.6; getting 4.2.2 LTS update ready to go. open issue on LTS repo, would love eyes on it, to verify that the commits going into 4.2.2 look good. (https://github.com/nodejs/LTS/issues/50) working with Miles on getting CITGM updated. * Chris Dickinson (CTC): Some silly build stuff * Jeremiah Senkpiel (CTC): Not much — computer was dead since last Friday, ): but repaired now. * Trevor Norris (CTC): Bugs and issues — couple of outstanding PRs around asyncwrap, one done at Fedor’s request to make AsyncWrap public, in order to make JSStream class public * Alexis Campailla (CTC): Meetings; first API WG meeting, defining scope of the work for the WG, we want to address engine abstraction and native module API and some performance issues; small work in CI to add diagnostics; progress on module build service, going to post finding soon to get feedback * Mikeal Rogers (observer): getting a lot of interest on a certification program for node, for alternative implementations, looking at notes for API WG (thanks for taking great notes! that was awesome) I reached out to a few people that may contribute as well * Seth Thompson (observer): No updates this week. * Bert Belder (CTC): nothing noteworthy * Ben Noordhuis (CTC): Fixed debugger bugs, reviewed a lot of pull requests. * Colin Ihrig (CTC): Trying to help out with issue tracker, anticipate in another week ½ I should have significantly more time to work on core. ### Load JSON-LD in the same way as JSON [#3502](https://github.com/nodejs/node/pull/3502) * adds .jsonld files to require.extensions so that they’d load using json loader Rod: I raised this to CTC. I see this as a slippery slope, adding anything more to require.extensions. I don’t see how this won’t turn into XML — turns into bloat in formats that folks want to support. My preference would be to let the ecosystem figure this out and let folks write their own JSON loaders. Jeremiah: also probably belongs in npm James: .jsonld is just a json file with a special syntax internally. I have a module that loads it. It’s very easy to work around. Rename the file to use a json extension. I don’t see the harm in landing it, but if we don’t want to go that route, Mikeal: is the patch to add the extension or to give you your own serializer (extension) Bert: It seems harmless, but 6 months from now what if someone shows up and says “hey you’re not validating it properly” and then we have to add a validator … I’m very sensitive to slippery slope argument Alexis: Is it a different syntax? Bert: is every json document a valid jsonld document? James: no. Mikeal: we’re using a parser from npm, are we going to get a war between parsers, swapping them out? James: this doesn’t do any special parsing for jsonld, it just aliases json and uses the existing process. Trevor: the problem is what it opens us up to. invariably this leads to more PRs. this patch I don’t have a problem with, but I have a problem with this kind of patch in the future Bert: I think we’re reaching consensus here, which is: reject this patch. is anyone here strongly in favor. Ben: not in favor. one argument is jsonld is now a standard. but I too am sensitive to the slippery slope argument, so I’m perfectly fine with rejecting it. James: when rejecting it, it would be worthwhile to note how to work around it. I can do this. Jeremiah: require.extensions is not going to change anytime soon, so folks can write their own. Bert: I think we can go to the next issue. ### fs: decode filenames using UTF-8 in fs.watch [#3401](https://github.com/nodejs/node/pull/3401) See also [#3519](https://github.com/nodejs/node/issues/3519) Bert: this is Ben’s issue. Ben: I wouldn’t say it’s my issue, but I’ve been involved the thing is that filenames are frequently (but not always) utf8, the problem is now that node in one or two places it doesn’t encode utf8 [Ben, post meeting addition: For background: I thought we had some file logic baked into node::Environment and the dtrace/etw/lttng/systemtap subsystems but turns out that's not the case.] Bert: where else are we encoding differently? Ben: I can answer this in a few seconds. At least, I think there are more places. Maybe I’m mistaken, also a possibility! Jeremiah: I think someone else said it was only fs.watch too. Bert: I’ve seen the discussion but I haven’t commented. I think there’s a problem with assuming that all files are all utf8, but it seems inconsequential to assume this everywhere but this one place Ben: this is not the best issue to link to, I agree it’s inconsistent to do utf8 in most places and latin1 in only one place. There’s a link to another issue 3519. my beef with the PR is not that it’s a terrible fix, it’s more that decoding to utf8 is not always the right thing to do because not all fs are utf-8. If we’re going to do this it has to be a semver major, and if we’re going to do a semver major, then it may as well be a full fix, which I’ve outlined in 3519. Bert: there’s actually some discussions we need to have around these things. Your suggestion is to not land this PR, and instead fix this the right way. Do you think it’s likely that 3519 will see attention any time soon? Ben: It’s on my todo list. I should mention that the way node deals with file names has been a thorn in my side for a long time now, I’ve been planning to do something about it for a long time, so take this as you will. Bert: my question is: do we take this PR now, ahead of Bert: customizable decoding Mikeal: is the other one going to be a breaking change? Ben: yes Bert: or it could be a bugfix? Mikeal: so it would make sense to buffer as many changes around that as possible. Jeremiah: we could land the semver-major fix on master which would go into 6.x, then if we have time before 6.x we could do the proper fix. maybe that keeps us from fixing it entirely though? Ben: that’s my problem, it’s a bandaid that lets us truck on for a another couple of years. James?: I don’t really like quick fixes, but … Trevor: on the fs doc page, a lot of those calls reference the system level call, on unix do those use utf8 Ben: how do you mean? Trevor: for example, stat, first arg is char* pathname, if i were to take a utf8 string and read that in… what encoding does it use? Ben: syscall is agnostic. kernel treats as string of bytes. in node, we call fs.stat in javascript, string is decoded to utf8, then passed on to the kernel. Trevor: if i have a file that’s latin1, I’d have to turn that into a buffer as a binary buffer then tostring it to a utf8 string in order for the file to be open? [multiple people are talking] Ben: yes. Ben: sometimes it’s not possible to open files with funny characters in their names. Trevor: if there were a file with invalid utf8 characters it’d be impossible to open those, right? Ben: yep. James: I’m not a fan of the quick fix. I am okay with incremental so long as the larger task gets done, but … Bert: I am in favor of the quick fix, it restores consistency in the way node does things. practically speaking, almost all fs are going to be utf-8. it fixes the problem where fs.watch tells you “hey a file changed” but you go to look and the file’s not there due to the encoding scheme. I’d like to make a little improvement. the problem has been known since at least 2011, and we’ve never gotten around to it. I would not be surprised if it takes another 4 years for someone to take a stab at it. Brian: is it possible to get the user’s LOCALE and convert to that before sending it off? Ben: that’s worse than what we have now. James: the LOCALE often lies. Bert: are we going to land the patch to fs.watch? I’d like to have a quick references. Trevor: it’s not going to land in 5, we could leave it open until near v6 and land it then if no one is able to get around to the full fix. there’s 5-6 months between 5 and 6… Rod: that sounds like a nice compromise. ### WG: Considering a new HTTP WG [#3214](https://github.com/nodejs/node/issues/3214) Rod: I left this on because I thought it’d be nice to get a report from the WG on how it went. James: [cd: I am missing folk here]: Jeremiah, Eran Hammer, Doug Wilson, Myles Borins Brian White, Patrick Mueller, and myself. We talked about the charter. Looking into what improvements can be made to better support the ecosystem. Making existing impl hookable so that modules could swap out parts of the implementation with their own. Like replacing the parser, or header specific handling. The charter covers that aspect of it, but emphasizes that existing systems are not broken. We have a number of issues that we’ve created to start discussing these. I’ll get these into the doc. That’s the short version. Still really early to tell what all will come of it and what kind of schedule it’ll be on. 5th, at [cd: TIME?] We’ll be drawing up a charter and bringing it back to this group. Any other questions? Rod: could we get a report on the API WG? Trevor: the discussion was mainly around the native api. it went in a direction I wasn’t expecting. I explained my JS API proposal, then it went into a module discussion. ABI compat is straight out, it went in the direction of NAN (API compat, but occasional recompiles). Some discussion arose around abstracting node, like v8 completely. to replace with another VM. How do you handle specific difference like features that are available in one vm or another? or JS features that are/aren’t available between VMs. To target all vms, you end up having to use ES5. I was kind of losing where they were going with it. there are a lot of smart people. We’ll just have to have a discussion about feasibility. Ben: Was there any talk about who’s going to do the actual work? Trevor: No — it was more theoretical. It was more like the ES committee — develop features then say “go make these.” IF I bring it up I’m sure I can get some solid answers. Alexis: I’m trying to push for the Chakra folks to do some of this work. Mikeal: [cd: sorry, I missed this.] Rod: What companies are involved? Did MS show up? Trevor: Yes, I think so. JXCore, IBM was there, can’t remember offhand. Bert: JXCore is also secretly MS? Alexis: Not a secret! They’re on contract for an industrial IoT project. Alexis: IBM was there, Nodesource. Mikeal: Looking for someone from samsung’s jerryscript team to join. Trevor: My initial proposal was to get something usable. I’ll be out of there if it turns into WASM — if it blows up in size. Mikeal: The whole point is to be smaller than the current API, right? Bert: Well, not smaller, but … let’s not talk about technical issues Alexis: We’ve discussed multiple approaches, and we can tackle the problem from multiple sides. Trevor is tackling it by reducing the size of core. The approach I want to take is FFI interface into native modules. All of these approaches can help us tackle this huge beast into a manageable problem. They’re not competing solutions. Bert: We want to avoid scope creep. If the WG comes up with a HUGE proposal with 20 points of view, then no one will ever go do it. Trevor: I want to simplify the JS API, and get it to a point where all of the existing api can sit on top of it. If someone wants to do the work of replacing V8, they’ll have a clean entry point into the JS. And then write a set of compliance tests that specify what every entry point does. Writing a bunch for native code without JS tests to back it up would be futile. Bert: Restricting it to API design, that in theory, the sort of design goal, is for the API to be sufficient for Node to use. Alexis: This would include the native module api? Rod: It sounds like HTTP attacked charter first, maybe the API WG needs to do the same, to combat growth of scope. Maybe anyone else on this call that wants to could join and try to define scope? Is there another call scheduled, Trevor? Trevor: we’re still collecting times. I’ll mention the ctc in the issue. Rod: we should make a new @ctc GH group. Bert: which is going to be more fun? Rod: The CTC Bert: when are we going to split up? Rod: Mikeal is organizing another meeting. Mikeal: It’s tomorrow at this time slot. ### node-gyp: Windows users are not happy. [node-gyp#629](https://github.com/nodejs/node-gyp/issues/629) Jeremiah: Do we want to talk about the windows issue? Rod?: it kind of contains all of the windows problems. Alexis: I was asking about guidance on this. Rod: there’s a strategy of giving folks a place to vent, keeping it from spilling over elsewhere. Without this issue, it might explode into a bunch more issues. Alexis: We’re working on a module build service. The other thing is that MS is going to release a smaller SKU of the compiler, that might be able to be included with node-gyp. Rod: Next visual studio is going to be shipping with clang. Trevor: Yes for AST stuff. [cd: might have gotten this wrong] Rod: Alexis, you should post in there, but I think it’s going to always catch folks googling for the problem. I’m not sure you can resolve it by closing or locking it. Folks will go there and not see a proper resolution. Mikeal: make sure there are issues for everything in the thread, then close and lock. Make sure there are resolutions (even if it’s “move hte conversation”). Rod: I’m happy for Alexis to take the lead on this. Rod: Maybe change the title to “Windows users are happy?” Alexis: Maybe change to “Unix users are unhappy.” Rod: that’d be an epic troll. ## Next Meeting November 4, 2015 node-v4.2.6/doc/api_assets/sh.css000644 000766 000024 00000000610 12650222326 016767 0ustar00iojsstaff000000 000000 .sh_sourceCode { font-weight: normal; font-style: normal; } .sh_sourceCode .sh_symbol, .sh_sourceCode .sh_cbracket { color: #333; } .sh_sourceCode .sh_keyword { color: #338; } .sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number, .sh_sourceCode .sh_specialchar { color: #E54305; } .sh_sourceCode .sh_comment { color: #666; font-weight: lighter; } node-v4.2.6/doc/api_assets/sh_main.js000644 000766 000024 00000035702 12650222326 017631 0ustar00iojsstaff000000 000000 /* SHJS - Syntax Highlighting in JavaScript Copyright (C) 2007, 2008 gnombat@users.sourceforge.net License: http://shjs.sourceforge.net/doc/gplv3.html */ if (! this.sh_languages) { this.sh_languages = {}; } var sh_requests = {}; function sh_isEmailAddress(url) { if (/^mailto:/.test(url)) { return false; } return url.indexOf('@') !== -1; } function sh_setHref(tags, numTags, inputString) { var url = inputString.substring(tags[numTags - 2].pos, tags[numTags - 1].pos); if (url.length >= 2 && url.charAt(0) === '<' && url.charAt(url.length - 1) === '>') { url = url.substr(1, url.length - 2); } if (sh_isEmailAddress(url)) { url = 'mailto:' + url; } tags[numTags - 2].node.href = url; } /* Konqueror has a bug where the regular expression /$/g will not match at the end of a line more than once: var regex = /$/g; var match; var line = '1234567890'; regex.lastIndex = 10; match = regex.exec(line); var line2 = 'abcde'; regex.lastIndex = 5; match = regex.exec(line2); // fails */ function sh_konquerorExec(s) { var result = ['']; result.index = s.length; result.input = s; return result; } /** Highlights all elements containing source code in a text string. The return value is an array of objects, each representing an HTML start or end tag. Each object has a property named pos, which is an integer representing the text offset of the tag. Every start tag also has a property named node, which is the DOM element started by the tag. End tags do not have this property. @param inputString a text string @param language a language definition object @return an array of tag objects */ function sh_highlightString(inputString, language) { if (/Konqueror/.test(navigator.userAgent)) { if (! language.konquered) { for (var s = 0; s < language.length; s++) { for (var p = 0; p < language[s].length; p++) { var r = language[s][p][0]; if (r.source === '$') { r.exec = sh_konquerorExec; } } } language.konquered = true; } } var a = document.createElement('a'); var span = document.createElement('span'); // the result var tags = []; var numTags = 0; // each element is a pattern object from language var patternStack = []; // the current position within inputString var pos = 0; // the name of the current style, or null if there is no current style var currentStyle = null; var output = function(s, style) { var length = s.length; // this is more than just an optimization - we don't want to output empty elements if (length === 0) { return; } if (! style) { var stackLength = patternStack.length; if (stackLength !== 0) { var pattern = patternStack[stackLength - 1]; // check whether this is a state or an environment if (! pattern[3]) { // it's not a state - it's an environment; use the style for this environment style = pattern[1]; } } } if (currentStyle !== style) { if (currentStyle) { tags[numTags++] = {pos: pos}; if (currentStyle === 'sh_url') { sh_setHref(tags, numTags, inputString); } } if (style) { var clone; if (style === 'sh_url') { clone = a.cloneNode(false); } else { clone = span.cloneNode(false); } clone.className = style; tags[numTags++] = {node: clone, pos: pos}; } } pos += length; currentStyle = style; }; var endOfLinePattern = /\r\n|\r|\n/g; endOfLinePattern.lastIndex = 0; var inputStringLength = inputString.length; while (pos < inputStringLength) { var start = pos; var end; var startOfNextLine; var endOfLineMatch = endOfLinePattern.exec(inputString); if (endOfLineMatch === null) { end = inputStringLength; startOfNextLine = inputStringLength; } else { end = endOfLineMatch.index; startOfNextLine = endOfLinePattern.lastIndex; } var line = inputString.substring(start, end); var matchCache = []; for (;;) { var posWithinLine = pos - start; var stateIndex; var stackLength = patternStack.length; if (stackLength === 0) { stateIndex = 0; } else { // get the next state stateIndex = patternStack[stackLength - 1][2]; } var state = language[stateIndex]; var numPatterns = state.length; var mc = matchCache[stateIndex]; if (! mc) { mc = matchCache[stateIndex] = []; } var bestMatch = null; var bestPatternIndex = -1; for (var i = 0; i < numPatterns; i++) { var match; if (i < mc.length && (mc[i] === null || posWithinLine <= mc[i].index)) { match = mc[i]; } else { var regex = state[i][0]; regex.lastIndex = posWithinLine; match = regex.exec(line); mc[i] = match; } if (match !== null && (bestMatch === null || match.index < bestMatch.index)) { bestMatch = match; bestPatternIndex = i; if (match.index === posWithinLine) { break; } } } if (bestMatch === null) { output(line.substring(posWithinLine), null); break; } else { // got a match if (bestMatch.index > posWithinLine) { output(line.substring(posWithinLine, bestMatch.index), null); } var pattern = state[bestPatternIndex]; var newStyle = pattern[1]; var matchedString; if (newStyle instanceof Array) { for (var subexpression = 0; subexpression < newStyle.length; subexpression++) { matchedString = bestMatch[subexpression + 1]; output(matchedString, newStyle[subexpression]); } } else { matchedString = bestMatch[0]; output(matchedString, newStyle); } switch (pattern[2]) { case -1: // do nothing break; case -2: // exit patternStack.pop(); break; case -3: // exitall patternStack.length = 0; break; default: // this was the start of a delimited pattern or a state/environment patternStack.push(pattern); break; } } } // end of the line if (currentStyle) { tags[numTags++] = {pos: pos}; if (currentStyle === 'sh_url') { sh_setHref(tags, numTags, inputString); } currentStyle = null; } pos = startOfNextLine; } return tags; } //////////////////////////////////////////////////////////////////////////////// // DOM-dependent functions function sh_getClasses(element) { var result = []; var htmlClass = element.className; if (htmlClass && htmlClass.length > 0) { var htmlClasses = htmlClass.split(' '); for (var i = 0; i < htmlClasses.length; i++) { if (htmlClasses[i].length > 0) { result.push(htmlClasses[i]); } } } return result; } function sh_addClass(element, name) { var htmlClasses = sh_getClasses(element); for (var i = 0; i < htmlClasses.length; i++) { if (name.toLowerCase() === htmlClasses[i].toLowerCase()) { return; } } htmlClasses.push(name); element.className = htmlClasses.join(' '); } /** Extracts the tags from an HTML DOM NodeList. @param nodeList a DOM NodeList @param result an object with text, tags and pos properties */ function sh_extractTagsFromNodeList(nodeList, result) { var length = nodeList.length; for (var i = 0; i < length; i++) { var node = nodeList.item(i); switch (node.nodeType) { case 1: if (node.nodeName.toLowerCase() === 'br') { var terminator; if (/MSIE/.test(navigator.userAgent)) { terminator = '\r'; } else { terminator = '\n'; } result.text.push(terminator); result.pos++; } else { result.tags.push({node: node.cloneNode(false), pos: result.pos}); sh_extractTagsFromNodeList(node.childNodes, result); result.tags.push({pos: result.pos}); } break; case 3: case 4: result.text.push(node.data); result.pos += node.length; break; } } } /** Extracts the tags from the text of an HTML element. The extracted tags will be returned as an array of tag objects. See sh_highlightString for the format of the tag objects. @param element a DOM element @param tags an empty array; the extracted tag objects will be returned in it @return the text of the element @see sh_highlightString */ function sh_extractTags(element, tags) { var result = {}; result.text = []; result.tags = tags; result.pos = 0; sh_extractTagsFromNodeList(element.childNodes, result); return result.text.join(''); } /** Merges the original tags from an element with the tags produced by highlighting. @param originalTags an array containing the original tags @param highlightTags an array containing the highlighting tags - these must not overlap @result an array containing the merged tags */ function sh_mergeTags(originalTags, highlightTags) { var numOriginalTags = originalTags.length; if (numOriginalTags === 0) { return highlightTags; } var numHighlightTags = highlightTags.length; if (numHighlightTags === 0) { return originalTags; } var result = []; var originalIndex = 0; var highlightIndex = 0; while (originalIndex < numOriginalTags && highlightIndex < numHighlightTags) { var originalTag = originalTags[originalIndex]; var highlightTag = highlightTags[highlightIndex]; if (originalTag.pos <= highlightTag.pos) { result.push(originalTag); originalIndex++; } else { result.push(highlightTag); if (highlightTags[highlightIndex + 1].pos <= originalTag.pos) { highlightIndex++; result.push(highlightTags[highlightIndex]); highlightIndex++; } else { // new end tag result.push({pos: originalTag.pos}); // new start tag highlightTags[highlightIndex] = {node: highlightTag.node.cloneNode(false), pos: originalTag.pos}; } } } while (originalIndex < numOriginalTags) { result.push(originalTags[originalIndex]); originalIndex++; } while (highlightIndex < numHighlightTags) { result.push(highlightTags[highlightIndex]); highlightIndex++; } return result; } /** Inserts tags into text. @param tags an array of tag objects @param text a string representing the text @return a DOM DocumentFragment representing the resulting HTML */ function sh_insertTags(tags, text) { var doc = document; var result = document.createDocumentFragment(); var tagIndex = 0; var numTags = tags.length; var textPos = 0; var textLength = text.length; var currentNode = result; // output one tag or text node every iteration while (textPos < textLength || tagIndex < numTags) { var tag; var tagPos; if (tagIndex < numTags) { tag = tags[tagIndex]; tagPos = tag.pos; } else { tagPos = textLength; } if (tagPos <= textPos) { // output the tag if (tag.node) { // start tag var newNode = tag.node; currentNode.appendChild(newNode); currentNode = newNode; } else { // end tag currentNode = currentNode.parentNode; } tagIndex++; } else { // output text currentNode.appendChild(doc.createTextNode(text.substring(textPos, tagPos))); textPos = tagPos; } } return result; } /** Highlights an element containing source code. Upon completion of this function, the element will have been placed in the "sh_sourceCode" class. @param element a DOM
 element containing the source code to be highlighted
@param  language  a language definition object
*/
function sh_highlightElement(element, language) {
  sh_addClass(element, 'sh_sourceCode');
  var originalTags = [];
  var inputString = sh_extractTags(element, originalTags);
  var highlightTags = sh_highlightString(inputString, language);
  var tags = sh_mergeTags(originalTags, highlightTags);
  var documentFragment = sh_insertTags(tags, inputString);
  while (element.hasChildNodes()) {
    element.removeChild(element.firstChild);
  }
  element.appendChild(documentFragment);
}

function sh_getXMLHttpRequest() {
  if (window.ActiveXObject) {
    return new ActiveXObject('Msxml2.XMLHTTP');
  }
  else if (window.XMLHttpRequest) {
    return new XMLHttpRequest();
  }
  throw 'No XMLHttpRequest implementation available';
}

function sh_load(language, element, prefix, suffix) {
  if (language in sh_requests) {
    sh_requests[language].push(element);
    return;
  }
  sh_requests[language] = [element];
  var request = sh_getXMLHttpRequest();
  var url = prefix + 'sh_' + language + suffix;
  request.open('GET', url, true);
  request.onreadystatechange = function () {
    if (request.readyState === 4) {
      try {
        if (! request.status || request.status === 200) {
          eval(request.responseText);
          var elements = sh_requests[language];
          for (var i = 0; i < elements.length; i++) {
            sh_highlightElement(elements[i], sh_languages[language]);
          }
        }
        else {
          throw 'HTTP error: status ' + request.status;
        }
      }
      finally {
        request = null;
      }
    }
  };
  request.send(null);
}

/**
Highlights all elements containing source code on the current page. Elements
containing source code must be "pre" elements with a "class" attribute of
"sh_LANGUAGE", where LANGUAGE is a valid language identifier; e.g., "sh_java"
identifies the element as containing "java" language source code.
*/
function highlight(prefix, suffix, tag) {
  var nodeList = document.getElementsByTagName(tag);
  for (var i = 0; i < nodeList.length; i++) {
    var element = nodeList.item(i);
    var htmlClasses = sh_getClasses(element);
    var highlighted = false;
    var donthighlight = false;
    for (var j = 0; j < htmlClasses.length; j++) {
      var htmlClass = htmlClasses[j].toLowerCase();
      if (htmlClass === 'sh_none') {
        donthighlight = true
        continue;
      }
      if (htmlClass.substr(0, 3) === 'sh_') {
        var language = htmlClass.substring(3);
        if (language in sh_languages) {
          sh_highlightElement(element, sh_languages[language]);
          highlighted = true;
        }
        else if (typeof(prefix) === 'string' && typeof(suffix) === 'string') {
          sh_load(language, element, prefix, suffix);
        }
        else {
          throw 'Found <' + tag + '> element with class="' + htmlClass + '", but no such language exists';
        }
        break;
      }
    }
    if (highlighted === false && donthighlight == false) {
      sh_highlightElement(element, sh_languages["javascript"]);
    }
  }
}



function sh_highlightDocument(prefix, suffix) {
  highlight(prefix, suffix, 'tt');
  highlight(prefix, suffix, 'code');
  highlight(prefix, suffix, 'pre');
}
node-v4.2.6/doc/api_assets/style.css000644 000766 000024 00000015306 12650222326 017525 0ustar00iojsstaff000000 000000 /*--------------------- Layout and Typography ----------------------------*/
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-variant-ligatures: none;
          font-variant-ligatures: none;
}

body {
  font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
  font-size: 62.5%;
  margin: 0;
  padding: 0;
  color: #333;
  background: #fff;
}

#content {
  font-size: 1.8em;
}

a,
a:link,
a:active {
  color: #80bd01;
  text-decoration: none;
  border-radius: 2px;
  padding: .1em .2em;
  margin: -.1em 0;
}

a:hover,
a:focus {
  color: #fff;
  background-color: #80bd01;
}

strong {
  font-weight: 700;
}

code a:hover {
  background: none;
}

#changelog #gtoc {
  display: none;
}

#gtoc {
  font-size: 0.8em;
}

#gtoc p {
}

#gtoc a {
}

#gtoc a:hover {
}

.api_stability_0,
.api_stability_1,
.api_stability_2,
.api_stability_3,
.api_stability_4,
.api_stability_5 {
  color: white !important;
  margin: 0em 0 1.0em 0;
  font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
  font-weight: 700;
}

.api_stability_0 *,
.api_stability_1 *,
.api_stability_2 *,
.api_stability_3 *,
.api_stability_4 *,
.api_stability_5 * {
  color: white !important;
}

.api_stability_0 a,
.api_stability_1 a,
.api_stability_2 a,
.api_stability_3 a,
.api_stability_4 a,
.api_stability_5 a {
  text-decoration: underline;
}

.api_stability_0 {
  background-color: #D60027;
}

.api_stability_1 {
  background-color: #EC5315;
}

.api_stability_2 {
  background-color: #4EBA0F;
}

.api_stability_3 {
  background-color: #0084B6;
}

ul.plain {
  list-style: none;
}

abbr {
  border-bottom: 1px dotted #454545;
}

p {
  position: relative;
  text-rendering: optimizeLegibility;
  margin: 0 0 1em 0;
  line-height: 1.5em;
}

#apicontent > *:last-child {
  margin-bottom: 0;
  padding-bottom: 2.0em;
}

table {
  border-collapse: collapse;
  margin: 0 0 1.5em 0;
}

th, td {
  border: 1px solid #aaa;
}

table p {
}

th {
  text-align:left;
}

ol, ul, dl {
  margin: 0 0 0.6em 0;
  padding: 0;
}

ol ul, ol ol, ol dl,
ul ul, ul ol, ul dl,
dl ul, dl ol, dl dl {
  margin-bottom: 0;
}

ul, ol {
  margin-left: 2em;
}

dl dt {
  position: relative;
  margin: 1.5em 0 0;
}

dl dd {
  position: relative;
  margin: 0 1em 0;
}

dd + dt.pre {
  margin-top: 1.6em;
}

h1, h2, h3, h4, h5, h6 {
  text-rendering: optimizeLegibility;
  font-weight: 700;
  position: relative;
  margin-bottom: 0.5em;
}

header h1 {
  line-height: 2.0em;
  margin: 0;
}

#apicontent {
  padding-top: 1.0em;
}

#toc + h1 {
  margin-top: 1em;
  padding-top: 0;
}

h2 {
  font-size: 1.5em;
  margin: 1.0em 0 0.5em;
}

h2 + h2 {
  margin: 0 0 0.5em;
}

h3 {
  font-size: 1.0em;
  margin: 1.5em 0 0.5em;
}

h3 + h3 {
  margin: 0 0 0.5em;
}

h2, h3, h4 {
  position: relative;
  padding-right: 40px;
}

h1 span, h2 span, h3 span, h4 span {
  position: absolute;
  display: block;
  top: 0;
  right: 0;
}

h1 span:hover, h2 span:hover, h3 span:hover, h4 span:hover {
  opacity: 1;
}

h1 span a, h2 span a, h3 span a, h4 span a {
  font-size: 0.8em;
  color: #000;
  text-decoration: none;
  font-weight: bold;
}

h5 {
  font-size: 1.125em;
  line-height: 1.4em;
}

h6 {
  font-size: 1em;
  line-height: 1.4667em;
}

pre, tt, code {
  line-height: 1.5em;
  font-family: Monaco, Consolas, "Lucida Console", monospace;
  margin: 0; padding: 0;
}

.pre {
  font-family: Monaco, Consolas, "Lucida Console", monospace;
  line-height: 1.5em;
  font-size: 1.2em;
}

pre {
  padding: 1.0em 1.5em;
  vertical-align: top;
  background: #f2f5f0;
  margin: 0.166666em -4.0em 1.0em 0em;
  overflow-x: auto;
}

pre > code {
  font-size: 0.8em;
}

pre + h3 {
  margin-top: 2.225em;
}

code.pre {
  white-space: pre;
}

#intro {
  margin-top: 1.25em;
  margin-left: 1.0em;
}

#intro a {
  color: #ddd;
  font-size: 1.25em;
  font-weight: bold;
}

hr {
  background: none;
  border: medium none;
  border-bottom: 1px solid #7a7a7a;
  margin: 0em 0em 1em 0;
}

#toc {
}

#toc h2 {
  margin-top: 0;
  font-size: 1.0em;
  line-height: 0;
  margin: 1.5em 0;
}

#toc ul {
  font-size: 0.8125em;
}

#toc ul ul { font-size: 1.0em; }

#toc ul a {
  text-decoration:none;
}

#toc ul li {
  margin-bottom: 0.6666em;
  list-style: square outside;
}

#toc li > ul {
  margin-top: 0.6666em;
}

#toc ul a:hover,
#toc ul a:focus {
}

#apicontent li {
  margin-bottom: 0.5em;
}

#apicontent li:last-child {
  margin-bottom: 0;
}

p tt,
p code,
li code {
  font-size: 0.9em;
  color: #040404;
  background-color: #f0f0f0;
  padding: .1em .2em;
  border-radius: 2px;
}

a code {
  color: inherit;
  background: inherit;
}

span.type {
  color: #222;
}

#content {
  margin: 0 auto;
  overflow: visible;
  clear: both;
  display: block;
}

#column1.interior {
  width: 702px;
  margin-left: 234px;
  padding-left: 2.0em;
}

#column2.interior {
  width: 234px;
  background: #333;
  position: fixed;
  height: 100%;
  overflow-y: scroll;
}

#column2.interior:after {
  content: '';
  position: fixed;
  bottom: 0;
  left: 0;
  width: 234px;
  height: 4em;
  background: linear-gradient(rgba(242,245,240, 0), rgba(51, 51, 51, 1));
  pointer-events: none;
}

#column2 ul {
  list-style: none;
  margin-left: 0em;
  margin-top: 1.25em;
  background: #333;
  margin-bottom: 0;
  padding-bottom: 3em;
}

#column2 ul li {
  padding-left: 1.4em;
  margin-bottom: 0.5em;
  padding-bottom: 0.5em;
  font-size: 0.8em;
}

#column2 ul li:last-child {
  margin-bottom: 0;
}

#column2 ul li a {
  color: #ccc;
  border-radius: 0;
}

#column2 ul li a.active,
#column2 ul li a.active:hover,
#column2 ul li a.active:focus {
  color: #80bd01;
  border-radius: 0;
  border-bottom: 1px solid #80bd01;
  background: none;
}

#intro a:hover,
#column2 ul li a:hover,
#column2 ul li a:focus {
  color: #fff;
  background: none;
}

span > .mark,
span > .mark:visited {
  font-size: 18px;
  color: #707070;
  position: absolute;
  top: 0px;
  right: 0px;
}

span > .mark:hover {
  color: #FE7110;
}

th, td {
  padding: 0.75em 1.0em 0.75em 1.0em;
  vertical-align: top;
}

th > *:last-child,
td > *:last-child {
  margin-bottom: 0;
}

/* simpler clearfix */
.clearfix:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

@media only screen and (max-width: 1024px) {
  #content {
    font-size: 2.1em;
  }
  #column1.interior {
    margin-left: 0;
    padding-left: 0.5em;
    padding-right: 0.5em;
    width: auto;
  }
  pre {
    margin-right: 0;
  }
  #column2 {
    display: none;
  }
}

@media only screen and (max-width: 1024px) and (orientation: portrait) {
  #content {
    font-size: 2.4em;
  }
  #column1.interior {
    margin-left: 0;
    padding-left: 0.5em;
    padding-right: 0.5em;
    width: auto;
  }
  pre {
    margin-right: 0;
  }
  #column2 {
    display: none;
  }
}
node-v4.2.6/doc/api/_toc.html000644 000766 000024 00000012424 12650222331 016075 0ustar00iojsstaff000000 000000 


  
   Node.js v4.2.6 Manual & Documentation
  
  
  
  


  
  
  
  



node-v4.2.6/doc/api/_toc.json000644 000766 000024 00000014322 12650222331 016101 0ustar00iojsstaff000000 000000 {
  "source": "doc/api/_toc.markdown",
  "desc": [
    {
      "type": "space"
    },
    {
      "type": "list_start",
      "ordered": false
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[About these Docs](documentation.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Synopsis](synopsis.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Assertion Testing](assert.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Buffer](buffer.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[C/C++ Addons](addons.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Child Processes](child_process.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Cluster](cluster.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Console](console.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Crypto](crypto.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Debugger](debugger.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[DNS](dns.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Domain](domain.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Errors](errors.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Events](events.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[File System](fs.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Globals](globals.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[HTTP](http.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[HTTPS](https.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Modules](modules.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Net](net.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[OS](os.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Path](path.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Process](process.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Punycode](punycode.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Query Strings](querystring.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Readline](readline.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[REPL](repl.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Stream](stream.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[String Decoder](string_decoder.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Timers](timers.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[TLS/SSL](tls.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[TTY](tty.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[UDP/Datagram](dgram.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[URL](url.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[Utilities](util.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[V8](v8.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[VM](vm.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_item_start"
    },
    {
      "type": "text",
      "text": "[ZLIB](zlib.html)"
    },
    {
      "type": "list_item_end"
    },
    {
      "type": "list_end"
    }
  ]
}
node-v4.2.6/doc/api/_toc.markdown000644 000766 000024 00000002060 12650222326 016752 0ustar00iojsstaff000000 000000 @// NB(chrisdickinson): if you move this file, be sure to update tools/doc/html.js to
@// point at the new location.
* [About these Docs](documentation.html)
* [Synopsis](synopsis.html)
* [Assertion Testing](assert.html)
* [Buffer](buffer.html)
* [C/C++ Addons](addons.html)
* [Child Processes](child_process.html)
* [Cluster](cluster.html)
* [Console](console.html)
* [Crypto](crypto.html)
* [Debugger](debugger.html)
* [DNS](dns.html)
* [Domain](domain.html)
* [Errors](errors.html)
* [Events](events.html)
* [File System](fs.html)
* [Globals](globals.html)
* [HTTP](http.html)
* [HTTPS](https.html)
* [Modules](modules.html)
* [Net](net.html)
* [OS](os.html)
* [Path](path.html)
* [Process](process.html)
* [Punycode](punycode.html)
* [Query Strings](querystring.html)
* [Readline](readline.html)
* [REPL](repl.html)
* [Stream](stream.html)
* [String Decoder](string_decoder.html)
* [Timers](timers.html)
* [TLS/SSL](tls.html)
* [TTY](tty.html)
* [UDP/Datagram](dgram.html)
* [URL](url.html)
* [Utilities](util.html)
* [V8](v8.html)
* [VM](vm.html)
* [ZLIB](zlib.html)
node-v4.2.6/doc/api/addons.html000644 000766 000024 00000074405 12650222331 016430 0ustar00iojsstaff000000 000000 


  
  Addons Node.js v4.2.6 Manual & Documentation
  
  
  
  


  

Node.js v4.2.6 Documentation


Addons#

Addons are dynamically-linked shared objects. They can provide glue to C and C++ libraries. The API (at the moment) is rather complex, involving knowledge of several libraries:

  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node.js source tree), which is also available online.

  • libuv, C event loop library. Anytime one needs to wait for a file descriptor to become readable, wait for a timer, or wait for a signal to be received, one will need to interface with libuv. That is, if you perform any I/O, libuv will need to be used.

  • Internal Node.js libraries. The most important class is node::ObjectWrap which you will likely want to derive from.

  • Others. Look in deps/ for what else is available.

Node.js statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries.

All of the following examples are available for download and may be used as a starting-point for your own Addon.

Hello world#

To get started, let's make a small Addon which is the C++ equivalent of the following JavaScript code:

module.exports.hello = function() { return 'world'; };

First we create a file hello.cc:

// hello.cc
#include <node.h>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(addon, init)

}  // namespace demo

Note that all Node.js addons must export an initialization function:

void Initialize(Local<Object> exports);
NODE_MODULE(module_name, Initialize)

There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

The module_name needs to match the filename of the final binary (excluding the .node suffix).

The source code needs to be built into addon.node, the binary Addon. To do this, we create a file called binding.gyp which describes the configuration to build your module in a JSON-like format. This file gets compiled by node-gyp.

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "hello.cc" ]
    }
  ]
}

The next step is to generate the appropriate project build files for the current platform. Use node-gyp configure for that.

Now you will have either a Makefile (on Unix platforms) or a vcxproj file (on Windows) in the build/ directory. Next, invoke the node-gyp build command.

Now you have your compiled .node bindings file! The compiled bindings end up in build/Release/.

You can now use the binary addon in a Node.js project hello.js by pointing require to the recently built hello.node module:

// hello.js
const addon = require('./build/Release/addon');

console.log(addon.hello()); // 'world'

Please see patterns below for further information or

https://github.com/arturadib/node-qt for an example in production.

Addon patterns#

Below are some addon patterns to help you get started. Consult the online v8 reference for help with the various v8 calls, and v8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.

In order to use these examples, you need to compile them using node-gyp. Create the following binding.gyp file:

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon.cc" ]
    }
  ]
}

In cases where there is more than one .cc file, simply add the file name to the sources array. For example:

"sources": ["addon.cc", "myexample.cc"]

Now that you have your binding.gyp ready, you can configure and build the addon:

$ node-gyp configure build

Function arguments#

The following pattern illustrates how to read arguments from JavaScript function calls and return a result. This is the main and only needed source addon.cc:

// addon.cc
#include <node.h>

namespace demo {

using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.Length() < 2) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong number of arguments")));
    return;
  }

  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong arguments")));
    return;
  }

  double value = args[0]->NumberValue() + args[1]->NumberValue();
  Local<Number> num = Number::New(isolate, value);

  args.GetReturnValue().Set(num);
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, Init)

}  // namespace demo

You can test it with the following JavaScript snippet:

// test.js
const addon = require('./build/Release/addon');

console.log( 'This should be eight:', addon.add(3,5) );

Callbacks#

You can pass JavaScript functions to a C++ function and execute them from there. Here's addon.cc:

// addon.cc
#include <node.h>

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::String;
using v8::Value;

void RunCallback(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Function> cb = Local<Function>::Cast(args[0]);
  const unsigned argc = 1;
  Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };
  cb->Call(Null(isolate), argc, argv);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", RunCallback);
}

NODE_MODULE(addon, Init)

}  // namespace demo

Note that this example uses a two-argument form of Init() that receives the full module object as the second argument. This allows the addon to completely overwrite exports with a single function instead of adding the function as a property of exports.

To test it, run the following JavaScript snippet:

// test.js
const addon = require('./build/Release/addon');

addon(function(msg){
  console.log(msg); // 'hello world'
});

Object factory#

You can create and return new objects from within a C++ function with this addon.cc pattern, which returns an object with property msg that echoes the string passed to createObject():

// addon.cc
#include <node.h>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  Local<Object> obj = Object::New(isolate);
  obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());

  args.GetReturnValue().Set(obj);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, Init)

}  // namespace demo

To test it in JavaScript:

// test.js
const addon = require('./build/Release/addon');

var obj1 = addon('hello');
var obj2 = addon('world');
console.log(obj1.msg+' '+obj2.msg); // 'hello world'

Function factory#

This pattern illustrates how to create and return a JavaScript function that wraps a C++ function:

// addon.cc
#include <node.h>

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void MyFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
}

void CreateFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);
  Local<Function> fn = tpl->GetFunction();

  // omit this to make it anonymous
  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));

  args.GetReturnValue().Set(fn);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateFunction);
}

NODE_MODULE(addon, Init)

}  // namespace demo

To test:

// test.js
const addon = require('./build/Release/addon');

var fn = addon();
console.log(fn()); // 'hello world'

Wrapping C++ objects#

Here, we will create a wrapper for a C++ object/class MyObject that can be instantiated in JavaScript through the new operator. First, prepare the main module addon.cc:

// addon.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Local;
using v8::Object;

void InitAll(Local<Object> exports) {
  MyObject::Init(exports);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

Then, in myobject.h, make your wrapper inherit from node::ObjectWrap:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Local<v8::Object> exports);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

And in myobject.cc, implement the various methods that you want to expose. Here we expose the method plusOne by adding it to the constructor's prototype:

// myobject.cc
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
  exports->Set(String::NewFromUtf8(isolate, "MyObject"),
               tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}

}  // namespace demo

Test it with:

// test.js
const addon = require('./build/Release/addon');

var obj = new addon.MyObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

Factory of wrapped objects#

This is useful when you want to be able to create native objects without explicitly instantiating them with the new operator in JavaScript. For example:

var obj = addon.createObject();
// instead of:
// var obj = new addon.Object();

Let's register our createObject method in addon.cc:

// addon.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  MyObject::NewInstance(args);
}

void InitAll(Local<Object> exports, Local<Object> module) {
  MyObject::Init(exports->GetIsolate());

  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

In myobject.h, we now introduce the static method NewInstance that takes care of instantiating the object. In other words, it does the job of new in JavaScript:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Isolate* isolate);
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

The implementation is similar to the above in myobject.cc:

// myobject.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Isolate* isolate) {
  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  const unsigned argc = 1;
  Local<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}

}  // namespace demo

Test it with:

// test.js
const createObject = require('./build/Release/addon');

var obj = createObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

var obj2 = createObject(20);
console.log( obj2.plusOne() ); // 21
console.log( obj2.plusOne() ); // 22
console.log( obj2.plusOne() ); // 23

Passing wrapped objects around#

In addition to wrapping and returning C++ objects, you can pass them around by unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap. In the following addon.cc, we introduce a function add() that can take on two MyObject objects:

// addon.cc
#include <node.h>
#include <node_object_wrap.h>
#include "myobject.h"

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  MyObject::NewInstance(args);
}

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
      args[0]->ToObject());
  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
      args[1]->ToObject());

  double sum = obj1->value() + obj2->value();
  args.GetReturnValue().Set(Number::New(isolate, sum));
}

void InitAll(Local<Object> exports) {
  MyObject::Init(exports->GetIsolate());

  NODE_SET_METHOD(exports, "createObject", CreateObject);
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

To make things interesting, we introduce a public method in myobject.h so we can probe private values after unwrapping the object:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Isolate* isolate);
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
  inline double value() const { return value_; }

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

The implementation of myobject.cc is similar to before:

// myobject.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Isolate* isolate) {
  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  const unsigned argc = 1;
  Local<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

}  // namespace demo

Test it with:

// test.js
const addon = require('./build/Release/addon');

var obj1 = addon.createObject(10);
var obj2 = addon.createObject(20);
var result = addon.add(obj1, obj2);

console.log(result); // 30

AtExit hooks#

void AtExit(callback, args)#

  • callback: void (*)(void*) - A pointer to the function to call at exit.
  • args: void* - A pointer to pass to the callback at exit.

Registers exit hooks that run after the event loop has ended but before the VM is killed.

Callbacks are run in last-in first-out order. AtExit takes two parameters: a pointer to a callback function to run at exit, and a pointer to untyped context data to be passed to that callback.

The file addon.cc implements AtExit below:

// addon.cc
#undef NDEBUG
#include <assert.h>
#include <stdlib.h>
#include <node.h>

namespace demo {

using node::AtExit;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Object;

static char cookie[] = "yum yum";
static int at_exit_cb1_called = 0;
static int at_exit_cb2_called = 0;

static void at_exit_cb1(void* arg) {
  Isolate* isolate = static_cast<Isolate*>(arg);
  HandleScope scope(isolate);
  Local<Object> obj = Object::New(isolate);
  assert(!obj.IsEmpty()); // assert VM is still alive
  assert(obj->IsObject());
  at_exit_cb1_called++;
}

static void at_exit_cb2(void* arg) {
  assert(arg == static_cast<void*>(cookie));
  at_exit_cb2_called++;
}

static void sanity_check(void*) {
  assert(at_exit_cb1_called == 1);
  assert(at_exit_cb2_called == 2);
}

void init(Local<Object> exports) {
  AtExit(sanity_check);
  AtExit(at_exit_cb2, cookie);
  AtExit(at_exit_cb2, cookie);
  AtExit(at_exit_cb1, exports->GetIsolate());
}

NODE_MODULE(addon, init);

}  // namespace demo

Test in JavaScript by running:

// test.js
const addon = require('./build/Release/addon');
node-v4.2.6/doc/api/addons.json000644 000766 000024 00000066561 12650222331 016441 0ustar00iojsstaff000000 000000 { "source": "doc/api/addons.markdown", "modules": [ { "textRaw": "Addons", "name": "addons", "desc": "

Addons are dynamically-linked shared objects. They can provide glue to C and\nC++ libraries. The API (at the moment) is rather complex, involving\nknowledge of several libraries:\n\n

\n
    \n
  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript:\ncreating objects, calling functions, etc. Documented mostly in the\nv8.h header file (deps/v8/include/v8.h in the Node.js source\ntree), which is also available [online][].

    \n
  • \n
  • [libuv][], C event loop library. Anytime one needs to wait for a file\ndescriptor to become readable, wait for a timer, or wait for a signal\nto be received, one will need to interface with libuv. That is, if you\nperform any I/O, libuv will need to be used.

    \n
  • \n
  • Internal Node.js libraries. The most important class is node::ObjectWrap\nwhich you will likely want to derive from.

    \n
  • \n
  • Others. Look in deps/ for what else is available.

    \n
  • \n
\n

Node.js statically compiles all its dependencies into the executable.\nWhen compiling your module, you don't need to worry about linking to\nany of these libraries.\n\n

\n

All of the following examples are available for [download][] and may\nbe used as a starting-point for your own Addon.\n\n

\n", "modules": [ { "textRaw": "Hello world", "name": "hello_world", "desc": "

To get started, let's make a small Addon which is the C++ equivalent of\nthe following JavaScript code:\n\n

\n
module.exports.hello = function() { return 'world'; };
\n

First we create a file hello.cc:\n\n

\n
// hello.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));\n}\n\nvoid init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, "hello", Method);\n}\n\nNODE_MODULE(addon, init)\n\n}  // namespace demo
\n

Note that all Node.js addons must export an initialization function:\n\n

\n
void Initialize(Local<Object> exports);\nNODE_MODULE(module_name, Initialize)
\n

There is no semi-colon after NODE_MODULE as it's not a function (see\nnode.h).\n\n

\n

The module_name needs to match the filename of the final binary (excluding\nthe .node suffix).\n\n

\n

The source code needs to be built into addon.node, the binary Addon. To\ndo this, we create a file called binding.gyp which describes the configuration\nto build your module in a JSON-like format. This file gets compiled by\n[node-gyp][].\n\n

\n
{\n  "targets": [\n    {\n      "target_name": "addon",\n      "sources": [ "hello.cc" ]\n    }\n  ]\n}
\n

The next step is to generate the appropriate project build files for the\ncurrent platform. Use node-gyp configure for that.\n\n

\n

Now you will have either a Makefile (on Unix platforms) or a vcxproj file\n(on Windows) in the build/ directory. Next, invoke the node-gyp build\ncommand.\n\n

\n

Now you have your compiled .node bindings file! The compiled bindings end up\nin build/Release/.\n\n

\n

You can now use the binary addon in a Node.js project hello.js by pointing\nrequire to the recently built hello.node module:\n\n

\n
// hello.js\nconst addon = require('./build/Release/addon');\n\nconsole.log(addon.hello()); // 'world'
\n

Please see patterns below for further information or\n

\n

https://github.com/arturadib/node-qt for an example in production.\n\n\n

\n", "type": "module", "displayName": "Hello world" }, { "textRaw": "Addon patterns", "name": "addon_patterns", "desc": "

Below are some addon patterns to help you get started. Consult the online\n[v8 reference][] for help with the various v8 calls, and v8's\n[Embedder's Guide][] for an explanation of several concepts used such as\nhandles, scopes, function templates, etc.\n\n

\n

In order to use these examples, you need to compile them using node-gyp.\nCreate the following binding.gyp file:\n\n

\n
{\n  "targets": [\n    {\n      "target_name": "addon",\n      "sources": [ "addon.cc" ]\n    }\n  ]\n}
\n

In cases where there is more than one .cc file, simply add the file name to\nthe sources array. For example:\n\n

\n
"sources": ["addon.cc", "myexample.cc"]
\n

Now that you have your binding.gyp ready, you can configure and build the\naddon:\n\n

\n
$ node-gyp configure build
\n", "modules": [ { "textRaw": "Function arguments", "name": "function_arguments", "desc": "

The following pattern illustrates how to read arguments from JavaScript\nfunction calls and return a result. This is the main and only needed source\naddon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Exception;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.Length() < 2) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, "Wrong number of arguments")));\n    return;\n  }\n\n  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, "Wrong arguments")));\n    return;\n  }\n\n  double value = args[0]->NumberValue() + args[1]->NumberValue();\n  Local<Number> num = Number::New(isolate, value);\n\n  args.GetReturnValue().Set(num);\n}\n\nvoid Init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, "add", Add);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

You can test it with the following JavaScript snippet:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nconsole.log( 'This should be eight:', addon.add(3,5) );
\n", "type": "module", "displayName": "Function arguments" }, { "textRaw": "Callbacks", "name": "callbacks", "desc": "

You can pass JavaScript functions to a C++ function and execute them from\nthere. Here's addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Null;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid RunCallback(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Function> cb = Local<Function>::Cast(args[0]);\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };\n  cb->Call(Null(isolate), argc, argv);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", RunCallback);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

Note that this example uses a two-argument form of Init() that receives\nthe full module object as the second argument. This allows the addon\nto completely overwrite exports with a single function instead of\nadding the function as a property of exports.\n\n

\n

To test it, run the following JavaScript snippet:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\naddon(function(msg){\n  console.log(msg); // 'hello world'\n});
\n", "type": "module", "displayName": "Callbacks" }, { "textRaw": "Object factory", "name": "object_factory", "desc": "

You can create and return new objects from within a C++ function with this\naddon.cc pattern, which returns an object with property msg that echoes\nthe string passed to createObject():\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<Object> obj = Object::New(isolate);\n  obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());\n\n  args.GetReturnValue().Set(obj);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", CreateObject);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

To test it in JavaScript:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj1 = addon('hello');\nvar obj2 = addon('world');\nconsole.log(obj1.msg+' '+obj2.msg); // 'hello world'
\n", "type": "module", "displayName": "Object factory" }, { "textRaw": "Function factory", "name": "function_factory", "desc": "

This pattern illustrates how to create and return a JavaScript function that\nwraps a C++ function:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid MyFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));\n}\n\nvoid CreateFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);\n  Local<Function> fn = tpl->GetFunction();\n\n  // omit this to make it anonymous\n  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));\n\n  args.GetReturnValue().Set(fn);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", CreateFunction);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

To test:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar fn = addon();\nconsole.log(fn()); // 'hello world'
\n", "type": "module", "displayName": "Function factory" }, { "textRaw": "Wrapping C++ objects", "name": "wrapping_c++_objects", "desc": "

Here, we will create a wrapper for a C++ object/class MyObject that can be\ninstantiated in JavaScript through the new operator. First, prepare the main\nmodule addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Local;\nusing v8::Object;\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

Then, in myobject.h, make your wrapper inherit from node::ObjectWrap:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Local<v8::Object> exports);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

And in myobject.cc, implement the various methods that you want to expose.\nHere we expose the method plusOne by adding it to the constructor's\nprototype:\n\n

\n
// myobject.cc\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Local<Object> exports) {\n  Isolate* isolate = exports->GetIsolate();\n\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n  exports->Set(String::NewFromUtf8(isolate, "MyObject"),\n               tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj = new addon.MyObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13
\n", "type": "module", "displayName": "Wrapping C++ objects" }, { "textRaw": "Factory of wrapped objects", "name": "factory_of_wrapped_objects", "desc": "

This is useful when you want to be able to create native objects without\nexplicitly instantiating them with the new operator in JavaScript. For\nexample:\n\n

\n
var obj = addon.createObject();\n// instead of:\n// var obj = new addon.Object();
\n

Let's register our createObject method in addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports, Local<Object> module) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(module, "exports", CreateObject);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

In myobject.h, we now introduce the static method NewInstance that takes\ncare of instantiating the object. In other words, it does the job of new in\nJavaScript:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

The implementation is similar to the above in myobject.cc:\n\n

\n
// myobject.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Object> instance = cons->NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst createObject = require('./build/Release/addon');\n\nvar obj = createObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13\n\nvar obj2 = createObject(20);\nconsole.log( obj2.plusOne() ); // 21\nconsole.log( obj2.plusOne() ); // 22\nconsole.log( obj2.plusOne() ); // 23
\n", "type": "module", "displayName": "Factory of wrapped objects" }, { "textRaw": "Passing wrapped objects around", "name": "passing_wrapped_objects_around", "desc": "

In addition to wrapping and returning C++ objects, you can pass them around\nby unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap.\nIn the following addon.cc, we introduce a function add() that can take on\ntwo MyObject objects:\n\n

\n
// addon.cc\n#include <node.h>\n#include <node_object_wrap.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(\n      args[0]->ToObject());\n  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(\n      args[1]->ToObject());\n\n  double sum = obj1->value() + obj2->value();\n  args.GetReturnValue().Set(Number::New(isolate, sum));\n}\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(exports, "createObject", CreateObject);\n  NODE_SET_METHOD(exports, "add", Add);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

To make things interesting, we introduce a public method in myobject.h so we\ncan probe private values after unwrapping the object:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n  inline double value() const { return value_; }\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

The implementation of myobject.cc is similar to before:\n\n

\n
// myobject.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Object> instance = cons->NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj1 = addon.createObject(10);\nvar obj2 = addon.createObject(20);\nvar result = addon.add(obj1, obj2);\n\nconsole.log(result); // 30
\n", "type": "module", "displayName": "Passing wrapped objects around" }, { "textRaw": "AtExit hooks", "name": "atexit_hooks", "modules": [ { "textRaw": "void AtExit(callback, args)", "name": "void_atexit(callback,_args)", "desc": "

Registers exit hooks that run after the event loop has ended but before the VM\nis killed.\n\n

\n

Callbacks are run in last-in first-out order. AtExit takes two parameters:\na pointer to a callback function to run at exit, and a pointer to untyped\ncontext data to be passed to that callback.\n\n

\n

The file addon.cc implements AtExit below:\n\n

\n
// addon.cc\n#undef NDEBUG\n#include <assert.h>\n#include <stdlib.h>\n#include <node.h>\n\nnamespace demo {\n\nusing node::AtExit;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\n\nstatic char cookie[] = "yum yum";\nstatic int at_exit_cb1_called = 0;\nstatic int at_exit_cb2_called = 0;\n\nstatic void at_exit_cb1(void* arg) {\n  Isolate* isolate = static_cast<Isolate*>(arg);\n  HandleScope scope(isolate);\n  Local<Object> obj = Object::New(isolate);\n  assert(!obj.IsEmpty()); // assert VM is still alive\n  assert(obj->IsObject());\n  at_exit_cb1_called++;\n}\n\nstatic void at_exit_cb2(void* arg) {\n  assert(arg == static_cast<void*>(cookie));\n  at_exit_cb2_called++;\n}\n\nstatic void sanity_check(void*) {\n  assert(at_exit_cb1_called == 1);\n  assert(at_exit_cb2_called == 2);\n}\n\nvoid init(Local<Object> exports) {\n  AtExit(sanity_check);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb1, exports->GetIsolate());\n}\n\nNODE_MODULE(addon, init);\n\n}  // namespace demo
\n

Test in JavaScript by running:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');
\n", "type": "module", "displayName": "void AtExit(callback, args)" } ], "type": "module", "displayName": "AtExit hooks" } ], "type": "module", "displayName": "Addon patterns" } ], "type": "module", "displayName": "Addons" } ] } node-v4.2.6/doc/api/addons.markdown000644 000766 000024 00000056627 12650222326 017320 0ustar00iojsstaff000000 000000 # Addons Addons are dynamically-linked shared objects. They can provide glue to C and C++ libraries. The API (at the moment) is rather complex, involving knowledge of several libraries: - V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the `v8.h` header file (`deps/v8/include/v8.h` in the Node.js source tree), which is also available [online][]. - [libuv][], C event loop library. Anytime one needs to wait for a file descriptor to become readable, wait for a timer, or wait for a signal to be received, one will need to interface with libuv. That is, if you perform any I/O, libuv will need to be used. - Internal Node.js libraries. The most important class is `node::ObjectWrap` which you will likely want to derive from. - Others. Look in `deps/` for what else is available. Node.js statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries. All of the following examples are available for [download][] and may be used as a starting-point for your own Addon. ## Hello world To get started, let's make a small Addon which is the C++ equivalent of the following JavaScript code: module.exports.hello = function() { return 'world'; }; First we create a file `hello.cc`: // hello.cc #include namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void Method(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world")); } void init(Local exports) { NODE_SET_METHOD(exports, "hello", Method); } NODE_MODULE(addon, init) } // namespace demo Note that all Node.js addons must export an initialization function: void Initialize(Local exports); NODE_MODULE(module_name, Initialize) There is no semi-colon after `NODE_MODULE` as it's not a function (see `node.h`). The `module_name` needs to match the filename of the final binary (excluding the .node suffix). The source code needs to be built into `addon.node`, the binary Addon. To do this, we create a file called `binding.gyp` which describes the configuration to build your module in a JSON-like format. This file gets compiled by [node-gyp][]. { "targets": [ { "target_name": "addon", "sources": [ "hello.cc" ] } ] } The next step is to generate the appropriate project build files for the current platform. Use `node-gyp configure` for that. Now you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file (on Windows) in the `build/` directory. Next, invoke the `node-gyp build` command. Now you have your compiled `.node` bindings file! The compiled bindings end up in `build/Release/`. You can now use the binary addon in a Node.js project `hello.js` by pointing `require` to the recently built `hello.node` module: // hello.js const addon = require('./build/Release/addon'); console.log(addon.hello()); // 'world' Please see patterns below for further information or for an example in production. ## Addon patterns Below are some addon patterns to help you get started. Consult the online [v8 reference][] for help with the various v8 calls, and v8's [Embedder's Guide][] for an explanation of several concepts used such as handles, scopes, function templates, etc. In order to use these examples, you need to compile them using `node-gyp`. Create the following `binding.gyp` file: { "targets": [ { "target_name": "addon", "sources": [ "addon.cc" ] } ] } In cases where there is more than one `.cc` file, simply add the file name to the `sources` array. For example: "sources": ["addon.cc", "myexample.cc"] Now that you have your `binding.gyp` ready, you can configure and build the addon: $ node-gyp configure build ### Function arguments The following pattern illustrates how to read arguments from JavaScript function calls and return a result. This is the main and only needed source `addon.cc`: // addon.cc #include namespace demo { using v8::Exception; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::String; using v8::Value; void Add(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); if (args.Length() < 2) { isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, "Wrong number of arguments"))); return; } if (!args[0]->IsNumber() || !args[1]->IsNumber()) { isolate->ThrowException(Exception::TypeError( String::NewFromUtf8(isolate, "Wrong arguments"))); return; } double value = args[0]->NumberValue() + args[1]->NumberValue(); Local num = Number::New(isolate, value); args.GetReturnValue().Set(num); } void Init(Local exports) { NODE_SET_METHOD(exports, "add", Add); } NODE_MODULE(addon, Init) } // namespace demo You can test it with the following JavaScript snippet: // test.js const addon = require('./build/Release/addon'); console.log( 'This should be eight:', addon.add(3,5) ); ### Callbacks You can pass JavaScript functions to a C++ function and execute them from there. Here's `addon.cc`: // addon.cc #include namespace demo { using v8::Function; using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Null; using v8::Object; using v8::String; using v8::Value; void RunCallback(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); Local cb = Local::Cast(args[0]); const unsigned argc = 1; Local argv[argc] = { String::NewFromUtf8(isolate, "hello world") }; cb->Call(Null(isolate), argc, argv); } void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", RunCallback); } NODE_MODULE(addon, Init) } // namespace demo Note that this example uses a two-argument form of `Init()` that receives the full `module` object as the second argument. This allows the addon to completely overwrite `exports` with a single function instead of adding the function as a property of `exports`. To test it, run the following JavaScript snippet: // test.js const addon = require('./build/Release/addon'); addon(function(msg){ console.log(msg); // 'hello world' }); ### Object factory You can create and return new objects from within a C++ function with this `addon.cc` pattern, which returns an object with property `msg` that echoes the string passed to `createObject()`: // addon.cc #include namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); Local obj = Object::New(isolate); obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString()); args.GetReturnValue().Set(obj); } void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", CreateObject); } NODE_MODULE(addon, Init) } // namespace demo To test it in JavaScript: // test.js const addon = require('./build/Release/addon'); var obj1 = addon('hello'); var obj2 = addon('world'); console.log(obj1.msg+' '+obj2.msg); // 'hello world' ### Function factory This pattern illustrates how to create and return a JavaScript function that wraps a C++ function: // addon.cc #include namespace demo { using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void MyFunction(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world")); } void CreateFunction(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); Local tpl = FunctionTemplate::New(isolate, MyFunction); Local fn = tpl->GetFunction(); // omit this to make it anonymous fn->SetName(String::NewFromUtf8(isolate, "theFunction")); args.GetReturnValue().Set(fn); } void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", CreateFunction); } NODE_MODULE(addon, Init) } // namespace demo To test: // test.js const addon = require('./build/Release/addon'); var fn = addon(); console.log(fn()); // 'hello world' ### Wrapping C++ objects Here, we will create a wrapper for a C++ object/class `MyObject` that can be instantiated in JavaScript through the `new` operator. First, prepare the main module `addon.cc`: // addon.cc #include #include "myobject.h" namespace demo { using v8::Local; using v8::Object; void InitAll(Local exports) { MyObject::Init(exports); } NODE_MODULE(addon, InitAll) } // namespace demo Then, in `myobject.h`, make your wrapper inherit from `node::ObjectWrap`: // myobject.h #ifndef MYOBJECT_H #define MYOBJECT_H #include #include namespace demo { class MyObject : public node::ObjectWrap { public: static void Init(v8::Local exports); private: explicit MyObject(double value = 0); ~MyObject(); static void New(const v8::FunctionCallbackInfo& args); static void PlusOne(const v8::FunctionCallbackInfo& args); static v8::Persistent constructor; double value_; }; } // namespace demo #endif And in `myobject.cc`, implement the various methods that you want to expose. Here we expose the method `plusOne` by adding it to the constructor's prototype: // myobject.cc #include "myobject.h" namespace demo { using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::Persistent; using v8::String; using v8::Value; Persistent MyObject::constructor; MyObject::MyObject(double value) : value_(value) { } MyObject::~MyObject() { } void MyObject::Init(Local exports) { Isolate* isolate = exports->GetIsolate(); // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); constructor.Reset(isolate, tpl->GetFunction()); exports->Set(String::NewFromUtf8(isolate, "MyObject"), tpl->GetFunction()); } void MyObject::New(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); MyObject* obj = new MyObject(value); obj->Wrap(args.This()); args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. const int argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); args.GetReturnValue().Set(cons->NewInstance(argc, argv)); } } void MyObject::PlusOne(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); MyObject* obj = ObjectWrap::Unwrap(args.Holder()); obj->value_ += 1; args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo Test it with: // test.js const addon = require('./build/Release/addon'); var obj = new addon.MyObject(10); console.log( obj.plusOne() ); // 11 console.log( obj.plusOne() ); // 12 console.log( obj.plusOne() ); // 13 ### Factory of wrapped objects This is useful when you want to be able to create native objects without explicitly instantiating them with the `new` operator in JavaScript. For example: var obj = addon.createObject(); // instead of: // var obj = new addon.Object(); Let's register our `createObject` method in `addon.cc`: // addon.cc #include #include "myobject.h" namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Object; using v8::String; using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { MyObject::NewInstance(args); } void InitAll(Local exports, Local module) { MyObject::Init(exports->GetIsolate()); NODE_SET_METHOD(module, "exports", CreateObject); } NODE_MODULE(addon, InitAll) } // namespace demo In `myobject.h`, we now introduce the static method `NewInstance` that takes care of instantiating the object. In other words, it does the job of `new` in JavaScript: // myobject.h #ifndef MYOBJECT_H #define MYOBJECT_H #include #include namespace demo { class MyObject : public node::ObjectWrap { public: static void Init(v8::Isolate* isolate); static void NewInstance(const v8::FunctionCallbackInfo& args); private: explicit MyObject(double value = 0); ~MyObject(); static void New(const v8::FunctionCallbackInfo& args); static void PlusOne(const v8::FunctionCallbackInfo& args); static v8::Persistent constructor; double value_; }; } // namespace demo #endif The implementation is similar to the above in `myobject.cc`: // myobject.cc #include #include "myobject.h" namespace demo { using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::Persistent; using v8::String; using v8::Value; Persistent MyObject::constructor; MyObject::MyObject(double value) : value_(value) { } MyObject::~MyObject() { } void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); tpl->InstanceTemplate()->SetInternalFieldCount(1); // Prototype NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne); constructor.Reset(isolate, tpl->GetFunction()); } void MyObject::New(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); MyObject* obj = new MyObject(value); obj->Wrap(args.This()); args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. const int argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); args.GetReturnValue().Set(cons->NewInstance(argc, argv)); } } void MyObject::NewInstance(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); Local instance = cons->NewInstance(argc, argv); args.GetReturnValue().Set(instance); } void MyObject::PlusOne(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); MyObject* obj = ObjectWrap::Unwrap(args.Holder()); obj->value_ += 1; args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } } // namespace demo Test it with: // test.js const createObject = require('./build/Release/addon'); var obj = createObject(10); console.log( obj.plusOne() ); // 11 console.log( obj.plusOne() ); // 12 console.log( obj.plusOne() ); // 13 var obj2 = createObject(20); console.log( obj2.plusOne() ); // 21 console.log( obj2.plusOne() ); // 22 console.log( obj2.plusOne() ); // 23 ### Passing wrapped objects around In addition to wrapping and returning C++ objects, you can pass them around by unwrapping them with the Node.js helper function `node::ObjectWrap::Unwrap`. In the following `addon.cc`, we introduce a function `add()` that can take on two `MyObject` objects: // addon.cc #include #include #include "myobject.h" namespace demo { using v8::FunctionCallbackInfo; using v8::Isolate; using v8::Local; using v8::Number; using v8::Object; using v8::String; using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { MyObject::NewInstance(args); } void Add(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); MyObject* obj1 = node::ObjectWrap::Unwrap( args[0]->ToObject()); MyObject* obj2 = node::ObjectWrap::Unwrap( args[1]->ToObject()); double sum = obj1->value() + obj2->value(); args.GetReturnValue().Set(Number::New(isolate, sum)); } void InitAll(Local exports) { MyObject::Init(exports->GetIsolate()); NODE_SET_METHOD(exports, "createObject", CreateObject); NODE_SET_METHOD(exports, "add", Add); } NODE_MODULE(addon, InitAll) } // namespace demo To make things interesting, we introduce a public method in `myobject.h` so we can probe private values after unwrapping the object: // myobject.h #ifndef MYOBJECT_H #define MYOBJECT_H #include #include namespace demo { class MyObject : public node::ObjectWrap { public: static void Init(v8::Isolate* isolate); static void NewInstance(const v8::FunctionCallbackInfo& args); inline double value() const { return value_; } private: explicit MyObject(double value = 0); ~MyObject(); static void New(const v8::FunctionCallbackInfo& args); static v8::Persistent constructor; double value_; }; } // namespace demo #endif The implementation of `myobject.cc` is similar to before: // myobject.cc #include #include "myobject.h" namespace demo { using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::Isolate; using v8::Local; using v8::Object; using v8::Persistent; using v8::String; using v8::Value; Persistent MyObject::constructor; MyObject::MyObject(double value) : value_(value) { } MyObject::~MyObject() { } void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); tpl->InstanceTemplate()->SetInternalFieldCount(1); constructor.Reset(isolate, tpl->GetFunction()); } void MyObject::New(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); MyObject* obj = new MyObject(value); obj->Wrap(args.This()); args.GetReturnValue().Set(args.This()); } else { // Invoked as plain function `MyObject(...)`, turn into construct call. const int argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); args.GetReturnValue().Set(cons->NewInstance(argc, argv)); } } void MyObject::NewInstance(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); Local instance = cons->NewInstance(argc, argv); args.GetReturnValue().Set(instance); } } // namespace demo Test it with: // test.js const addon = require('./build/Release/addon'); var obj1 = addon.createObject(10); var obj2 = addon.createObject(20); var result = addon.add(obj1, obj2); console.log(result); // 30 ### AtExit hooks #### void AtExit(callback, args) * `callback`: `void (*)(void*)` - A pointer to the function to call at exit. * `args`: `void*` - A pointer to pass to the callback at exit. Registers exit hooks that run after the event loop has ended but before the VM is killed. Callbacks are run in last-in first-out order. AtExit takes two parameters: a pointer to a callback function to run at exit, and a pointer to untyped context data to be passed to that callback. The file `addon.cc` implements AtExit below: // addon.cc #undef NDEBUG #include #include #include namespace demo { using node::AtExit; using v8::HandleScope; using v8::Isolate; using v8::Local; using v8::Object; static char cookie[] = "yum yum"; static int at_exit_cb1_called = 0; static int at_exit_cb2_called = 0; static void at_exit_cb1(void* arg) { Isolate* isolate = static_cast(arg); HandleScope scope(isolate); Local obj = Object::New(isolate); assert(!obj.IsEmpty()); // assert VM is still alive assert(obj->IsObject()); at_exit_cb1_called++; } static void at_exit_cb2(void* arg) { assert(arg == static_cast(cookie)); at_exit_cb2_called++; } static void sanity_check(void*) { assert(at_exit_cb1_called == 1); assert(at_exit_cb2_called == 2); } void init(Local exports) { AtExit(sanity_check); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb1, exports->GetIsolate()); } NODE_MODULE(addon, init); } // namespace demo Test in JavaScript by running: // test.js const addon = require('./build/Release/addon'); [online]: https://v8docs.nodesource.com/ [libuv]: https://github.com/libuv/libuv [download]: https://github.com/nodejs/node-addon-examples [node-gyp]: https://github.com/nodejs/node-gyp [v8 reference]: http://izs.me/v8-docs/main.html [Embedder's Guide]: https://code.google.com/apis/v8/embed.html node-v4.2.6/doc/api/all.html000644 000766 000024 00003252734 12650222331 015736 0ustar00iojsstaff000000 000000 About this Documentation Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

About this Documentation#

The goal of this documentation is to comprehensively explain the Node.js API, both from a reference as well as a conceptual point of view. Each section describes a built-in module or high-level concept.

Where appropriate, property types, method arguments, and the arguments provided to event handlers are detailed in a list underneath the topic heading.

Every .html document has a corresponding .json document presenting the same information in a structured manner. This feature is experimental, and added for the benefit of IDEs and other utilities that wish to do programmatic things with the documentation.

Every .html and .json file is generated based on the corresponding .markdown file in the doc/api/ folder in Node.js's source tree. The documentation is generated using the tools/doc/generate.js program. The HTML template is located at doc/template.html.

Stability Index#

Throughout the documentation, you will see indications of a section's stability. The Node.js API is still somewhat changing, and as it matures, certain parts are more reliable than others. Some are so proven, and so relied upon, that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous and in the process of being redesigned.

The stability indices are as follows:

Stability: 0 - Deprecated
This feature is known to be problematic, and changes are
planned.  Do not rely on it.  Use of the feature may cause warnings.  Backwards
compatibility should not be expected.
Stability: 1 - Experimental
This feature is subject to change, and is gated by a command line flag.
It may change or be removed in future versions.
Stability: 2 - Stable
The API has proven satisfactory. Compatibility with the npm ecosystem
is a high priority, and will not be broken unless absolutely necessary.
Stability: 3 - Locked
Only fixes related to security, performance, or bug fixes will be accepted.
Please do not suggest API changes in this area; they will be refused.

JSON Output#

Stability: 1 - Experimental

Every HTML file in the markdown has a corresponding JSON file with the same data.

This feature was added in Node.js v0.6.12. It is experimental.

Synopsis#

An example of a web server written with Node.js which responds with 'Hello World':

const http = require('http');

http.createServer( (request, response) => {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

To run the server, put the code into a file called example.js and execute it with the node program

> node example.js
Server running at http://127.0.0.1:8124/

All of the examples in the documentation can be run similarly.

Addons#

Addons are dynamically-linked shared objects. They can provide glue to C and C++ libraries. The API (at the moment) is rather complex, involving knowledge of several libraries:

  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript: creating objects, calling functions, etc. Documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node.js source tree), which is also available online.

  • libuv, C event loop library. Anytime one needs to wait for a file descriptor to become readable, wait for a timer, or wait for a signal to be received, one will need to interface with libuv. That is, if you perform any I/O, libuv will need to be used.

  • Internal Node.js libraries. The most important class is node::ObjectWrap which you will likely want to derive from.

  • Others. Look in deps/ for what else is available.

Node.js statically compiles all its dependencies into the executable. When compiling your module, you don't need to worry about linking to any of these libraries.

All of the following examples are available for download and may be used as a starting-point for your own Addon.

Hello world#

To get started, let's make a small Addon which is the C++ equivalent of the following JavaScript code:

module.exports.hello = function() { return 'world'; };

First we create a file hello.cc:

// hello.cc
#include <node.h>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void Method(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(addon, init)

}  // namespace demo

Note that all Node.js addons must export an initialization function:

void Initialize(Local<Object> exports);
NODE_MODULE(module_name, Initialize)

There is no semi-colon after NODE_MODULE as it's not a function (see node.h).

The module_name needs to match the filename of the final binary (excluding the .node suffix).

The source code needs to be built into addon.node, the binary Addon. To do this, we create a file called binding.gyp which describes the configuration to build your module in a JSON-like format. This file gets compiled by node-gyp.

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "hello.cc" ]
    }
  ]
}

The next step is to generate the appropriate project build files for the current platform. Use node-gyp configure for that.

Now you will have either a Makefile (on Unix platforms) or a vcxproj file (on Windows) in the build/ directory. Next, invoke the node-gyp build command.

Now you have your compiled .node bindings file! The compiled bindings end up in build/Release/.

You can now use the binary addon in a Node.js project hello.js by pointing require to the recently built hello.node module:

// hello.js
const addon = require('./build/Release/addon');

console.log(addon.hello()); // 'world'

Please see patterns below for further information or

https://github.com/arturadib/node-qt for an example in production.

Addon patterns#

Below are some addon patterns to help you get started. Consult the online v8 reference for help with the various v8 calls, and v8's Embedder's Guide for an explanation of several concepts used such as handles, scopes, function templates, etc.

In order to use these examples, you need to compile them using node-gyp. Create the following binding.gyp file:

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "addon.cc" ]
    }
  ]
}

In cases where there is more than one .cc file, simply add the file name to the sources array. For example:

"sources": ["addon.cc", "myexample.cc"]

Now that you have your binding.gyp ready, you can configure and build the addon:

$ node-gyp configure build

Function arguments#

The following pattern illustrates how to read arguments from JavaScript function calls and return a result. This is the main and only needed source addon.cc:

// addon.cc
#include <node.h>

namespace demo {

using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.Length() < 2) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong number of arguments")));
    return;
  }

  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
    isolate->ThrowException(Exception::TypeError(
        String::NewFromUtf8(isolate, "Wrong arguments")));
    return;
  }

  double value = args[0]->NumberValue() + args[1]->NumberValue();
  Local<Number> num = Number::New(isolate, value);

  args.GetReturnValue().Set(num);
}

void Init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, Init)

}  // namespace demo

You can test it with the following JavaScript snippet:

// test.js
const addon = require('./build/Release/addon');

console.log( 'This should be eight:', addon.add(3,5) );

Callbacks#

You can pass JavaScript functions to a C++ function and execute them from there. Here's addon.cc:

// addon.cc
#include <node.h>

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Null;
using v8::Object;
using v8::String;
using v8::Value;

void RunCallback(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  Local<Function> cb = Local<Function>::Cast(args[0]);
  const unsigned argc = 1;
  Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };
  cb->Call(Null(isolate), argc, argv);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", RunCallback);
}

NODE_MODULE(addon, Init)

}  // namespace demo

Note that this example uses a two-argument form of Init() that receives the full module object as the second argument. This allows the addon to completely overwrite exports with a single function instead of adding the function as a property of exports.

To test it, run the following JavaScript snippet:

// test.js
const addon = require('./build/Release/addon');

addon(function(msg){
  console.log(msg); // 'hello world'
});

Object factory#

You can create and return new objects from within a C++ function with this addon.cc pattern, which returns an object with property msg that echoes the string passed to createObject():

// addon.cc
#include <node.h>

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  Local<Object> obj = Object::New(isolate);
  obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());

  args.GetReturnValue().Set(obj);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, Init)

}  // namespace demo

To test it in JavaScript:

// test.js
const addon = require('./build/Release/addon');

var obj1 = addon('hello');
var obj2 = addon('world');
console.log(obj1.msg+' '+obj2.msg); // 'hello world'

Function factory#

This pattern illustrates how to create and return a JavaScript function that wraps a C++ function:

// addon.cc
#include <node.h>

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void MyFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
}

void CreateFunction(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);
  Local<Function> fn = tpl->GetFunction();

  // omit this to make it anonymous
  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));

  args.GetReturnValue().Set(fn);
}

void Init(Local<Object> exports, Local<Object> module) {
  NODE_SET_METHOD(module, "exports", CreateFunction);
}

NODE_MODULE(addon, Init)

}  // namespace demo

To test:

// test.js
const addon = require('./build/Release/addon');

var fn = addon();
console.log(fn()); // 'hello world'

Wrapping C++ objects#

Here, we will create a wrapper for a C++ object/class MyObject that can be instantiated in JavaScript through the new operator. First, prepare the main module addon.cc:

// addon.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Local;
using v8::Object;

void InitAll(Local<Object> exports) {
  MyObject::Init(exports);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

Then, in myobject.h, make your wrapper inherit from node::ObjectWrap:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Local<v8::Object> exports);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

And in myobject.cc, implement the various methods that you want to expose. Here we expose the method plusOne by adding it to the constructor's prototype:

// myobject.cc
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Local<Object> exports) {
  Isolate* isolate = exports->GetIsolate();

  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
  exports->Set(String::NewFromUtf8(isolate, "MyObject"),
               tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}

}  // namespace demo

Test it with:

// test.js
const addon = require('./build/Release/addon');

var obj = new addon.MyObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

Factory of wrapped objects#

This is useful when you want to be able to create native objects without explicitly instantiating them with the new operator in JavaScript. For example:

var obj = addon.createObject();
// instead of:
// var obj = new addon.Object();

Let's register our createObject method in addon.cc:

// addon.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  MyObject::NewInstance(args);
}

void InitAll(Local<Object> exports, Local<Object> module) {
  MyObject::Init(exports->GetIsolate());

  NODE_SET_METHOD(module, "exports", CreateObject);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

In myobject.h, we now introduce the static method NewInstance that takes care of instantiating the object. In other words, it does the job of new in JavaScript:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Isolate* isolate);
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

The implementation is similar to the above in myobject.cc:

// myobject.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Isolate* isolate) {
  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  // Prototype
  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  const unsigned argc = 1;
  Local<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

void MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());
  obj->value_ += 1;

  args.GetReturnValue().Set(Number::New(isolate, obj->value_));
}

}  // namespace demo

Test it with:

// test.js
const createObject = require('./build/Release/addon');

var obj = createObject(10);
console.log( obj.plusOne() ); // 11
console.log( obj.plusOne() ); // 12
console.log( obj.plusOne() ); // 13

var obj2 = createObject(20);
console.log( obj2.plusOne() ); // 21
console.log( obj2.plusOne() ); // 22
console.log( obj2.plusOne() ); // 23

Passing wrapped objects around#

In addition to wrapping and returning C++ objects, you can pass them around by unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap. In the following addon.cc, we introduce a function add() that can take on two MyObject objects:

// addon.cc
#include <node.h>
#include <node_object_wrap.h>
#include "myobject.h"

namespace demo {

using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Value;

void CreateObject(const FunctionCallbackInfo<Value>& args) {
  MyObject::NewInstance(args);
}

void Add(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
      args[0]->ToObject());
  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
      args[1]->ToObject());

  double sum = obj1->value() + obj2->value();
  args.GetReturnValue().Set(Number::New(isolate, sum));
}

void InitAll(Local<Object> exports) {
  MyObject::Init(exports->GetIsolate());

  NODE_SET_METHOD(exports, "createObject", CreateObject);
  NODE_SET_METHOD(exports, "add", Add);
}

NODE_MODULE(addon, InitAll)

}  // namespace demo

To make things interesting, we introduce a public method in myobject.h so we can probe private values after unwrapping the object:

// myobject.h
#ifndef MYOBJECT_H
#define MYOBJECT_H

#include <node.h>
#include <node_object_wrap.h>

namespace demo {

class MyObject : public node::ObjectWrap {
 public:
  static void Init(v8::Isolate* isolate);
  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
  inline double value() const { return value_; }

 private:
  explicit MyObject(double value = 0);
  ~MyObject();

  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
  static v8::Persistent<v8::Function> constructor;
  double value_;
};

}  // namespace demo

#endif

The implementation of myobject.cc is similar to before:

// myobject.cc
#include <node.h>
#include "myobject.h"

namespace demo {

using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::Persistent;
using v8::String;
using v8::Value;

Persistent<Function> MyObject::constructor;

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

void MyObject::Init(Isolate* isolate) {
  // Prepare constructor template
  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);
  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  constructor.Reset(isolate, tpl->GetFunction());
}

void MyObject::New(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  if (args.IsConstructCall()) {
    // Invoked as constructor: `new MyObject(...)`
    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
    MyObject* obj = new MyObject(value);
    obj->Wrap(args.This());
    args.GetReturnValue().Set(args.This());
  } else {
    // Invoked as plain function `MyObject(...)`, turn into construct call.
    const int argc = 1;
    Local<Value> argv[argc] = { args[0] };
    Local<Function> cons = Local<Function>::New(isolate, constructor);
    args.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

void MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();

  const unsigned argc = 1;
  Local<Value> argv[argc] = { args[0] };
  Local<Function> cons = Local<Function>::New(isolate, constructor);
  Local<Object> instance = cons->NewInstance(argc, argv);

  args.GetReturnValue().Set(instance);
}

}  // namespace demo

Test it with:

// test.js
const addon = require('./build/Release/addon');

var obj1 = addon.createObject(10);
var obj2 = addon.createObject(20);
var result = addon.add(obj1, obj2);

console.log(result); // 30

AtExit hooks#

void AtExit(callback, args)#

  • callback: void (*)(void*) - A pointer to the function to call at exit.
  • args: void* - A pointer to pass to the callback at exit.

Registers exit hooks that run after the event loop has ended but before the VM is killed.

Callbacks are run in last-in first-out order. AtExit takes two parameters: a pointer to a callback function to run at exit, and a pointer to untyped context data to be passed to that callback.

The file addon.cc implements AtExit below:

// addon.cc
#undef NDEBUG
#include <assert.h>
#include <stdlib.h>
#include <node.h>

namespace demo {

using node::AtExit;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Object;

static char cookie[] = "yum yum";
static int at_exit_cb1_called = 0;
static int at_exit_cb2_called = 0;

static void at_exit_cb1(void* arg) {
  Isolate* isolate = static_cast<Isolate*>(arg);
  HandleScope scope(isolate);
  Local<Object> obj = Object::New(isolate);
  assert(!obj.IsEmpty()); // assert VM is still alive
  assert(obj->IsObject());
  at_exit_cb1_called++;
}

static void at_exit_cb2(void* arg) {
  assert(arg == static_cast<void*>(cookie));
  at_exit_cb2_called++;
}

static void sanity_check(void*) {
  assert(at_exit_cb1_called == 1);
  assert(at_exit_cb2_called == 2);
}

void init(Local<Object> exports) {
  AtExit(sanity_check);
  AtExit(at_exit_cb2, cookie);
  AtExit(at_exit_cb2, cookie);
  AtExit(at_exit_cb1, exports->GetIsolate());
}

NODE_MODULE(addon, init);

}  // namespace demo

Test in JavaScript by running:

// test.js
const addon = require('./build/Release/addon');

Assert#

Stability: 3 - Locked

The assert module provides a simple set of assertion tests that can be used to test invariants. The module is intended for internal use by Node.js, but can be used in application code via require('assert'). However, assert is not a testing framework, and is not intended to be used as a general purpose assertion library.

The API for the assert module is Locked. This means that there will be no additions or changes to any of the methods implemented and exposed by the module.

assert(value[, message]), assert.ok(value[, message])#

Tests if value is truthy. It is equivalent to assert.equal(!!value, true, message).

If value is not truthy, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

const assert = require('assert');

assert(true);  // OK
assert(1);     // OK
assert(false);
  // throws "AssertionError: false == true"
assert(0);
  // throws "AssertionError: 0 == true"
assert(false, 'it\'s false');
  // throws "AssertionError: it's false"

assert.ok(true);  // OK
assert.ok(1);     // OK
assert.ok(false);
  // throws "AssertionError: false == true"
assert.ok(0);
  // throws "AssertionError: 0 == true"
assert.ok(false, 'it\'s false');
  // throws "AssertionError: it's false"

assert.deepEqual(actual, expected[, message])#

Tests for deep equality between the actual and expected parameters. Primitive values are compared with the equal comparison operator ( == ).

Only enumerable "own" properties are considered. The deepEqual() implementation does not test object prototypes, attached symbols, or non-enumerable properties. This can lead to some potentially surprising results. For example, the following example does not throw an AssertionError because the properties on the Error object are non-enumerable:

// WARNING: This does not throw an AssertionError!
assert.deepEqual(Error('a'), Error('b'));

"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:

const assert = require('assert');

const obj1 = {
  a : {
    b : 1
  }
};
const obj2 = {
  a : {
    b : 2
  }
};
const obj3 = {
  a : {
    b : 1
  }
}
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
  // OK, object is equal to itself

assert.deepEqual(obj1, obj2);
  // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
  // values of b are different

assert.deepEqual(obj1, obj3);
  // OK, objects are equal

assert.deepEqual(obj1, obj4);
  // AssertionError: { a: { b: 1 } } deepEqual {}
  // Prototypes are ignored

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.deepStrictEqual(actual, expected[, message])#

Generally identical to assert.deepEqual with the exception that primitive values are compared using the strict equality operator ( === ).

const assert = require('assert');

assert.deepEqual({a:1}, {a:'1'});
  // OK, because 1 == '1'

assert.deepStrictEqual({a:1}, {a:'1'});
  // AssertionError: { a: 1 } deepStrictEqual { a: '1' }
  // because 1 !== '1' using strict equality

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.doesNotThrow(block[, error][, message])#

Asserts that the function block does not throw an error. See assert.throws() for more details.

When assert.doesNotThrow() is called, it will immediately call the block function.

If an error is thrown and it is the same type as that specified by the error parameter, then an AssertionError is thrown. If the error is of a different type, or if the error parameter is undefined, the error is propagated back to the caller.

The following, for instance, will throw the TypeError because there is no matching error type in the assertion:

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  SyntaxError
);

However, the following will result in an AssertionError with the message 'Got unwanted exception (TypeError)..':

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  TypeError
);

If an AssertionError is thrown and a value is provided for the message parameter, the value of message will be appended to the AssertionError message:

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  TypeError,
  'Whoops'
);
// Throws: AssertionError: Got unwanted exception (TypeError). Whoops

assert.equal(actual, expected[, message])#

Tests shallow, coercive equality between the actual and expected parameters using the equal comparison operator ( == ).

const assert = require('assert');

assert.equal(1, 1);
  // OK, 1 == 1
assert.equal(1, '1');
  // OK, 1 == '1'

assert.equal(1, 2);
  // AssertionError: 1 == 2
assert.equal({a: {b: 1}}, {a: {b: 1}});
  //AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.fail(actual, expected, message, operator)#

Throws an AssertionError. If message is falsy, the error message is set as the values of actual and expected separated by the provided operator. Otherwise, the error message is the value of message.

const assert = require('assert');

assert.fail(1, 2, undefined, '>');
  // AssertionError: 1 > 2

assert.fail(1, 2, 'whoops', '>');
  // AssertionError: whoops

assert.ifError(value)#

Throws value if value is truthy. This is useful when testing the error argument in callbacks.

const assert = require('assert');

assert.ifError(0); // OK
assert.ifError(1); // Throws 1
assert.ifError('error') // Throws 'error'
assert.ifError(new Error()); // Throws Error

assert.notDeepEqual(actual, expected[, message])#

Tests for any deep inequality. Opposite of assert.deepEqual.

const assert = require('assert');

const obj1 = {
  a : {
    b : 1
  }
};
const obj2 = {
  a : {
    b : 2
  }
};
const obj3 = {
  a : {
    b : 1
  }
}
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
  AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.deepEqual(obj1, obj2);
  // OK, obj1 and obj2 are not deeply equal

assert.deepEqual(obj1, obj3);
  // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.deepEqual(obj1, obj4);
  // OK, obj1 and obj2 are not deeply equal

If the values are deeply equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notDeepStrictEqual(actual, expected[, message])#

Tests for deep strict inequality. Opposite of assert.deepStrictEqual.

const assert = require('assert');

assert.notDeepEqual({a:1}, {a:'1'});
  // AssertionError: { a: 1 } notDeepEqual { a: '1' }

assert.notDeepStrictEqual({a:1}, {a:'1'});
  // OK

If the values are deeply and strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notEqual(actual, expected[, message])#

Tests shallow, coercive inequality with the not equal comparison operator ( != ).

const assert = require('assert');

assert.notEqual(1, 2);
  // OK

assert.notEqual(1, 1);
  // AssertionError: 1 != 1

assert.notEqual(1, '1');
  // AssertionError: 1 != '1'

If the values are equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notStrictEqual(actual, expected[, message])#

Tests strict inequality as determined by the strict not equal operator ( !== ).

const assert = require('assert');

assert.notStrictEqual(1, 2);
  // OK

assert.notStrictEqual(1, 1);
  // AssertionError: 1 != 1

assert.notStrictEqual(1, '1');
  // OK

If the values are strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.strictEqual(actual, expected[, message])#

Tests strict equality as determined by the strict equality operator ( === ).

const assert = require('assert');

assert.strictEqual(1, 2);
  // AssertionError: 1 === 2

assert.strictEqual(1, 1);
  // OK

assert.strictEqual(1, '1');
  // AssertionError: 1 === '1'

If the values are not strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.throws(block[, error][, message])#

Expects the function block to throw an error. If specified, error can be a constructor, RegExp, or validation function.

Validate instanceof using constructor:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  Error
);

Validate error message using RegExp:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  /value/
);

Custom error validation:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  function(err) {
    if ( (err instanceof Error) && /value/.test(err) ) {
      return true;
    }
  },
  'unexpected error'
);

Buffer#

Stability: 2 - Stable

Pure JavaScript is Unicode-friendly but not nice to binary data. When dealing with TCP streams or the file system, it's necessary to handle octet streams. Node.js has several strategies for manipulating, creating, and consuming octet streams.

Raw data is stored in instances of the Buffer class. A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.

The Buffer class is a global, making it very rare that one would need to ever require('buffer').

Converting between Buffers and JavaScript string objects requires an explicit encoding method. The different string encodings are:

  • 'ascii' - for 7-bit ASCII data only. This encoding method is very fast and will strip the high bit if set.

  • 'utf8' - Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.

  • 'utf16le' - 2 or 4 bytes, little-endian encoded Unicode characters. Surrogate pairs (U+10000 to U+10FFFF) are supported.

  • 'ucs2' - Alias of 'utf16le'.

  • 'base64' - Base64 string encoding.

  • 'binary' - A way of encoding the buffer into a one-byte (latin-1) encoded string. The string 'latin-1' is not supported. Instead, pass 'binary' to use 'latin-1' encoding.

  • 'hex' - Encode each byte as two hexadecimal characters.

Creating a typed array from a Buffer works with the following caveats:

  1. The buffer's memory is copied, not shared.

  2. The buffer's memory is interpreted as an array, not a byte array. That is, new Uint32Array(new Buffer([1,2,3,4])) creates a 4-element Uint32Array with elements [1,2,3,4], not a Uint32Array with a single element [0x1020304] or [0x4030201].

NOTE: Node.js v0.8 retained a reference to the buffer in array.buffer instead of cloning it.

While more efficient, it introduces subtle incompatibilities with the typed arrays specification. ArrayBuffer#slice() makes a copy of the slice while Buffer#slice() creates a view.

Class: Buffer#

The Buffer class is a global type for dealing with binary data directly. It can be constructed in a variety of ways.

new Buffer(array)#

  • array Array

Allocates a new buffer using an array of octets.

new Buffer(buffer)#

  • buffer Buffer

Copies the passed buffer data onto a new Buffer instance.

new Buffer(size)#

  • size Number

Allocates a new buffer of size bytes. size must be less than 1,073,741,824 bytes (1 GB) on 32-bit architectures or 2,147,483,648 bytes (2 GB) on 64-bit architectures. Otherwise, a RangeError is thrown.

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So the contents of a newly created Buffer are unknown and could contain sensitive data. Use buf.fill(0) to initialize a buffer to zeroes.

new Buffer(str[, encoding])#

  • str String - string to encode.
  • encoding String - encoding to use, Optional.

Allocates a new buffer containing the given str. encoding defaults to 'utf8'.

Class Method: Buffer.byteLength(string[, encoding])#

  • string String
  • encoding String, Optional, Default: 'utf8'
  • Return: Number

Gives the actual byte length of a string. encoding defaults to 'utf8'. This is not the same as String.prototype.length since that returns the number of characters in a string.

Example:

str = '\u00bd + \u00bc = \u00be';

console.log(`${str}: ${str.length} characters, ` +
            `${Buffer.byteLength(str, 'utf8')} bytes`);

// ½ + ¼ = ¾: 9 characters, 12 bytes

Class Method: Buffer.compare(buf1, buf2)#

  • buf1 Buffer
  • buf2 Buffer

The same as buf1.compare(buf2). Useful for sorting an Array of Buffers:

var arr = [Buffer('1234'), Buffer('0123')];
arr.sort(Buffer.compare);

Class Method: Buffer.concat(list[, totalLength])#

  • list Array List of Buffer objects to concat
  • totalLength Number Total length of the buffers in the list when concatenated

Returns a buffer which is the result of concatenating all the buffers in the list together.

If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.

If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.

Example: build a single buffer from a list of three buffers:

var buf1 = new Buffer(10);
var buf2 = new Buffer(14);
var buf3 = new Buffer(18);

buf1.fill(0);
buf2.fill(0);
buf3.fill(0);

var buffers = [buf1, buf2, buf3];

var totalLength = 0;
for (var i = 0; i < buffers.length; i++) {
  totalLength += buffers[i].length;
}

console.log(totalLength);
var bufA = Buffer.concat(buffers, totalLength);
console.log(bufA);
console.log(bufA.length);

// 42
// <Buffer 00 00 00 00 ...>
// 42

Class Method: Buffer.isBuffer(obj)#

  • obj Object
  • Return: Boolean

Tests if obj is a Buffer.

Class Method: Buffer.isEncoding(encoding)#

  • encoding String The encoding string to test

Returns true if the encoding is a valid encoding argument, or false otherwise.

buffer.entries()#

Creates iterator for [index, byte] arrays.

buffer.keys()#

Creates iterator for buffer keys (indices).

buffer.values()#

Creates iterator for buffer values (bytes). This function is called automatically when buffer is used in a for..of statement.

buf[index]#

Get and set the octet at index. The values refer to individual bytes, so the legal range is between 0x00 and 0xFF hex or 0 and 255.

Example: copy an ASCII string into a buffer, one byte at a time:

str = "Node.js";
buf = new Buffer(str.length);

for (var i = 0; i < str.length ; i++) {
  buf[i] = str.charCodeAt(i);
}

console.log(buf);

// Node.js

buf.compare(otherBuffer)#

  • otherBuffer Buffer

Returns a number indicating whether this comes before, after, or is the same as the otherBuffer in sort order.

buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])#

  • targetBuffer Buffer object - Buffer to copy into
  • targetStart Number, Optional, Default: 0
  • sourceStart Number, Optional, Default: 0
  • sourceEnd Number, Optional, Default: buffer.length

Copies data from a region of this buffer to a region in the target buffer even if the target memory region overlaps with the source. If undefined, the targetStart and sourceStart parameters default to 0 while sourceEnd defaults to buffer.length.

Returns the number of bytes copied.

Example: build two Buffers, then copy buf1 from byte 16 through byte 19 into buf2, starting at the 8th byte in buf2.

buf1 = new Buffer(26);
buf2 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
  buf2[i] = 33; // ASCII !
}

buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));

// !!!!!!!!qrst!!!!!!!!!!!!!

Example: Build a single buffer, then copy data from one region to an overlapping region in the same buffer

buf = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97; // 97 is ASCII a
}

buf.copy(buf, 0, 4, 10);
console.log(buf.toString());

// efghijghijklmnopqrstuvwxyz

buf.equals(otherBuffer)#

  • otherBuffer Buffer

Returns a boolean indicating whether this and otherBuffer have the same bytes.

buf.fill(value[, offset][, end])#

  • value
  • offset Number, Optional
  • end Number, Optional

Fills the buffer with the specified value. If the offset (defaults to 0) and end (defaults to buffer.length) are not given it will fill the entire buffer.

var b = new Buffer(50);
b.fill('h');

buf.indexOf(value[, byteOffset])#

  • value String, Buffer or Number
  • byteOffset Number, Optional, Default: 0
  • Return: Number

Operates similar to Array#indexOf(). Accepts a String, Buffer or Number. Strings are interpreted as UTF8. Buffers will use the entire buffer. So in order to compare a partial Buffer use Buffer#slice(). Numbers can range from 0 to 255.

buf.length#

  • Number

The size of the buffer in bytes. Note that this is not necessarily the size of the contents. length refers to the amount of memory allocated for the buffer object. It does not change when the contents of the buffer are changed.

buf = new Buffer(1234);

console.log(buf.length);
buf.write('some string', 0, 'ascii');
console.log(buf.length);

// 1234
// 1234

While the length property is not immutable, changing the value of length can result in undefined and inconsistent behavior. Applications that wish to modify the length of a buffer should therefore treat length as read-only and use buf.slice to create a new buffer.

buf = new Buffer(10);
buf.write('abcdefghj', 0, 'ascii');
console.log(buf.length); // 10
buf = buf.slice(0,5);
console.log(buf.length); // 5

buf.readDoubleBE(offset[, noAssert])#

buf.readDoubleLE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a 64-bit double from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(8);

buf[0] = 0x55;
buf[1] = 0x55;
buf[2] = 0x55;
buf[3] = 0x55;
buf[4] = 0x55;
buf[5] = 0x55;
buf[6] = 0xd5;
buf[7] = 0x3f;

console.log(buf.readDoubleLE(0));

// 0.3333333333333333

buf.readFloatBE(offset[, noAssert])#

buf.readFloatLE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a 32-bit float from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = 0x80;
buf[3] = 0x3f;

console.log(buf.readFloatLE(0));

// 0x01

buf.readInt8(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 8-bit integer from the buffer at the specified offset.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt8, except buffer contents are treated as two's complement signed values.

buf.readInt16BE(offset[, noAssert])#

buf.readInt16LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 16-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt16*, except buffer contents are treated as two's complement signed values.

buf.readInt32BE(offset[, noAssert])#

buf.readInt32LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 32-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt32*, except buffer contents are treated as two's complement signed values.

buf.readIntBE(offset, byteLength[, noAssert])#

buf.readIntLE(offset, byteLength[, noAssert])#

  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUInt16LE(0x90ab, 0);
b.writeUInt32LE(0x12345678, 2);
b.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)
// output: '1234567890ab'

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

buf.readUInt8(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 8-bit integer from the buffer at the specified offset.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

for (ii = 0; ii < buf.length; ii++) {
  console.log(buf.readUInt8(ii));
}

// 0x3
// 0x4
// 0x23
// 0x42

buf.readUInt16BE(offset[, noAssert])#

buf.readUInt16LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 16-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt16BE(0));
console.log(buf.readUInt16LE(0));
console.log(buf.readUInt16BE(1));
console.log(buf.readUInt16LE(1));
console.log(buf.readUInt16BE(2));
console.log(buf.readUInt16LE(2));

// 0x0304
// 0x0403
// 0x0423
// 0x2304
// 0x2342
// 0x4223

buf.readUInt32BE(offset[, noAssert])#

buf.readUInt32LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 32-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt32BE(0));
console.log(buf.readUInt32LE(0));

// 0x03042342
// 0x42230403

buf.readUIntBE(offset, byteLength[, noAssert])#

buf.readUIntLE(offset, byteLength[, noAssert])#

  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUInt16LE(0x90ab, 0);
b.writeUInt32LE(0x12345678, 2);
b.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)
// output: '1234567890ab'

buf.slice([start[, end]])#

  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

Returns a new buffer which references the same memory as the old, but offset and cropped by the start (defaults to 0) and end (defaults to buffer.length) indexes. Negative indexes start from the end of the buffer.

Modifying the new buffer slice will modify memory in the original buffer!

Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte from the original Buffer.

var buf1 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
}

var buf2 = buf1.slice(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));

// abc
// !bc

buf.toString([encoding][, start][, end])#

  • encoding String, Optional, Default: 'utf8'
  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

Decodes and returns a string from buffer data encoded using the specified character set encoding. If encoding is undefined or null, then encoding defaults to 'utf8'. The start and end parameters default to 0 and buffer.length when undefined.

buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97; // 97 is ASCII a
}
buf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz
buf.toString('ascii',0,5); // outputs: abcde
buf.toString('utf8',0,5); // outputs: abcde
buf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde

See buf.write() example, below.

buf.toJSON()#

Returns a JSON representation of the Buffer instance. JSON.stringify implicitly calls this function when stringifying a Buffer instance.

Example:

var buf = new Buffer('test');
var json = JSON.stringify(buf);

console.log(json);
// '{"type":"Buffer","data":[116,101,115,116]}'

var copy = JSON.parse(json, function(key, value) {
    return value && value.type === 'Buffer'
      ? new Buffer(value.data)
      : value;
  });

console.log(copy);
// <Buffer 74 65 73 74>

buf.write(string[, offset][, length][, encoding])#

  • string String - data to be written to buffer
  • offset Number, Optional, Default: 0
  • length Number, Optional, Default: buffer.length - offset
  • encoding String, Optional, Default: 'utf8'

Writes string to the buffer at offset using the given encoding. offset defaults to 0, encoding defaults to 'utf8'. length is the number of bytes to write. Returns number of octets written. If buffer did not contain enough space to fit the entire string, it will write a partial amount of the string. length defaults to buffer.length - offset. The method will not write partial characters.

buf = new Buffer(256);
len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);

buf.writeDoubleBE(value, offset[, noAssert])#

buf.writeDoubleLE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid 64-bit double.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(8);
buf.writeDoubleBE(0xdeadbeefcafebabe, 0);

console.log(buf);

buf.writeDoubleLE(0xdeadbeefcafebabe, 0);

console.log(buf);

// <Buffer 43 eb d5 b7 dd f9 5f d7>
// <Buffer d7 5f f9 dd b7 d5 eb 43>

buf.writeFloatBE(value, offset[, noAssert])#

buf.writeFloatLE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. Behavior is unspecified if value is not a 32-bit float.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeFloatBE(0xcafebabe, 0);

console.log(buf);

buf.writeFloatLE(0xcafebabe, 0);

console.log(buf);

// <Buffer 4f 4a fe bb>
// <Buffer bb fe 4a 4f>

buf.writeInt8(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset. value must be a valid signed 8-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt8, except value is written out as a two's complement signed integer into buffer.

buf.writeInt16BE(value, offset[, noAssert])#

buf.writeInt16LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid signed 16-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt16*, except value is written out as a two's complement signed integer into buffer.

buf.writeInt32BE(value, offset[, noAssert])#

buf.writeInt32LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid signed 32-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt32*, except value is written out as a two's complement signed integer into buffer.

buf.writeIntBE(value, offset, byteLength[, noAssert])#

buf.writeIntLE(value, offset, byteLength[, noAssert])#

  • value {Number} Bytes to be written to buffer
  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

Writes value to the buffer at the specified offset and byteLength. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUIntBE(0x1234567890ab, 0, 6);
// <Buffer 12 34 56 78 90 ab>

Set noAssert to true to skip validation of value and offset. Defaults to false.

buf.writeUInt8(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset. value must be a valid unsigned 8-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);

console.log(buf);

// <Buffer 03 04 23 42>

buf.writeUInt16BE(value, offset[, noAssert])#

buf.writeUInt16LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid unsigned 16-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);

console.log(buf);

buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);

console.log(buf);

// <Buffer de ad be ef>
// <Buffer ad de ef be>

buf.writeUInt32BE(value, offset[, noAssert])#

buf.writeUInt32LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid unsigned 32-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt32BE(0xfeedface, 0);

console.log(buf);

buf.writeUInt32LE(0xfeedface, 0);

console.log(buf);

// <Buffer fe ed fa ce>
// <Buffer ce fa ed fe>

buf.writeUIntBE(value, offset, byteLength[, noAssert])#

buf.writeUIntLE(value, offset, byteLength[, noAssert])#

  • value {Number} Bytes to be written to buffer
  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

Writes value to the buffer at the specified offset and byteLength. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUIntBE(0x1234567890ab, 0, 6);
// <Buffer 12 34 56 78 90 ab>

Set noAssert to true to skip validation of value and offset. Defaults to false.

buffer.INSPECT_MAX_BYTES#

  • Number, Default: 50

How many bytes will be returned when buffer.inspect() is called. This can be overridden by user modules. See util.inspect() for more details on buffer.inspect() behavior.

Note that this is a property on the buffer module returned by require('buffer'), not on the Buffer global or a buffer instance.

ES6 iteration#

Buffers can be iterated over using for..of syntax:

var buf = new Buffer([1, 2, 3]);

for (var b of buf)
  console.log(b)

// 1
// 2
// 3

Additionally, the buffer.values(), buffer.keys(), and buffer.entries() methods can be used to create iterators.

Class: SlowBuffer#

Returns an un-pooled Buffer.

In order to avoid the garbage collection overhead of creating many individually allocated Buffers, by default allocations under 4KB are sliced from a single larger allocated object. This approach improves both performance and memory usage since v8 does not need to track and cleanup as many Persistent objects.

In the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using SlowBuffer and copy out the relevant bits.

// need to keep around a few small chunks of memory
var store = [];

socket.on('readable', function() {
  var data = socket.read();
  // allocate for retained data
  var sb = new SlowBuffer(10);
  // copy the data into the new allocation
  data.copy(sb, 0, 0, 10);
  store.push(sb);
});

This should be used only as a last resort after a developer has observed undue memory retention in their applications.

Child Process#

Stability: 2 - Stable

Node.js provides a tri-directional popen(3) facility through the child_process module.

It is possible to stream data through a child's stdin, stdout, and stderr in a fully non-blocking way. (Note that some programs use line-buffered I/O internally. That doesn't affect Node.js but it means data you send to the child process may not be immediately consumed.)

To create a child process, use require('child_process').spawn() or require('child_process').fork(). The semantics of each are slightly different as explained below.

For scripting purposes you may find the synchronous counterparts more convenient.

Class: ChildProcess#

ChildProcess is an EventEmitter.

Child processes always have three streams associated with them. child.stdin, child.stdout, and child.stderr. These may be shared with the stdio streams of the parent process, or they may be separate stream objects which can be piped to and from.

The ChildProcess class is not intended to be used directly. Use the spawn(), exec(), execFile(), or fork() methods to create an instance of ChildProcess.

Event: 'close'#

  • code Number the exit code, if it exited normally.
  • signal String the signal passed to kill the child process, if it was killed by the parent.

This event is emitted when the stdio streams of a child process have all terminated. This is distinct from 'exit', since multiple processes might share the same stdio streams.

Event: 'disconnect'#

This event is emitted after calling the .disconnect() method in the parent or in the child. After disconnecting it is no longer possible to send messages, and the .connected property is false.

Event: 'error'#

  • err Error Object the error.

Emitted when:

  1. The process could not be spawned, or
  2. The process could not be killed, or
  3. Sending a message to the child process failed.

Note that the 'exit' event may or may not fire after an error has occurred. If you are listening on both events to fire a function, remember to guard against calling your function twice.

See also ChildProcess#kill() and ChildProcess#send().

Event: 'exit'#

  • code Number the exit code, if it exited normally.
  • signal String the signal passed to kill the child process, if it was killed by the parent.

This event is emitted after the child process ends. If the process terminated normally, code is the final exit code of the process, otherwise null. If the process terminated due to receipt of a signal, signal is the string name of the signal, otherwise null.

Note that the child process stdio streams might still be open.

Also, note that Node.js establishes signal handlers for SIGINT and SIGTERM. It will not terminate due to receipt of those signals. It will exit.

See waitpid(2).

Event: 'message'#

  • message Object a parsed JSON object or primitive value.
  • sendHandle Handle object a net.Socket or net.Server object, or undefined.

Messages sent by .send(message, [sendHandle]) are obtained using the 'message' event.

child.connected#

  • Boolean Set to false after .disconnect is called

If .connected is false, it is no longer possible to send messages.

child.disconnect()#

Close the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. After calling this method the .connected flag will be set to false in both the parent and child, and it is no longer possible to send messages.

The 'disconnect' event will be emitted when there are no messages in the process of being received, most likely immediately.

Note that you can also call process.disconnect() in the child process when the child process has any open IPC channels with the parent (i.e fork()).

child.kill([signal])#

  • signal String

Send a signal to the child process. If no argument is given, the process will be sent 'SIGTERM'. See signal(7) for a list of available signals.

const spawn = require('child_process').spawn;
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `child process terminated due to receipt of signal ${signal}`);
});

// send SIGHUP to process
grep.kill('SIGHUP');

May emit an 'error' event when the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will be delivered to that process instead. What happens next is anyone's guess.

Note that while the function is called kill, the signal delivered to the child process may not actually kill it. kill really just sends a signal to a process.

See kill(2)

child.pid#

  • Integer

The process identifier (PID) of the child process.

Example:

const spawn = require('child_process').spawn;
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();

child.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object
  • callback Function
  • Return: Boolean

When using child_process.fork() you can write to the child using child.send(message[, sendHandle][, callback]) and messages are received by a 'message' event on the child.

For example:

const cp = require('child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, 'sub.js' might look like this:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

In the child, the process object will have a send() method, and process will emit objects each time it receives a message on its channel.

There is a special case when sending a {cmd: 'NODE_foo'} message. All messages containing a NODE_ prefix in its cmd property will not be emitted in the 'message' event, since they are internal messages used by Node.js core. Messages containing the prefix are emitted in the 'internalMessage' event. Avoid using this feature; it is subject to change without notice.

The sendHandle option to child.send() is for sending a TCP server or socket object to another process. The child will receive the object as its second argument to the 'message' event.

The callback option is a function that is invoked after the message is sent but before the target may have received it. It is called with a single argument: null on success, or an Error object on failure.

child.send() emits an 'error' event if no callback was given and the message cannot be sent, for example because the child process has already exited.

Returns true under normal circumstances or false when the backlog of unsent messages exceeds a threshold that makes it unwise to send more. Use the callback mechanism to implement flow control.

Example: sending server object#

Here is an example of sending a server:

const child = require('child_process').fork('child.js');

// Open up the server object and send the handle.
const server = require('net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  child.send('server', server);
});

And the child would then receive the server object as:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

Note that the server is now shared between the parent and child, this means that some connections will be handled by the parent and some by the child.

For dgram servers the workflow is exactly the same. Here you listen on a 'message' event instead of 'connection' and use server.bind instead of server.listen. (Currently only supported on UNIX platforms.)

Example: sending socket object#

Here is an example of sending a socket. It will spawn two children and handle connections with the remote address 74.125.127.100 as VIP by sending the socket to a "special" child process. Other sockets will go to a "normal" process.

const normal = require('child_process').fork('child.js', ['normal']);
const special = require('child_process').fork('child.js', ['special']);

// Open up the server and send sockets to child
const server = require('net').createServer();
server.on('connection', (socket) => {

  // if this is a VIP
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // just the usual...
  normal.send('socket', socket);
});
server.listen(1337);

The child.js could look like this:

process.on('message', (m, socket) => {
  if (m === 'socket') {
    socket.end(`You were handled as a ${process.argv[2]} person`);
  }
});

Note that once a single socket has been sent to a child the parent can no longer keep track of when the socket is destroyed. To indicate this condition the .connections property becomes null. It is also recommended not to use .maxConnections in this condition.

child.stderr#

  • Stream object

A Readable Stream that represents the child process's stderr.

If the child was not spawned with stdio[2] set to 'pipe', then this will not be set.

child.stderr is shorthand for child.stdio[2]. Both properties will refer to the same object, or null.

child.stdin#

  • Stream object

A Writable Stream that represents the child process's stdin. If the child is waiting to read all its input, it will not continue until this stream has been closed via end().

If the child was not spawned with stdio[0] set to 'pipe', then this will not be set.

child.stdin is shorthand for child.stdio[0]. Both properties will refer to the same object, or null.

child.stdio#

  • Array

A sparse array of pipes to the child process, corresponding with positions in the stdio option to spawn() that have been set to 'pipe'. Note that streams 0-2 are also available as ChildProcess.stdin, ChildProcess.stdout, and ChildProcess.stderr, respectively.

In the following example, only the child's fd 1 is setup as a pipe, so only the parent's child.stdio[1] is a stream, all other values in the array are null.

const assert = require('assert');
const fs = require('fs');
const child_process = require('child_process');

const child = child_process.spawn('ls', {
    stdio: [
      0, // use parents stdin for child
      'pipe', // pipe child's stdout to parent
      fs.openSync('err.out', 'w') // direct child's stderr to a file
    ]
});

assert.equal(child.stdio[0], null);
assert.equal(child.stdio[0], child.stdin);

assert(child.stdout);
assert.equal(child.stdio[1], child.stdout);

assert.equal(child.stdio[2], null);
assert.equal(child.stdio[2], child.stderr);

child.stdout#

  • Stream object

A Readable Stream that represents the child process's stdout.

If the child was not spawned with stdio[1] set to 'pipe', then this will not be set.

child.stdout is shorthand for child.stdio[1]. Both properties will refer to the same object, or null.

Asynchronous Process Creation#

These methods follow the common async programming patterns (accepting a callback or returning an EventEmitter).

child_process.exec(command[, options], callback)#

  • command String The command to run, with space-separated arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • encoding String (Default: 'utf8')
    • shell String Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
    • timeout Number (Default: 0)
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200*1024)
    • killSignal String (Default: 'SIGTERM')
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • callback Function called with the output when process terminates
    • error Error
    • stdout Buffer
    • stderr Buffer
  • Return: ChildProcess object

Runs a command in a shell and buffers the output.

const exec = require('child_process').exec;
const child = exec('cat *.js bad_file | wc -l',
  (error, stdout, stderr) => {
    console.log(`stdout: ${stdout}`);
    console.log(`stderr: ${stderr}`);
    if (error !== null) {
      console.log(`exec error: ${error}`);
    }
});

The callback gets the arguments (error, stdout, stderr). On success, error will be null. On error, error will be an instance of Error and error.code will be the exit code of the child process, and error.signal will be set to the signal that terminated the process.

There is a second optional argument to specify several options. The default options are

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

If timeout is greater than 0, then it will kill the child process if it runs longer than timeout milliseconds. The child process is killed with killSignal (default: 'SIGTERM'). maxBuffer specifies the largest amount of data (in bytes) allowed on stdout or stderr - if this value is exceeded then the child process is killed.

Note: Unlike the exec() POSIX system call, child_process.exec() does not replace the existing process and uses a shell to execute the command.

child_process.execFile(file[, args][, options][, callback])#

  • file String The filename of the program to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • encoding String (Default: 'utf8')
    • timeout Number (Default: 0)
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200*1024)
    • killSignal String (Default: 'SIGTERM')
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • callback Function called with the output when process terminates
    • error Error
    • stdout Buffer
    • stderr Buffer
  • Return: ChildProcess object

This is similar to child_process.exec() except it does not execute a subshell but rather the specified file directly. This makes it slightly leaner than child_process.exec(). It has the same options.

child_process.fork(modulePath[, args][, options])#

  • modulePath String The module to run in the child
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • execPath String Executable used to create the child process
    • execArgv Array List of string arguments passed to the executable (Default: process.execArgv)
    • silent Boolean If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the 'pipe' and 'inherit' options for spawn()'s stdio for more details (default is false)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • Return: ChildProcess object

This is a special case of the child_process.spawn() functionality for spawning Node.js processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. See ChildProcess#send() for details.

These child Node.js processes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node.js. That is, you cannot create many thousands of them.

The execPath property in the options object allows for a process to be created for the child rather than the current node executable. This should be done with care and by default will talk over the fd represented an environmental variable NODE_CHANNEL_FD on the child process. The input and output on this fd is expected to be line delimited JSON objects.

Note: Unlike the fork() POSIX system call, child_process.fork() does not clone the current process.

child_process.spawn(command[, args][, options])#

  • command String The command to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • stdio Array|String Child's stdio configuration. (See below)
    • detached Boolean Prepare child to run independently of its parent process. Specific behavior depends on the platform, see below)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • return: ChildProcess object

Launches a new process with the given command, with command line arguments in args. If omitted, args defaults to an empty Array.

The third argument is used to specify additional options, with these defaults:

{ cwd: undefined,
  env: process.env
}

Use cwd to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory.

Use env to specify environment variables that will be visible to the new process, the default is process.env.

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:

const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

Example: A very elaborate way to run 'ps ax | grep ssh'

const spawn = require('child_process').spawn;
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

ps.stderr.on('data', (data) => {
  console.log(`ps stderr: ${data}`);
});

ps.on('close', (code) => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`);
  }
  grep.stdin.end();
});

grep.stdout.on('data', (data) => {
  console.log(`${data}`);
});

grep.stderr.on('data', (data) => {
  console.log(`grep stderr: ${data}`);
});

grep.on('close', (code) => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`);
  }
});

Example of checking for failed exec:

const spawn = require('child_process').spawn;
const child = spawn('bad_command');

child.on('error', (err) => {
  console.log('Failed to start child process.');
});

options.detached#

On Windows, this makes it possible for the child to continue running after the parent exits. The child will have a new console window (this cannot be disabled).

On non-Windows, if the detached option is set, the child process will be made the leader of a new process group and session. Note that child processes may continue running after the parent exits whether they are detached or not. See setsid(2) for more information.

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given child, use the child.unref() method, and the parent's event loop will not include the child in its reference count.

Example of detaching a long-running process and redirecting its output to a file:

 const fs = require('fs');
 const spawn = require('child_process').spawn;
 const out = fs.openSync('./out.log', 'a');
 const err = fs.openSync('./out.log', 'a');

 const child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });

 child.unref();

When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal.

options.stdio#

As a shorthand, the stdio argument may be one of the following strings:

  • 'pipe' - ['pipe', 'pipe', 'pipe'], this is the default value
  • 'ignore' - ['ignore', 'ignore', 'ignore']
  • 'inherit' - [process.stdin, process.stdout, process.stderr] or [0,1,2]

Otherwise, the 'stdio' option to child_process.spawn() is an array where each index corresponds to a fd in the child. The value is one of the following:

  1. 'pipe' - Create a pipe between the child process and the parent process. The parent end of the pipe is exposed to the parent as a property on the child_process object as ChildProcess.stdio[fd]. Pipes created for fds 0 - 2 are also available as ChildProcess.stdin, ChildProcess.stdout and ChildProcess.stderr, respectively.
  2. 'ipc' - Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most one IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is an Node.js program, then the presence of an IPC channel will enable process.send() and process.on('message').
  3. 'ignore' - Do not set this file descriptor in the child. Note that Node.js will always open fd 0 - 2 for the processes it spawns. When any of these is ignored Node.js will open /dev/null and attach it to the child's fd.
  4. Stream object - Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream's underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the stdio array. Note that the stream must have an underlying descriptor (file streams do not until the 'open' event has occurred).
  5. Positive integer - The integer value is interpreted as a file descriptor that is is currently open in the parent process. It is shared with the child process, similar to how Stream objects can be shared.
  6. null, undefined - Use default value. For stdio fds 0, 1 and 2 (in other words, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the default is 'ignore'.

Example:

const spawn = require('child_process').spawn;

// Child will use parent's stdios
spawn('prg', [], { stdio: 'inherit' });

// Spawn child sharing only stderr
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Open an extra fd=4, to interact with programs present a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

See also: child_process.exec() and child_process.fork()

Synchronous Process Creation#

These methods are synchronous, meaning they WILL block the event loop, pausing execution of your code until the spawned process exits.

Blocking calls like these are mostly useful for simplifying general purpose scripting tasks and for simplifying the loading/processing of application configuration at startup.

child_process.execFileSync(file[, args][, options])#

  • file String The filename of the program to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration. (Default: 'pipe')
      • stderr by default will be output to the parent process' stderr unless stdio is specified
    • env Object Environment key-value pairs
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execFileSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync()

child_process.execSync(command[, options])#

  • command String The command to run
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration. (Default: 'pipe')
      • stderr by default will be output to the parent process' stderr unless stdio is specified
    • env Object Environment key-value pairs
    • shell String Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync()

child_process.spawnSync(command[, args][, options])#

  • command String The command to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration.
    • env Object Environment key-value pairs
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Object
    • pid Number Pid of the child process
    • output Array Array of results from stdio output
    • stdout Buffer|String The contents of output[1]
    • stderr Buffer|String The contents of output[2]
    • status Number The exit code of the child process
    • signal String The signal used to kill the child process
    • error Error The error object if the child process failed or timed out

spawnSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

Cluster#

Stability: 2 - Stable

A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load.

The cluster module allows you to easily create child processes that all share server ports.

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);
}

Running Node.js will now share port 8000 between the workers:

% NODE_DEBUG=cluster node server.js
23521,Master Worker 23524 online
23521,Master Worker 23526 online
23521,Master Worker 23523 online
23521,Master Worker 23528 online

Please note that, on Windows, it is not yet possible to set up a named pipe server in a worker.

How It Works#

The worker processes are spawned using the [child_process.fork][] method, so that they can communicate with the parent via IPC and pass server handles back and forth.

The cluster module supports two methods of distributing incoming connections.

The first one (and the default one on all platforms except Windows), is the round-robin approach, where the master process listens on a port, accepts new connections and distributes them across the workers in a round-robin fashion, with some built-in smarts to avoid overloading a worker process.

The second approach is where the master process creates the listen socket and sends it to interested workers. The workers then accept incoming connections directly.

The second approach should, in theory, give the best performance. In practice however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight.

Because server.listen() hands off most of the work to the master process, there are three cases where the behavior between a normal Node.js process and a cluster worker differs:

  1. server.listen({fd: 7}) Because the message is passed to the master, file descriptor 7 in the parent will be listened on, and the handle passed to the worker, rather than listening to the worker's idea of what the number 7 file descriptor references.
  2. server.listen(handle) Listening on handles explicitly will cause the worker to use the supplied handle, rather than talk to the master process. If the worker already has the handle, then it's presumed that you know what you are doing.
  3. server.listen(0) Normally, this will cause servers to listen on a random port. However, in a cluster, each worker will receive the same "random" port each time they do listen(0). In essence, the port is random the first time, but predictable thereafter. If you want to listen on a unique port, generate a port number based on the cluster worker ID.

There is no routing logic in Node.js, or in your program, and no shared state between the workers. Therefore, it is important to design your program such that it does not rely too heavily on in-memory data objects for things like sessions and login.

Because workers are all separate processes, they can be killed or re-spawned depending on your program's needs, without affecting other workers. As long as there are some workers still alive, the server will continue to accept connections. If no workers are alive, existing connections will be dropped and new connections will be refused. Node.js does not automatically manage the number of workers for you, however. It is your responsibility to manage the worker pool for your application's needs.

Class: Worker#

A Worker object contains all public information and method about a worker. In the master it can be obtained using cluster.workers. In a worker it can be obtained using cluster.worker.

Event: 'disconnect'#

Similar to the cluster.on('disconnect') event, but specific to this worker.

cluster.fork().on('disconnect', () => {
  // Worker has disconnected
});

Event: 'error'#

This event is the same as the one provided by child_process.fork().

In a worker you can also use process.on('error').

Event: 'exit'#

  • code Number the exit code, if it exited normally.
  • signal String the name of the signal (eg. 'SIGHUP') that caused the process to be killed.

Similar to the cluster.on('exit') event, but specific to this worker.

const worker = cluster.fork();
worker.on('exit', (code, signal) => {
  if( signal ) {
    console.log(`worker was killed by signal: ${signal}`);
  } else if( code !== 0 ) {
    console.log(`worker exited with error code: ${code}`);
  } else {
    console.log('worker success!');
  }
});

Event: 'listening'#

  • address Object

Similar to the cluster.on('listening') event, but specific to this worker.

cluster.fork().on('listening', (address) => {
  // Worker is listening
});

It is not emitted in the worker.

Event: 'message'#

  • message Object

Similar to the cluster.on('message') event, but specific to this worker.

This event is the same as the one provided by child_process.fork().

In a worker you can also use process.on('message').

As an example, here is a cluster that keeps count of the number of requests in the master process using the message system:

const cluster = require('cluster');
const http = require('http');

if (cluster.isMaster) {

  // Keep track of http requests
  var numReqs = 0;
  setInterval(() => {
    console.log('numReqs =', numReqs);
  }, 1000);

  // Count requests
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd == 'notifyRequest') {
      numReqs += 1;
    }
  }

  // Start workers and listen for messages containing notifyRequest
  const numCPUs = require('os').cpus().length;
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  Object.keys(cluster.workers).forEach((id) => {
    cluster.workers[id].on('message', messageHandler);
  });

} else {

  // Worker processes have a http server.
  http.Server((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');

    // notify master about the request
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

Event: 'online'#

Similar to the cluster.on('online') event, but specific to this worker.

cluster.fork().on('online', () => {
  // Worker is online
});

It is not emitted in the worker.

worker.disconnect()#

In a worker, this function will close all servers, wait for the 'close' event on those servers, and then disconnect the IPC channel.

In the master, an internal message is sent to the worker causing it to call .disconnect() on itself.

Causes .suicide to be set.

Note that after a server is closed, it will no longer accept new connections, but connections may be accepted by any other listening worker. Existing connections will be allowed to close as usual. When no more connections exist, see [server.close()][], the IPC channel to the worker will close allowing it to die gracefully.

The above applies only to server connections, client connections are not automatically closed by workers, and disconnect does not wait for them to close before exiting.

Note that in a worker, process.disconnect exists, but it is not this function, it is disconnect.

Because long living server connections may block workers from disconnecting, it may be useful to send a message, so application specific actions may be taken to close them. It also may be useful to implement a timeout, killing a worker if the 'disconnect' event has not been emitted after some time.

if (cluster.isMaster) {
  var worker = cluster.fork();
  var timeout;

  worker.on('listening', (address) => {
    worker.send('shutdown');
    worker.disconnect();
    timeout = setTimeout(() => {
      worker.kill();
    }, 2000);
  });

  worker.on('disconnect', () => {
    clearTimeout(timeout);
  });

} else if (cluster.isWorker) {
  const net = require('net');
  var server = net.createServer((socket) => {
    // connections never end
  });

  server.listen(8000);

  process.on('message', (msg) => {
    if(msg === 'shutdown') {
      // initiate graceful close of any connections to server
    }
  });
}

worker.id#

  • Number

Each new worker is given its own unique id, this id is stored in the id.

While a worker is alive, this is the key that indexes it in cluster.workers

worker.isConnected()#

This function returns true if the worker is connected to its master via its IPC channel, false otherwise. A worker is connected to its master after it's been created. It is disconnected after the 'disconnect' event is emitted.

worker.isDead()#

This function returns true if the worker's process has terminated (either because of exiting or being signaled). Otherwise, it returns false.

worker.kill([signal='SIGTERM'])#

  • signal String Name of the kill signal to send to the worker process.

This function will kill the worker. In the master, it does this by disconnecting the worker.process, and once disconnected, killing with signal. In the worker, it does it by disconnecting the channel, and then exiting with code 0.

Causes .suicide to be set.

This method is aliased as worker.destroy() for backwards compatibility.

Note that in a worker, process.kill() exists, but it is not this function, it is kill.

worker.process#

  • ChildProcess object

All workers are created using child_process.fork(), the returned object from this function is stored as .process. In a worker, the global process is stored.

See: Child Process module

Note that workers will call process.exit(0) if the 'disconnect' event occurs on process and .suicide is not true. This protects against accidental disconnection.

worker.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object
  • callback Function
  • Return: Boolean

Send a message to a worker or master, optionally with a handle.

In the master this sends a message to a specific worker. It is identical to ChildProcess.send().

In a worker this sends a message to the master. It is identical to process.send().

This example will echo back all messages from the master:

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');

} else if (cluster.isWorker) {
  process.on('message', (msg) => {
    process.send(msg);
  });
}

worker.suicide#

  • Boolean

Set by calling .kill() or .disconnect(), until then it is undefined.

The boolean worker.suicide lets you distinguish between voluntary and accidental exit, the master may choose not to respawn a worker based on this value.

cluster.on('exit', (worker, code, signal) => {
  if (worker.suicide === true) {
    console.log('Oh, it was just suicide\' – no need to worry').
  }
});

// kill worker
worker.kill();

Event: 'disconnect'#

  • worker Worker object

Emitted after the worker IPC channel has disconnected. This can occur when a worker exits gracefully, is killed, or is disconnected manually (such as with worker.disconnect()).

There may be a delay between the 'disconnect' and 'exit' events. These events can be used to detect if the process is stuck in a cleanup or if there are long-living connections.

cluster.on('disconnect', (worker) => {
  console.log(`The worker #${worker.id} has disconnected`);
});

Event: 'exit'#

  • worker Worker object
  • code Number the exit code, if it exited normally.
  • signal String the name of the signal (eg. 'SIGHUP') that caused the process to be killed.

When any of the workers die the cluster module will emit the 'exit' event.

This can be used to restart the worker by calling .fork() again.

cluster.on('exit', (worker, code, signal) => {
  console.log('worker %d died (%s). restarting...',
    worker.process.pid, signal || code);
  cluster.fork();
});

See child_process event: 'exit'.

Event: 'fork'#

  • worker Worker object

When a new worker is forked the cluster module will emit a 'fork' event. This can be used to log worker activity, and create your own timeout.

var timeouts = [];
function errorMsg() {
  console.error('Something must be wrong with the connection ...');
}

cluster.on('fork', (worker) => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});
cluster.on('listening', (worker, address) => {
  clearTimeout(timeouts[worker.id]);
});
cluster.on('exit', (worker, code, signal) => {
  clearTimeout(timeouts[worker.id]);
  errorMsg();
});

Event: 'listening'#

  • worker Worker object
  • address Object

After calling listen() from a worker, when the 'listening' event is emitted on the server, a 'listening' event will also be emitted on cluster in the master.

The event handler is executed with two arguments, the worker contains the worker object and the address object contains the following connection properties: address, port and addressType. This is very useful if the worker is listening on more than one address.

cluster.on('listening', (worker, address) => {
  console.log(
    `A worker is now connected to ${address.address}:${address.port}`);
});

The addressType is one of:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (unix domain socket)
  • "udp4" or "udp6" (UDP v4 or v6)

Event: 'message'#

  • worker Worker object
  • message Object

Emitted when any worker receives a message.

See child_process event: 'message'.

Event: 'online'#

  • worker Worker object

After forking a new worker, the worker should respond with an online message. When the master receives an online message it will emit this event. The difference between 'fork' and 'online' is that fork is emitted when the master forks a worker, and 'online' is emitted when the worker is running.

cluster.on('online', (worker) => {
  console.log('Yay, the worker responded after it was forked');
});

Event: 'setup'#

  • settings Object

Emitted every time .setupMaster() is called.

The settings object is the cluster.settings object at the time .setupMaster() was called and is advisory only, since multiple calls to .setupMaster() can be made in a single tick.

If accuracy is important, use cluster.settings.

cluster.disconnect([callback])#

  • callback Function called when all workers are disconnected and handles are closed

Calls .disconnect() on each worker in cluster.workers.

When they are disconnected all internal handles will be closed, allowing the master process to die gracefully if no other event is waiting.

The method takes an optional callback argument which will be called when finished.

This can only be called from the master process.

cluster.fork([env])#

  • env Object Key/value pairs to add to worker process environment.
  • return Worker object

Spawn a new worker process.

This can only be called from the master process.

cluster.isMaster#

  • Boolean

True if the process is a master. This is determined by the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined, then isMaster is true.

cluster.isWorker#

  • Boolean

True if the process is not a master (it is the negation of cluster.isMaster).

cluster.schedulingPolicy#

The scheduling policy, either cluster.SCHED_RR for round-robin or cluster.SCHED_NONE to leave it to the operating system. This is a global setting and effectively frozen once you spawn the first worker or call cluster.setupMaster(), whatever comes first.

SCHED_RR is the default on all operating systems except Windows. Windows will change to SCHED_RR once libuv is able to effectively distribute IOCP handles without incurring a large performance hit.

cluster.schedulingPolicy can also be set through the NODE_CLUSTER_SCHED_POLICY environment variable. Valid values are "rr" and "none".

cluster.settings#

  • Object
    • execArgv Array list of string arguments passed to the Node.js executable. (Default=process.execArgv)
    • exec String file path to worker file. (Default=process.argv[1])
    • args Array string arguments passed to worker. (Default=process.argv.slice(2))
    • silent Boolean whether or not to send output to parent's stdio. (Default=false)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)

After calling .setupMaster() (or .fork()) this settings object will contain the settings, including the default values.

It is effectively frozen after being set, because .setupMaster() can only be called once.

This object is not supposed to be changed or set manually, by you.

cluster.setupMaster([settings])#

  • settings Object
    • exec String file path to worker file. (Default=process.argv[1])
    • args Array string arguments passed to worker. (Default=process.argv.slice(2))
    • silent Boolean whether or not to send output to parent's stdio. (Default=false)

setupMaster is used to change the default 'fork' behavior. Once called, the settings will be present in cluster.settings.

Note that:

  • any settings changes only affect future calls to .fork() and have no effect on workers that are already running
  • The only attribute of a worker that cannot be set via .setupMaster() is the env passed to .fork()
  • the defaults above apply to the first call only, the defaults for later calls is the current value at the time of cluster.setupMaster() is called

Example:

const cluster = require('cluster');
cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true
});
cluster.fork(); // https worker
cluster.setupMaster({
  args: ['--use', 'http']
});
cluster.fork(); // http worker

This can only be called from the master process.

cluster.worker#

  • Object

A reference to the current worker object. Not available in the master process.

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`I am worker #${cluster.worker.id}`);
}

cluster.workers#

  • Object

A hash that stores the active worker objects, keyed by id field. Makes it easy to loop through all the workers. It is only available in the master process.

A worker is removed from cluster.workers after the worker has disconnected and exited. The order between these two events cannot be determined in advance. However, it is guaranteed that the removal from the cluster.workers list happens before last 'disconnect' or 'exit' event is emitted.

// Go through all workers
function eachWorker(callback) {
  for (var id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker((worker) => {
  worker.send('big announcement to all workers');
});

Should you wish to reference a worker over a communication channel, using the worker's unique id is the easiest way to find the worker.

socket.on('data', (id) => {
  var worker = cluster.workers[id];
});

Console#

Stability: 2 - Stable

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to stdout and stderr. Because this object is global, it can be used without calling require('console').

Example using the global console:

console.log('hello world');
  // Prints: hello world, to stdout
console.log('hello %s', 'world');
  // Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
  // Prints: [Error: Whoops, something bad happened], to stderr

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
  // Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
  // Prints: hello world, to out
myConsole.log('hello %s', 'world');
  // Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
  // Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
  // Prints: Danger Will Robinson! Danger!, to err

While the API for the Console class is designed fundamentally around the Web browser console object, the Console is Node.js is not intended to duplicate the browsers functionality exactly.

Asynchronous vs Synchronous Consoles#

The console functions are synchronous when the destination is a terminal or a file (to avoid lost messages in case of premature exit) and asynchronous when the destination is a pipe (to avoid blocking for long periods of time).

In the following example, stdout is non-blocking while stderr is blocking:

$ node script.js 2> error.log | tee info.log

Typically, the distinction between blocking/non-blocking is not important unless an application is logging significant amounts of data. High volume logging should use a Console instance that writes to a pipe.

Class: Console#

The Console class can be used to create a simple logger with configurable output streams and can be accessed using either require('console').Console or console.Console:

const Console = require('console').Console;
const Console = console.Console;

new Console(stdout[, stderr])#

Creates a new Console by passing one or two writable stream instances. stdout is a writable stream to print log or info output. stderr is used for warning or error output. If stderr isn't passed, the warning and error output will be sent to the stdout.

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
var count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5

The global console is a special Console whose output is sent to process.stdout and process.stderr. It is equivalent to calling:

new Console(process.stdout, process.stderr);

console.assert(value[, message][, ...])#

A simple assertion test that verifies whether value is truthy. If it is not, an AssertionError is throw. If provided, the error message is formatted using util.format() and used as the error message.

console.assert(true, 'does nothing');
  // OK
console.assert(false, 'Whoops %s', 'didn\'t work');
  // AssertionError: Whoops didn't work

console.dir(obj[, options])#

Uses util.inspect() on obj and prints the resulting string to stdout. This function bypasses any custom inspect() function defined on obj. An optional options object may be passed that alters certain aspects of the formatted string:

  • showHidden - if true then the object's non-enumerable and symbol properties will be shown too. Defaults to false.

  • depth - tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely, pass null.

  • colors - if true, then the output will be styled with ANSI color codes. Defaults to false. Colors are customizable; see [customizing util.inspect() colors][].

console.error([data][, ...])#

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf() (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
  // Prints: error #5, to stderr
console.error('error', code);
  // Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

console.info([data][, ...])#

The console.info() function is an alias for console.log().

console.log([data][, ...])#

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf() (the arguments are all passed to util.format()).

var count = 5;
console.log('count: %d', count);
  // Prints: count: 5, to stdout
console.log('count: ', count);
  // Prints: count: 5, to stdout

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

console.time(label)#

Used to calculate the duration of a specific operation. To start a timer, call the console.time() method, giving it a unique label as the only parameter. To stop the timer, and to get the elapsed time in milliseconds, just call the console.timeEnd() method, again passing the timer's unique label as the parameter.

console.timeEnd(label)#

Stops a timer that was previously started by calling console.time() and prints the result to stdout:

console.time('100-elements');
for (var i = 0; i < 100; i++) {
  ;
}
console.timeEnd('100-elements');
// prints 100-elements: 262ms

console.trace(message[, ...])#

Prints to stderr the string 'Trace :', followed by the util.format() formatted message and stack trace to the current position in the code.

console.trace('Show me');
  // Prints: (stack trace will vary based on where trace is called)
  //  Trace: Show me
  //    at repl:2:9
  //    at REPLServer.defaultEval (repl.js:248:27)
  //    at bound (domain.js:287:14)
  //    at REPLServer.runBound [as eval] (domain.js:300:12)
  //    at REPLServer.<anonymous> (repl.js:412:12)
  //    at emitOne (events.js:82:20)
  //    at REPLServer.emit (events.js:169:7)
  //    at REPLServer.Interface._onLine (readline.js:210:10)
  //    at REPLServer.Interface._line (readline.js:549:8)
  //    at REPLServer.Interface._ttyWrite (readline.js:826:14)

console.warn([data][, ...])#

The console.warn() function is an alias for console.error().

Crypto#

Stability: 2 - Stable

Use require('crypto') to access this module.

The crypto module offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection.

It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.

Class: Certificate#

The class used for working with signed public key & challenges. The most common usage for this series of functions is when dealing with the <keygen> element. https://www.openssl.org/docs/apps/spkac.html

Returned by crypto.Certificate.

Certificate.exportChallenge(spkac)#

Exports the encoded challenge associated with the SPKAC.

Certificate.exportPublicKey(spkac)#

Exports the encoded public key from the supplied SPKAC.

Certificate.verifySpkac(spkac)#

Returns true of false based on the validity of the SPKAC.

Class: Cipher#

Class for encrypting data.

Returned by crypto.createCipher and crypto.createCipheriv.

Cipher objects are streams that are both readable and writable. The written plain text data is used to produce the encrypted data on the readable side. The legacy update and final methods are also supported.

cipher.final([output_encoding])#

Returns any remaining enciphered contents, with output_encoding being one of: 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is returned.

Note: cipher object can not be used after final() method has been called.

cipher.getAuthTag()#

For authenticated encryption modes (currently supported: GCM), this method returns a Buffer that represents the authentication tag that has been computed from the given data. Should be called after encryption has been completed using the final method!

cipher.setAAD(buffer)#

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

cipher.setAutoPadding(auto_padding=true)#

You can disable automatic padding of the input data to block size. If auto_padding is false, the length of the entire input data must be a multiple of the cipher's block size or final will fail. Useful for non-standard padding, e.g. using 0x0 instead of PKCS padding. You must call this before cipher.final.

cipher.update(data[, input_encoding][, output_encoding])#

Updates the cipher with data, the encoding of which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'. If no encoding is provided, then a buffer is expected. If data is a Buffer then input_encoding is ignored.

The output_encoding specifies the output format of the enciphered data, and can be 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is returned.

Returns the enciphered contents, and can be called many times with new data as it is streamed.

Class: Decipher#

Class for decrypting data.

Returned by crypto.createDecipher and crypto.createDecipheriv.

Decipher objects are streams that are both readable and writable. The written enciphered data is used to produce the plain-text data on the the readable side. The legacy update and final methods are also supported.

decipher.final([output_encoding])#

Returns any remaining plaintext which is deciphered, with output_encoding being one of: 'binary', 'ascii' or 'utf8'. If no encoding is provided, then a buffer is returned.

Note: decipher object can not be used after final() method has been called.

decipher.setAAD(buffer)#

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

decipher.setAuthTag(buffer)#

For authenticated encryption modes (currently supported: GCM), this method must be used to pass in the received authentication tag. If no tag is provided or if the ciphertext has been tampered with, final will throw, thus indicating that the ciphertext should be discarded due to failed authentication.

decipher.setAutoPadding(auto_padding=true)#

You can disable auto padding if the data has been encrypted without standard block padding to prevent decipher.final from checking and removing it. This will only work if the input data's length is a multiple of the ciphers block size. You must call this before streaming data to decipher.update.

decipher.update(data[, input_encoding][, output_encoding])#

Updates the decipher with data, which is encoded in 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is expected. If data is a Buffer then input_encoding is ignored.

The output_decoding specifies in what format to return the deciphered plaintext: 'binary', 'ascii' or 'utf8'. If no encoding is provided, then a buffer is returned.

Class: DiffieHellman#

The class for creating Diffie-Hellman key exchanges.

Returned by crypto.createDiffieHellman.

diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])#

Computes the shared secret using other_public_key as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified input_encoding, and secret is encoded using specified output_encoding. Encodings can be 'binary', 'hex', or 'base64'. If the input encoding is not provided, then a buffer is expected.

If no output encoding is given, then a buffer is returned.

diffieHellman.generateKeys([encoding])#

Generates private and public Diffie-Hellman key values, and returns the public key in the specified encoding. This key should be transferred to the other party. Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getGenerator([encoding])#

Returns the Diffie-Hellman generator in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPrime([encoding])#

Returns the Diffie-Hellman prime in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPrivateKey([encoding])#

Returns the Diffie-Hellman private key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPublicKey([encoding])#

Returns the Diffie-Hellman public key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.setPrivateKey(private_key[, encoding])#

Sets the Diffie-Hellman private key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

diffieHellman.setPublicKey(public_key[, encoding])#

Sets the Diffie-Hellman public key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

diffieHellman.verifyError#

A bit field containing any warnings and/or errors as a result of a check performed during initialization. The following values are valid for this property (defined in constants module):

  • DH_CHECK_P_NOT_SAFE_PRIME
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

Class: ECDH#

The class for creating EC Diffie-Hellman key exchanges.

Returned by crypto.createECDH.

ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding])#

Computes the shared secret using other_public_key as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified input_encoding, and secret is encoded using specified output_encoding. Encodings can be 'binary', 'hex', or 'base64'. If the input encoding is not provided, then a buffer is expected.

If no output encoding is given, then a buffer is returned.

ECDH.generateKeys([encoding[, format]])#

Generates private and public EC Diffie-Hellman key values, and returns the public key in the specified format and encoding. This key should be transferred to the other party.

Format specifies point encoding and can be 'compressed', 'uncompressed', or 'hybrid'. If no format is provided - the point will be returned in 'uncompressed' format.

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.getPrivateKey([encoding])#

Returns the EC Diffie-Hellman private key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.getPublicKey([encoding[, format]])#

Returns the EC Diffie-Hellman public key in the specified encoding and format.

Format specifies point encoding and can be 'compressed', 'uncompressed', or 'hybrid'. If no format is provided - the point will be returned in 'uncompressed' format.

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.setPrivateKey(private_key[, encoding])#

Sets the EC Diffie-Hellman private key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

Example (obtaining a shared secret):

const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');

alice.generateKeys();
bob.generateKeys();

const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);

ECDH.setPublicKey(public_key[, encoding])#

Sets the EC Diffie-Hellman public key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

Class: Hash#

The class for creating hash digests of data.

It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the computed hash digest. The legacy update and digest methods are also supported.

Returned by crypto.createHash.

hash.digest([encoding])#

Calculates the digest of all of the passed data to be hashed. The encoding can be 'hex', 'binary' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: hash object can not be used after digest() method has been called.

hash.update(data[, input_encoding])#

Updates the hash content with the given data, the encoding of which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'. If no encoding is provided, and the input is a string, an encoding of 'binary' is enforced. If data is a Buffer then input_encoding is ignored.

This can be called many times with new data as it is streamed.

Class: Hmac#

Class for creating cryptographic hmac content.

Returned by crypto.createHmac.

hmac.digest([encoding])#

Calculates the digest of all of the passed data to the hmac. The encoding can be 'hex', 'binary' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: hmac object can not be used after digest() method has been called.

hmac.update(data)#

Update the hmac content with the given data. This can be called many times with new data as it is streamed.

Class: Sign#

Class for generating signatures.

Returned by crypto.createSign.

Sign objects are writable streams. The written data is used to generate the signature. Once all of the data has been written, the sign method will return the signature. The legacy update method is also supported.

sign.sign(private_key[, output_format])#

Calculates the signature on all the updated data passed through the sign.

private_key can be an object or a string. If private_key is a string, it is treated as the key with no passphrase.

private_key:

  • key : A string holding the PEM encoded private key
  • passphrase : A string of passphrase for the private key

Returns the signature in output_format which can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: sign object can not be used after sign() method has been called.

sign.update(data)#

Updates the sign object with data. This can be called many times with new data as it is streamed.

Class: Verify#

Class for verifying signatures.

Returned by crypto.createVerify.

Verify objects are writable streams. The written data is used to validate against the supplied signature. Once all of the data has been written, the verify method will return true if the supplied signature is valid. The legacy update method is also supported.

verifier.update(data)#

Updates the verifier object with data. This can be called many times with new data as it is streamed.

verifier.verify(object, signature[, signature_format])#

Verifies the signed data by using the object and signature. object is a string containing a PEM encoded object, which can be one of RSA public key, DSA public key, or X.509 certificate. signature is the previously calculated signature for the data, in the signature_format which can be 'binary', 'hex' or 'base64'. If no encoding is specified, then a buffer is expected.

Returns true or false depending on the validity of the signature for the data and public key.

Note: verifier object can not be used after verify() method has been called.

crypto.DEFAULT_ENCODING#

The default encoding to use for functions that can take either strings or buffers. The default value is 'buffer', which makes it default to using Buffer objects. This is here to make the crypto module more easily compatible with legacy programs that expected 'binary' to be the default encoding.

Note that new programs will probably expect buffers, so only use this as a temporary measure.

crypto.createCipher(algorithm, password)#

Creates and returns a cipher object, with the given algorithm and password.

algorithm is dependent on OpenSSL, examples are 'aes192', etc. On recent releases, openssl list-cipher-algorithms will display the available cipher algorithms. password is used to derive key and IV, which must be a 'binary' encoded string or a buffer.

It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the enciphered contents. The legacy update and final methods are also supported.

Note: createCipher derives keys with the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same password always creates the same key. The low iteration count and non-cryptographically secure hash algorithm allow passwords to be tested very rapidly.

In line with OpenSSL's recommendation to use pbkdf2 instead of EVP_BytesToKey it is recommended you derive a key and iv yourself with crypto.pbkdf2 and to then use createCipheriv() to create the cipher stream.

crypto.createCipheriv(algorithm, key, iv)#

Creates and returns a cipher object, with the given algorithm, key and iv.

algorithm is the same as the argument to createCipher(). key is the raw key used by the algorithm. iv is an initialization vector.

key and iv must be 'binary' encoded strings or buffers.

crypto.createCredentials(details)#

Stability: 0 - Deprecated: Use tls.createSecureContext instead.

Creates a credentials object, with the optional details being a dictionary with keys:

  • pfx : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
  • key : A string holding the PEM encoded private key
  • passphrase : A string of passphrase for the private key or pfx
  • cert : A string holding the PEM encoded certificate
  • ca : Either a string or list of strings of PEM encoded CA certificates to trust.
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.

If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.

crypto.createDecipher(algorithm, password)#

Creates and returns a decipher object, with the given algorithm and key. This is the mirror of the createCipher() above.

crypto.createDecipheriv(algorithm, key, iv)#

Creates and returns a decipher object, with the given algorithm, key and iv. This is the mirror of the createCipheriv() above.

crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])#

Creates a Diffie-Hellman key exchange object using the supplied prime and an optional specific generator. generator can be a number, string, or Buffer. If no generator is specified, then 2 is used. prime_encoding and generator_encoding can be 'binary', 'hex', or 'base64'. If no prime_encoding is specified, then a Buffer is expected for prime. If no generator_encoding is specified, then a Buffer is expected for generator.

crypto.createDiffieHellman(prime_length[, generator])#

Creates a Diffie-Hellman key exchange object and generates a prime of prime_length bits and using an optional specific numeric generator. If no generator is specified, then 2 is used.

crypto.createECDH(curve_name)#

Creates an Elliptic Curve (EC) Diffie-Hellman key exchange object using a predefined curve specified by the curve_name string. Use getCurves() to obtain a list of available curve names. On recent releases, openssl ecparam -list_curves will also display the name and description of each available elliptic curve.

crypto.createHash(algorithm)#

Creates and returns a hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests.

algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are 'sha256', 'sha512', etc. On recent releases, openssl list-message-digest-algorithms will display the available digest algorithms.

Example: this program that takes the sha256 sum of a file

const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');

const shasum = crypto.createHash('sha256');

const s = fs.ReadStream(filename);
s.on('data', (d) => {
  shasum.update(d);
});

s.on('end', () => {
  var d = shasum.digest('hex');
  console.log(`${d}  ${filename}`);
});

crypto.createHmac(algorithm, key)#

Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key.

It is a stream that is both readable and writable. The written data is used to compute the hmac. Once the writable side of the stream is ended, use the read() method to get the computed digest. The legacy update and digest methods are also supported.

algorithm is dependent on the available algorithms supported by OpenSSL - see createHash above. key is the hmac key to be used.

crypto.createSign(algorithm)#

Creates and returns a signing object, with the given algorithm. On recent OpenSSL releases, openssl list-public-key-algorithms will display the available signing algorithms. Examples are 'RSA-SHA256'.

crypto.createVerify(algorithm)#

Creates and returns a verification object, with the given algorithm. This is the mirror of the signing object above.

crypto.getCiphers()#

Returns an array with the names of the supported ciphers.

Example:

const ciphers = crypto.getCiphers();
console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]

crypto.getCurves()#

Returns an array with the names of the supported elliptic curves.

Example:

const curves = crypto.getCurves();
console.log(curves); // ['secp256k1', 'secp384r1', ...]

crypto.getDiffieHellman(group_name)#

Creates a predefined Diffie-Hellman key exchange object. The supported groups are: 'modp1', 'modp2', 'modp5' (defined in RFC 2412, but see Caveats) and 'modp14', 'modp15', 'modp16', 'modp17', 'modp18' (defined in RFC 3526). The returned object mimics the interface of objects created by crypto.createDiffieHellman() above, but will not allow changing the keys (with diffieHellman.setPublicKey() for example). The advantage of using this routine is that the parties do not have to generate nor exchange group modulus beforehand, saving both processor and communication time.

Example (obtaining a shared secret):

const crypto = require('crypto');
const alice = crypto.getDiffieHellman('modp14');
const bob = crypto.getDiffieHellman('modp14');

alice.generateKeys();
bob.generateKeys();

const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);

crypto.getHashes()#

Returns an array with the names of the supported hash algorithms.

Example:

const hashes = crypto.getHashes();
console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]

crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)#

Asynchronous PBKDF2 function. Applies the selected HMAC digest function (default: SHA1) to derive a key of the requested byte length from the password, salt and number of iterations. The callback gets two arguments: (err, derivedKey).

The number of iterations passed to pbkdf2 should be as high as possible, the higher the number, the more secure it will be, but will take a longer amount of time to complete.

Chosen salts should also be unique. It is recommended that the salts are random and their length is greater than 16 bytes. See NIST SP 800-132 for details.

Example:

crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', function(err, key) {
  if (err)
    throw err;
  console.log(key.toString('hex'));  // 'c5e478d...1469e50'
});

You can get a list of supported digest functions with crypto.getHashes().

crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest])#

Synchronous PBKDF2 function. Returns derivedKey or throws error.

crypto.privateDecrypt(private_key, buffer)#

Decrypts buffer with private_key.

private_key can be an object or a string. If private_key is a string, it is treated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.

private_key:

  • key : A string holding the PEM encoded private key
  • passphrase : An optional string of passphrase for the private key
  • padding : An optional padding value, one of the following:
    • constants.RSA_NO_PADDING
    • constants.RSA_PKCS1_PADDING
    • constants.RSA_PKCS1_OAEP_PADDING

NOTE: All paddings are defined in constants module.

crypto.privateEncrypt(private_key, buffer)#

See above for details. Has the same API as crypto.privateDecrypt. Default padding is RSA_PKCS1_PADDING.

crypto.publicDecrypt(public_key, buffer)#

See above for details. Has the same API as crypto.publicEncrypt. Default padding is RSA_PKCS1_PADDING.

crypto.publicEncrypt(public_key, buffer)#

Encrypts buffer with public_key. Only RSA is currently supported.

public_key can be an object or a string. If public_key is a string, it is treated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING. Since RSA public keys may be derived from private keys you may pass a private key to this method.

public_key:

  • key : A string holding the PEM encoded private key
  • passphrase : An optional string of passphrase for the private key
  • padding : An optional padding value, one of the following:
    • constants.RSA_NO_PADDING
    • constants.RSA_PKCS1_PADDING
    • constants.RSA_PKCS1_OAEP_PADDING

NOTE: All paddings are defined in constants module.

crypto.randomBytes(size[, callback])#

Generates cryptographically strong pseudo-random data. Usage:

// async
crypto.randomBytes(256, (ex, buf) => {
  if (ex) throw ex;
  console.log('Have %d bytes of random data: %s', buf.length, buf);
});

// sync
const buf = crypto.randomBytes(256);
console.log('Have %d bytes of random data: %s', buf.length, buf);

NOTE: This will block if there is insufficient entropy, although it should normally never take longer than a few milliseconds. The only time when this may conceivably block is right after boot, when the whole system is still low on entropy.

crypto.setEngine(engine[, flags])#

Load and set engine for some/all OpenSSL functions (selected by flags).

engine could be either an id or a path to the engine's shared library.

flags is optional and has ENGINE_METHOD_ALL value by default. It could take one of or mix of following flags (defined in constants module):

  • ENGINE_METHOD_RSA
  • ENGINE_METHOD_DSA
  • ENGINE_METHOD_DH
  • ENGINE_METHOD_RAND
  • ENGINE_METHOD_ECDH
  • ENGINE_METHOD_ECDSA
  • ENGINE_METHOD_CIPHERS
  • ENGINE_METHOD_DIGESTS
  • ENGINE_METHOD_STORE
  • ENGINE_METHOD_PKEY_METH
  • ENGINE_METHOD_PKEY_ASN1_METH
  • ENGINE_METHOD_ALL
  • ENGINE_METHOD_NONE

Recent API Changes#

The Crypto module was added to Node.js before there was the concept of a unified Stream API, and before there were Buffer objects for handling binary data.

As such, the streaming classes don't have the typical methods found on other Node.js classes, and many methods accepted and returned Binary-encoded strings by default rather than Buffers. This was changed to use Buffers by default instead.

This is a breaking change for some use cases, but not all.

For example, if you currently use the default arguments to the Sign class, and then pass the results to the Verify class, without ever inspecting the data, then it will continue to work as before. Where you once got a binary string and then presented the binary string to the Verify object, you'll now get a Buffer, and present the Buffer to the Verify object.

However, if you were doing things with the string data that will not work properly on Buffers (such as, concatenating them, storing in databases, etc.), or you are passing binary strings to the crypto functions without an encoding argument, then you will need to start providing encoding arguments to specify which encoding you'd like to use. To switch to the previous style of using binary strings by default, set the crypto.DEFAULT_ENCODING field to 'binary'. Note that new programs will probably expect buffers, so only use this as a temporary measure.

Caveats#

The crypto module still supports some algorithms which are already compromised. And the API also allows the use of ciphers and hashes with a small key size that are considered to be too weak for safe use.

Users should take full responsibility for selecting the crypto algorithm and key size according to their security requirements.

Based on the recommendations of NIST SP 800-131A:

  • MD5 and SHA-1 are no longer acceptable where collision resistance is required such as digital signatures.
  • The key used with RSA, DSA and DH algorithms is recommended to have at least 2048 bits and that of the curve of ECDSA and ECDH at least 224 bits, to be safe to use for several years.
  • The DH groups of modp1, modp2 and modp5 have a key size smaller than 2048 bits and are not recommended.

See the reference for other recommendations and details.

Debugger#

Stability: 2 - Stable

Node.js includes a full-featured out-of-process debugging utility accessible via a simple TCP-based protocol and built-in debugging client. To use it, start Node.js with the debug argument followed by the path to the script to debug; a prompt will be displayed indicating successful launch of the debugger:

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug>

Node.js's debugger client does not yet support the full range of commands, but simple step and inspection are possible.

Inserting the statement debugger; into the source code of a script will enable a breakpoint at that position in the code.

For example, suppose myscript.js is written as:

// myscript.js
x = 5;
setTimeout(function () {
  debugger;
  console.log('world');
}, 1000);
console.log('hello');

Once the debugger is run, a breakpoint will occur at line 4:

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug> cont
< hello
break in /home/indutny/Code/git/indutny/myscript.js:3
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
  4   console.log('world');
  5 }, 1000);
debug> next
break in /home/indutny/Code/git/indutny/myscript.js:4
  2 setTimeout(function () {
  3   debugger;
  4   console.log('world');
  5 }, 1000);
  6 console.log('hello');
debug> repl
Press Ctrl + C to leave debug repl
> x
5
> 2+2
4
debug> next
< world
break in /home/indutny/Code/git/indutny/myscript.js:5
  3   debugger;
  4   console.log('world');
  5 }, 1000);
  6 console.log('hello');
  7
debug> quit
%

The repl command allows code to be evaluated remotely. The next command steps over to the next line. Type help to see what other commands are available.

Watchers#

It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's source code listing.

To begin watching an expression, type watch('my_expression'). The command watchers will print the active watchers. To remove a watcher, type unwatch('my_expression').

Commands reference#

Stepping#

  • cont, c - Continue execution
  • next, n - Step next
  • step, s - Step in
  • out, o - Step out
  • pause - Pause running code (like pause button in Developer Tools)

Breakpoints#

  • setBreakpoint(), sb() - Set breakpoint on current line
  • setBreakpoint(line), sb(line) - Set breakpoint on specific line
  • setBreakpoint('fn()'), sb(...) - Set breakpoint on a first statement in functions body
  • setBreakpoint('script.js', 1), sb(...) - Set breakpoint on first line of script.js
  • clearBreakpoint('script.js', 1), cb(...) - Clear breakpoint in script.js on line 1

It is also possible to set a breakpoint in a file (module) that isn't loaded yet:

% ./node debug test/fixtures/break-in-module/main.js
< debugger listening on port 5858
connecting to port 5858... ok
break in test/fixtures/break-in-module/main.js:1
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> setBreakpoint('mod.js', 23)
Warning: script 'mod.js' was not loaded yet.
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> c
break in test/fixtures/break-in-module/mod.js:23
 21
 22 exports.hello = function() {
 23   return 'hello from module';
 24 };
 25
debug>

Info#

  • backtrace, bt - Print backtrace of current execution frame
  • list(5) - List scripts source code with 5 line context (5 lines before and after)
  • watch(expr) - Add expression to watch list
  • unwatch(expr) - Remove expression from watch list
  • watchers - List all watchers and their values (automatically listed on each breakpoint)
  • repl - Open debugger's repl for evaluation in debugging script's context

Execution control#

  • run - Run script (automatically runs on debugger's start)
  • restart - Restart script
  • kill - Kill script

Various#

  • scripts - List all loaded scripts
  • version - Display V8's version

Advanced Usage#

An alternative way of enabling and accessing the debugger is to start Node.js with the --debug command-line flag or by signaling an existing Node.js process with SIGUSR1.

Once a process has been set in debug mode this way, it can be connected to using the Node.js debugger by either connecting to the pid of the running process or via URI reference to the listening debugger:

  • node debug -p <pid> - Connects to the process via the pid
  • node debug <URI> - Connects to the process via the URI such as localhost:5858

UDP / Datagram Sockets#

Stability: 2 - Stable

The dgram module provides an implementation of UDP Datagram sockets.

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(41234);
// server listening 0.0.0.0:41234

Class: dgram.Socket#

The dgram.Socket object is an EventEmitter that encapsulates the datagram functionality.

New instances of dgram.Socket are created using dgram.createSocket(). The new keyword is not to be used to create dgram.Socket instances.

Event: 'close'#

The 'close' event is emitted after a socket is closed with close(). Once triggered, no new 'message' events will be emitted on this socket.

Event: 'error'#

  • exception Error object

The 'error' event is emitted whenever any error occurs. The event handler function is passed a single Error object.

Event: 'listening'#

The 'listening' event is emitted whenever a socket begins listening for datagram messages. This occurs as soon as UDP sockets are created.

Event: 'message'#

  • msg Buffer object. The message
  • rinfo Object. Remote address information

The 'message' event is emitted when a new datagram is available on a socket. The event handler function is passed two arguments: msg and rinfo. The msg argument is a Buffer and rinfo is an object with the sender's address information provided by the address, family and port properties:

socket.on('message', (msg, rinfo) => {
  console.log('Received %d bytes from %s:%d\n',
              msg.length, rinfo.address, rinfo.port);
});

socket.addMembership(multicastAddress[, multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

Tells the kernel to join a multicast group at the given multicastAddress using the IP_ADD_MEMBERSHIP socket option. If the multicastInterface argument is not specified, the operating system will try to add membership to all valid networking interfaces.

socket.address()#

Returns an object containing the address information for a socket. For UDP sockets, this object will contain address, family and port properties.

[socket.bind([port][, address][, callback])]#

  • port Integer, Optional
  • address String, Optional
  • callback Function with no parameters, Optional. Called when binding is complete.

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address. If port is not specified, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

Note that specifying both a 'listening' event listener and passing a callback to the socket.bind() method is not harmful but not very useful.

A bound datagram socket keeps the Node.js process running to receive datagram messages.

If binding fails, an 'error' event is generated. In rare case (e.g. attempting to bind with a closed socket), an Error may be thrown.

Example of a UDP server listening on port 41234:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(41234);
// server listening 0.0.0.0:41234

socket.bind(options[, callback])#

  • options Object - Required. Supports the following properties:
    • port Number - Required.
    • address String - Optional.
    • exclusive Boolean - Optional.
  • callback Function - Optional.

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address that are passed as properties of an options object passed as the first argument. If port is not specified, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

The options object may contain an additional exclusive property that is use when using dgram.Socket objects with the [cluster] module. When exclusive is set to false (the default), cluster workers will use the same underlying socket handle allowing connection handling duties to be shared. When exclusive is true, however, the handle is not shared and attempted port sharing results in an error.

An example socket listening on an exclusive port is shown below.

socket.bind({
  address: 'localhost',
  port: 8000,
  exclusive: true
});

socket.close([callback])#

Close the underlying socket and stop listening for data on it. If a callback is provided, it is added as a listener for the 'close' event.

socket.dropMembership(multicastAddress[, multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

Instructs the kernel to leave a multicast group at multicastAddress using the IP_DROP_MEMBERSHIP socket option. This method is automatically called by the kernel when the socket is closed or the process terminates, so most apps will never have reason to call this.

If multicastInterface is not specified, the operating system will attempt to drop membership on all valid interfaces.

socket.send(buf, offset, length, port, address[, callback])#

  • buf Buffer object or string. Message to be sent
  • offset Integer. Offset in the buffer where the message starts.
  • length Integer. Number of bytes in the message.
  • port Integer. Destination port.
  • address String. Destination hostname or IP address.
  • callback Function. Called when the message has been sent. Optional.

Broadcasts a datagram on the socket. The destination port and address must be specified.

The buf argument is a Buffer object containing the message. The offset and length specify the offset within the Buffer where the message begins and the number of bytes in the message, respectively. With messages that contain multi-byte characters, offset and length will be calculated with respect to byte length and not the character position.

The address argument is a string. If the value of address is a host name, DNS will be used to resolve the address of the host. If the address is not specified or is an empty string, '0.0.0.0' or '::0' will be used instead. It is possible, depending on the network configuration, that these defaults may not work; accordingly, it is best to be explicit about the destination address.

If the socket has not been previously bound with a call to bind, the socket is assigned a random port number and is bound to the "all interfaces" address ('0.0.0.0' for udp4 sockets, '::0' for udp6 sockets.)

An optional callback function may be specified to as a way of reporting DNS errors or for determining when it is safe to reuse the buf object. Note that DNS lookups delay the time to send for at least one tick of the Node.js event loop.

The only way to know for sure that the datagram has been sent is by using a callback. If an error occurs and a callback is given, the error will be passed as the first argument to the callback. If a callback is not given, the error is emitted as an 'error' event on the socket object.

Example of sending a UDP packet to a random port on localhost;

const dgram = require('dgram');
const message = new Buffer('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 0, message.length, 41234, 'localhost', (err) => {
  client.close();
});

A Note about UDP datagram size

The maximum size of an IPv4/v6 datagram depends on the MTU (Maximum Transmission Unit) and on the Payload Length field size.

  • The Payload Length field is 16 bits wide, which means that a normal payload exceed 64K octets including the internet header and data (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); this is generally true for loopback interfaces, but such long datagram messages are impractical for most hosts and networks.

  • The MTU is the largest size a given link layer technology can support for datagram messages. For any link, IPv4 mandates a minimum MTU of 68 octets, while the recommended MTU for IPv4 is 576 (typically recommended as the MTU for dial-up type applications), whether they arrive whole or in fragments.

    For IPv6, the minimum MTU is 1280 octets, however, the mandatory minimum fragment reassembly buffer size is 1500 octets. The value of 68 octets is very small, since most current link layer technologies, like Ethernet, have a minimum MTU of 1500.

It is impossible to know in advance the MTU of each link through which a packet might travel. Sending a datagram greater than the receiver MTU will not work because the packet will get silently dropped without informing the source that the data did not reach its intended recipient.

socket.setBroadcast(flag)#

  • flag Boolean

Sets or clears the SO_BROADCAST socket option. When set to true, UDP packets may be sent to a local interface's broadcast address.

socket.setMulticastLoopback(flag)#

  • flag Boolean

Sets or clears the IP_MULTICAST_LOOP socket option. When set to true, multicast packets will also be received on the local interface.

socket.setMulticastTTL(ttl)#

  • ttl Integer

Sets the IP_MULTICAST_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through, specifically for multicast traffic. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded.

The argument passed to to socket.setMulticastTTL() is a number of hops between 0 and 255. The default on most systems is 1 but can vary.

socket.setTTL(ttl)#

  • ttl Integer

Sets the IP_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. Changing TTL values is typically done for network probes or when multicasting.

The argument to socket.setTTL() is a number of hops between 1 and 255. The default on most systems is 64 but can vary.

socket.ref()#

By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active. The socket.ref() method adds the socket back to the reference counting and restores the default behavior.

Calling socket.ref() multiples times will have no additional effect.

The socket.ref() method returns a reference to the socket so calls can be chained.

socket.unref()#

By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active, allowing the process to exit even if the socket is still listening.

Calling socket.unref() multiple times will have no addition effect.

The socket.unref() method returns a reference to the socket so calls can be chained.

Change to asynchronous socket.bind() behavior#

As of Node.js v0.10, dgram.Socket#bind() changed to an asynchronous execution model. Legacy code that assumes synchronous behavior, as in the following example:

const s = dgram.createSocket('udp4');
s.bind(1234);
s.addMembership('224.0.0.114');

Must be changed to pass a callback function to the dgram.Socket#bind() function:

const s = dgram.createSocket('udp4');
s.bind(1234, () => {
  s.addMembership('224.0.0.114');
});

dgram module functions#

dgram.createSocket(options[, callback])#

  • options Object
  • callback Function. Attached as a listener to 'message' events.
  • Returns: Socket object

Creates a dgram.Socket object. The options argument is an object that should contain a type field of either udp4 or udp6 and an optional boolean reuseAddr field.

When reuseAddr is true socket.bind() will reuse the address, even if another process has already bound a socket on it. reuseAddr defaults to false. An optional callback function can be passed specified which is added as a listener for 'message' events.

Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.

dgram.createSocket(type[, callback])#

  • type String. Either 'udp4' or 'udp6'
  • callback Function. Attached as a listener to 'message' events. Optional
  • Returns: Socket object

Creates a dgram.Socket object of the specified type. The type argument can be either udp4 or udp6. An optional callback function can be passed which is added as a listener for 'message' events.

Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.

DNS#

Stability: 2 - Stable

The dns module contains functions belonging to two different categories:

1) Functions that use the underlying operating system facilities to perform name resolution, and that do not necessarily perform any network communication. This category contains only one function: dns.lookup(). Developers looking to perform name resolution in the same way that other applications on the same operating system behave should use dns.lookup().

For example, looking up nodejs.org.

const dns = require('dns');

dns.lookup('nodejs.org', (err, addresses, family) => {
  console.log('addresses:', addresses);
});

2) Functions that connect to an actual DNS server to perform name resolution, and that always use the network to perform DNS queries. This category contains all functions in the dns module except dns.lookup(). These functions do not use the same set of configuration files used by dns.lookup() (e.g. /etc/hosts). These functions should be used by developers who do not want to use the underlying operating system's facilities for name resolution, and instead want to always perform DNS queries.

Below is an example that resolves 'nodejs.org' then reverse resolves the IP addresses that are returned.

const dns = require('dns');

dns.resolve4('nodejs.org', (err, addresses) => {
  if (err) throw err;

  console.log(`addresses: ${JSON.stringify(addresses)}`);

  addresses.forEach((a) => {
    dns.reverse(a, (err, hostnames) => {
      if (err) {
        throw err;
      }
      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
    });
  });
});

There are subtle consequences in choosing one over the other, please consult the Implementation considerations section for more information.

dns.getServers()#

Returns an array of IP address strings that are being used for name resolution.

dns.lookup(hostname[, options], callback)#

Resolves a hostname (e.g. 'nodejs.org') into the first found A (IPv4) or AAAA (IPv6) record. options can be an object or integer. If options is not provided, then IPv4 and IPv6 addresses are both valid. If options is an integer, then it must be 4 or 6.

Alternatively, options can be an object containing these properties:

  • family {Number} - The record family. If present, must be the integer 4 or 6. If not provided, both IP v4 and v6 addresses are accepted.
  • hints: {Number} - If present, it should be one or more of the supported getaddrinfo flags. If hints is not provided, then no flags are passed to getaddrinfo. Multiple flags can be passed through hints by logically ORing their values. See supported getaddrinfo flags below for more information on supported flags.
  • all: {Boolean} - When true, the callback returns all resolved addresses in an array, otherwise returns a single address. Defaults to false.

All properties are optional. An example usage of options is shown below.

{
  family: 4,
  hints: dns.ADDRCONFIG | dns.V4MAPPED,
  all: false
}

The callback function has arguments (err, address, family). address is a string representation of an IPv4 or IPv6 address. family is either the integer 4 or 6 and denotes the family of address (not necessarily the value initially passed to lookup).

With the all option set to true, the arguments change to (err, addresses), with addresses being an array of objects with the properties address and family.

On error, err is an Error object, where err.code is the error code. Keep in mind that err.code will be set to 'ENOENT' not only when the hostname does not exist but also when the lookup fails in other ways such as no available file descriptors.

dns.lookup() does not necessarily have anything to do with the DNS protocol. The implementation uses an operating system facility that can associate names with addresses, and vice versa. This implementation can have subtle but important consequences on the behavior of any Node.js program. Please take some time to consult the Implementation considerations section before using dns.lookup().

Supported getaddrinfo flags#

The following flags can be passed as hints to dns.lookup().

  • dns.ADDRCONFIG: Returned address types are determined by the types of addresses supported by the current system. For example, IPv4 addresses are only returned if the current system has at least one IPv4 address configured. Loopback addresses are not considered.
  • dns.V4MAPPED: If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. Note that it is not supported on some operating systems (e.g FreeBSD 10.1).

dns.lookupService(address, port, callback)#

Resolves the given address and port into a hostname and service using the operating system's underlying getnameinfo implementation.

The callback has arguments (err, hostname, service). The hostname and service arguments are strings (e.g. 'localhost' and 'http' respectively).

On error, err is an Error object, where err.code is the error code.

const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
  console.log(hostname, service);
    // Prints: localhost ssh
});

dns.resolve(hostname[, rrtype], callback)#

Uses the DNS protocol to resolve a hostname (e.g. 'nodejs.org') into an array of the record types specified by rrtype.

Valid values for rrtype are:

  • 'A' - IPV4 addresses, default
  • 'AAAA' - IPV6 addresses
  • 'MX' - mail exchange records
  • 'TXT' - text records
  • 'SRV' - SRV records
  • 'PTR' - used for reverse IP lookups
  • 'NS' - name server records
  • 'CNAME' - canonical name records
  • 'SOA' - start of authority record

The callback function has arguments (err, addresses). When successful, addresses will be an array. The type of each item in addresses is determined by the record type, and described in the documentation for the corresponding lookup methods below.

On error, err is an Error object, where err.code is one of the error codes listed below.

dns.resolve4(hostname, callback)#

Uses the DNS protocol to resolve a IPv4 addresses (A records) for the hostname. The addresses argument passed to the callback function will contain an array of IPv4 addresses (e.g. ['74.125.79.104', '74.125.79.105', '74.125.79.106']).

dns.resolve6(hostname, callback)#

Uses the DNS protocol to resolve a IPv6 addresses (AAAA records) for the hostname. The addresses argument passed to the callback function will contain an array of IPv6 addresses.

dns.resolveCname(hostname, callback)#

Uses the DNS protocol to resolve CNAME records for the hostname. The addresses argument passed to the callback function will contain an of canonical name records available for the hostname (e.g. ['bar.example.com']).

dns.resolveMx(hostname, callback)#

Uses the DNS protocol to resolve mail exchange records (MX records) for the hostname. The addresses argument passed to the callback function will contain an array of objects containing both a priority and exchange property (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).

dns.resolveNs(hostname, callback)#

Uses the DNS protocol to resolve name server records (NS records) for the hostname. The addresses argument passed to the callback function will contain an array of name server records available for hostname (e.g., ['ns1.example.com', 'ns2.example.com']).

dns.resolveSoa(hostname, callback)#

Uses the DNS protocol to resolve a start of authority record (SOA record) for the hostname. The addresses argument passed to the callback function will be an object with the following properties:

  • nsname
  • hostmaster
  • serial
  • refresh
  • retry
  • expire
  • minttl

    {

    nsname: 'ns.example.com',
    hostmaster: 'root.example.com',
    serial: 2013101809,
    refresh: 10000,
    retry: 2400,
    expire: 604800,
    minttl: 3600

    }

dns.resolveSrv(hostname, callback)#

Uses the DNS protocol to resolve service records (SRV records) for the hostname. The addresses argument passed to the callback function will be an array of objects with the following properties:

  • priority
  • weight
  • port
  • name

    {

    priority: 10,
    weight: 5,
    port: 21223,
    name: 'service.example.com'

    }

dns.resolveTxt(hostname, callback)#

Uses the DNS protocol to resolve text queries (TXT records) for the hostname. The addresses argument passed to the callback function is is a two-dimentional array of the text records available for hostname (e.g., [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately.

dns.reverse(ip, callback)#

Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of hostnames.

The callback function has arguments (err, hostnames), where hostnames is an array of resolved hostnames for the given ip.

On error, err is an Error object, where err.code is one of the error codes listed below.

dns.setServers(servers)#

Sets the IP addresses of the servers to be used when resolving. The servers argument is an array of IPv4 or IPv6 addresses.

If a port specified on the address it will be removed.

An error will be thrown if an invalid address is provided.

The dns.setServers() method must not be called while a DNS query is in progress.

Error codes#

Each DNS query can return one of the following error codes:

  • dns.NODATA: DNS server returned answer with no data.
  • dns.FORMERR: DNS server claims query was misformatted.
  • dns.SERVFAIL: DNS server returned general failure.
  • dns.NOTFOUND: Domain name not found.
  • dns.NOTIMP: DNS server does not implement requested operation.
  • dns.REFUSED: DNS server refused query.
  • dns.BADQUERY: Misformatted DNS query.
  • dns.BADNAME: Misformatted hostname.
  • dns.BADFAMILY: Unsupported address family.
  • dns.BADRESP: Misformatted DNS reply.
  • dns.CONNREFUSED: Could not contact DNS servers.
  • dns.TIMEOUT: Timeout while contacting DNS servers.
  • dns.EOF: End of file.
  • dns.FILE: Error reading file.
  • dns.NOMEM: Out of memory.
  • dns.DESTRUCTION: Channel is being destroyed.
  • dns.BADSTR: Misformatted string.
  • dns.BADFLAGS: Illegal flags specified.
  • dns.NONAME: Given hostname is not numeric.
  • dns.BADHINTS: Illegal hints flags specified.
  • dns.NOTINITIALIZED: c-ares library initialization not yet performed.
  • dns.LOADIPHLPAPI: Error loading iphlpapi.dll.
  • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
  • dns.CANCELLED: DNS query cancelled.

Implementation considerations#

Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

dns.lookup()#

Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like operating systems, the behavior of the dns.lookup() function can be modified by changing settings in nsswitch.conf(5) and/or resolv.conf(5), but note that changing these files will change the behavior of all other programs running on the same operating system.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it means that if for whatever reason the call to getaddrinfo(3) takes a long time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than 4 (its current default value). For more information on libuv's threadpool, see the official libuv documentation.

dns.resolve(), dns.resolve*() and dns.reverse()#

These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not use libuv's threadpool.

As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

They do not use the same set of configuration files than what dns.lookup() uses. For instance, they do not use the configuration from /etc/hosts.

Domain#

Stability: 0 - Deprecated

This module is pending deprecation. Once a replacement API has been finalized, this module will be fully deprecated. Most end users should not have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.

Domains provide a way to handle multiple different IO operations as a single group. If any of the event emitters or callbacks registered to a domain emit an 'error' event, or throw an error, then the domain object will be notified, rather than losing the context of the error in the process.on('uncaughtException') handler, or causing the program to exit immediately with an error code.

Warning: Don't Ignore Errors!#

Domain error handlers are not a substitute for closing down your process when an error occurs.

By the very nature of how throw works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state.

The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else.

The better approach is to send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.

In this way, domain usage goes hand-in-hand with the cluster module, since the master process can fork a new worker when a worker encounters an error. For Node.js programs that scale to multiple machines, the terminating proxy or service registry can take note of the failure, and react accordingly.

For example, this is not a good idea:

// XXX WARNING!  BAD IDEA!

var d = require('domain').create();
d.on('error', (er) => {
  // The error won't crash the process, but what it does is worse!
  // Though we've prevented abrupt process restarting, we are leaking
  // resources like crazy if this ever happens.
  // This is no better than process.on('uncaughtException')!
  console.log('error, but oh well', er.message);
});
d.run(() => {
  require('http').createServer((req, res) => {
    handleRequest(req, res);
  }).listen(PORT);
});

By using the context of a domain, and the resilience of separating our program into multiple worker processes, we can react more appropriately, and handle errors with much greater safety.

// Much better!

const cluster = require('cluster');
const PORT = +process.env.PORT || 1337;

if (cluster.isMaster) {
  // In real life, you'd probably use more than just 2 workers,
  // and perhaps not put the master and worker in the same file.
  //
  // You can also of course get a bit fancier about logging, and
  // implement whatever custom logic you need to prevent DoS
  // attacks and other bad behavior.
  //
  // See the options in the cluster documentation.
  //
  // The important thing is that the master does very little,
  // increasing our resilience to unexpected errors.

  cluster.fork();
  cluster.fork();

  cluster.on('disconnect', (worker) => {
    console.error('disconnect!');
    cluster.fork();
  });

} else {
  // the worker
  //
  // This is where we put our bugs!

  const domain = require('domain');

  // See the cluster documentation for more details about using
  // worker processes to serve requests.  How it works, caveats, etc.

  const server = require('http').createServer((req, res) => {
    var d = domain.create();
    d.on('error', (er) => {
      console.error('error', er.stack);

      // Note: we're in dangerous territory!
      // By definition, something unexpected occurred,
      // which we probably didn't want.
      // Anything can happen now!  Be very careful!

      try {
        // make sure we close down within 30 seconds
        var killtimer = setTimeout(() => {
          process.exit(1);
        }, 30000);
        // But don't keep the process open just for that!
        killtimer.unref();

        // stop taking new requests.
        server.close();

        // Let the master know we're dead.  This will trigger a
        // 'disconnect' in the cluster master, and then it will fork
        // a new worker.
        cluster.worker.disconnect();

        // try to send an error to the request that triggered the problem
        res.statusCode = 500;
        res.setHeader('content-type', 'text/plain');
        res.end('Oops, there was a problem!\n');
      } catch (er2) {
        // oh well, not much we can do at this point.
        console.error('Error sending 500!', er2.stack);
      }
    });

    // Because req and res were created before this domain existed,
    // we need to explicitly add them.
    // See the explanation of implicit vs explicit binding below.
    d.add(req);
    d.add(res);

    // Now run the handler function in the domain.
    d.run(() => {
      handleRequest(req, res);
    });
  });
  server.listen(PORT);
}

// This part isn't important.  Just an example routing thing.
// You'd put your fancy application logic here.
function handleRequest(req, res) {
  switch(req.url) {
    case '/error':
      // We do some async stuff, and then...
      setTimeout(() => {
        // Whoops!
        flerb.bark();
      });
      break;
    default:
      res.end('ok');
  }
}

Additions to Error objects#

Any time an Error object is routed through a domain, a few extra fields are added to it.

  • error.domain The domain that first handled the error.
  • error.domainEmitter The event emitter that emitted an 'error' event with the error object.
  • error.domainBound The callback function which was bound to the domain, and passed an error as its first argument.
  • error.domainThrown A boolean indicating whether the error was thrown, emitted, or passed to a bound callback function.

Implicit Binding#

If domains are in use, then all new EventEmitter objects (including Stream objects, requests, responses, etc.) will be implicitly bound to the active domain at the time of their creation.

Additionally, callbacks passed to lowlevel event loop requests (such as to fs.open, or other callback-taking methods) will automatically be bound to the active domain. If they throw, then the domain will catch the error.

In order to prevent excessive memory usage, Domain objects themselves are not implicitly added as children of the active domain. If they were, then it would be too easy to prevent request and response objects from being properly garbage collected.

If you want to nest Domain objects as children of a parent Domain, then you must explicitly add them.

Implicit binding routes thrown errors and 'error' events to the Domain's 'error' event, but does not register the EventEmitter on the Domain, so domain.dispose() will not shut down the EventEmitter. Implicit binding only takes care of thrown errors and 'error' events.

Explicit Binding#

Sometimes, the domain in use is not the one that ought to be used for a specific event emitter. Or, the event emitter could have been created in the context of one domain, but ought to instead be bound to some other domain.

For example, there could be one domain in use for an HTTP server, but perhaps we would like to have a separate domain to use for each request.

That is possible via explicit binding.

For example:

// create a top-level domain for the server
const domain = require('domain');
const http = require('http');
const serverDomain = domain.create();

serverDomain.run(() => {
  // server is created in the scope of serverDomain
  http.createServer((req, res) => {
    // req and res are also created in the scope of serverDomain
    // however, we'd prefer to have a separate domain for each request.
    // create it first thing, and add req and res to it.
    var reqd = domain.create();
    reqd.add(req);
    reqd.add(res);
    reqd.on('error', (er) => {
      console.error('Error', er, req.url);
      try {
        res.writeHead(500);
        res.end('Error occurred, sorry.');
      } catch (er) {
        console.error('Error sending 500', er, req.url);
      }
    });
  }).listen(1337);
});

domain.create()#

  • return: Domain

Returns a new Domain object.

Class: Domain#

The Domain class encapsulates the functionality of routing errors and uncaught exceptions to the active Domain object.

Domain is a child class of EventEmitter. To handle the errors that it catches, listen to its 'error' event.

domain.run(fn[, arg][, ...])#

  • fn Function

Run the supplied function in the context of the domain, implicitly binding all event emitters, timers, and lowlevel requests that are created in that context. Optionally, arguments can be passed to the function.

This is the most basic way to use a domain.

Example:

const domain = require('domain');
const fs = require('fs');
const d = domain.create();
d.on('error', (er) => {
  console.error('Caught error!', er);
});
d.run(() => {
  process.nextTick(() => {
    setTimeout(() => { // simulating some various async stuff
      fs.open('non-existent file', 'r', (er, fd) => {
        if (er) throw er;
        // proceed...
      });
    }, 100);
  });
});

In this example, the d.on('error') handler will be triggered, rather than crashing the program.

domain.members#

  • Array

An array of timers and event emitters that have been explicitly added to the domain.

domain.add(emitter)#

  • emitter EventEmitter | Timer emitter or timer to be added to the domain

Explicitly adds an emitter to the domain. If any event handlers called by the emitter throw an error, or if the emitter emits an 'error' event, it will be routed to the domain's 'error' event, just like with implicit binding.

This also works with timers that are returned from setInterval() and setTimeout(). If their callback function throws, it will be caught by the domain 'error' handler.

If the Timer or EventEmitter was already bound to a domain, it is removed from that one, and bound to this one instead.

domain.remove(emitter)#

  • emitter EventEmitter | Timer emitter or timer to be removed from the domain

The opposite of domain.add(emitter). Removes domain handling from the specified emitter.

domain.bind(callback)#

  • callback Function The callback function
  • return: Function The bound function

The returned function will be a wrapper around the supplied callback function. When the returned function is called, any errors that are thrown will be routed to the domain's 'error' event.

Example#

const d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.bind(function(er, data) {
    // if this throws, it will also be passed to the domain
    return cb(er, data ? JSON.parse(data) : null);
  }));
}

d.on('error', (er) => {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.intercept(callback)#

  • callback Function The callback function
  • return: Function The intercepted function

This method is almost identical to domain.bind(callback). However, in addition to catching thrown errors, it will also intercept Error objects sent as the first argument to the function.

In this way, the common if (err) return callback(err); pattern can be replaced with a single error handler in a single place.

Example#

const d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.intercept(function(data) {
    // note, the first argument is never passed to the
    // callback since it is assumed to be the 'Error' argument
    // and thus intercepted by the domain.

    // if this throws, it will also be passed to the domain
    // so the error-handling logic can be moved to the 'error'
    // event on the domain instead of being repeated throughout
    // the program.
    return cb(null, JSON.parse(data));
  }));
}

d.on('error', (er) => {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.enter()#

The enter method is plumbing used by the run, bind, and intercept methods to set the active domain. It sets domain.active and process.domain to the domain, and implicitly pushes the domain onto the domain stack managed by the domain module (see domain.exit() for details on the domain stack). The call to enter delimits the beginning of a chain of asynchronous calls and I/O operations bound to a domain.

Calling enter changes only the active domain, and does not alter the domain itself. enter and exit can be called an arbitrary number of times on a single domain.

If the domain on which enter is called has been disposed, enter will return without setting the domain.

domain.exit()#

The exit method exits the current domain, popping it off the domain stack. Any time execution is going to switch to the context of a different chain of asynchronous calls, it's important to ensure that the current domain is exited. The call to exit delimits either the end of or an interruption to the chain of asynchronous calls and I/O operations bound to a domain.

If there are multiple, nested domains bound to the current execution context, exit will exit any domains nested within this domain.

Calling exit changes only the active domain, and does not alter the domain itself. enter and exit can be called an arbitrary number of times on a single domain.

If the domain on which exit is called has been disposed, exit will return without exiting the domain.

domain.dispose()#

Stability: 0 - Deprecated.  Please recover from failed IO actions
explicitly via error event handlers set on the domain.

Once dispose has been called, the domain will no longer be used by callbacks bound into the domain via run, bind, or intercept, and a 'dispose' event is emitted.

Errors#

Applications running in Node.js will generally experience four categories of errors:

  • Standard JavaScript errors such as:
    • [EvalError][]: thrown when a call to eval() fails.
    • SyntaxError: thrown in response to improper JavaScript language syntax.
    • RangeError: thrown when a value is not within an expected range
    • ReferenceError: thrown when using undefined variables
    • TypeError: thrown when passing arguments of the wrong type
    • [URIError][]: thrown when a global URI handling function is misused.
  • System errors triggered by underlying operating system constraints such as attempting to open a file that does not exist, attempting to send data over a closed socket, etc;
  • And User-specified errors triggered by application code.
  • Assertion Errors are a special class of error that can be triggered whenever Node.js detects an exceptional logic violation that should never occur. These are raised typically by the assert module.

All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript Error class and are guaranteed to provide at least the properties available on that class.

Error Propagation and Interception#

Node.js supports several mechanisms for propagating and handling errors that occur while an application is running. How these errors are reported and handled depends entirely on the type of Error and the style of the API that is called.

All JavaScript errors are handled as exceptions that immediately generate and throw an error using the standard JavaScript throw mechanism. These are handled using the try / catch construct provided by the JavaScript language.

// Throws with a ReferenceError because z is undefined
try {
  const m = 1;
  const n = m + z;
} catch (err) {
  // Handle the error here.
}

Any use of the JavaScript throw mechanism will raise an exception that must be handled using try / catch or the Node.js process will exit immediately.

With few exceptions, Synchronous APIs (any blocking method that does not accept a callback function, such as fs.readFileSync), will use throw to report errors.

Errors that occur within Asynchronous APIs may be reported in multiple ways:

  • Most asynchronous methods that accept a callback function will accept an Error object passed as the first argument to that function. If that first argument is not null and is an instance of Error, then an error occurred that should be handled.

    const fs = require('fs');
    fs.readFile('a file that does not exist', (err, data) => {
      if (err) {
        console.error('There was an error reading the file!', err);
        return;
      }
      // Otherwise handle the data
    });
  • When an asynchronous method is called on an object that is an EventEmitter, errors can be routed to that object's 'error' event.

    const net = require('net');
    const connection = net.connect('localhost');
    
    // Adding an 'error' event handler to a stream:
    connection.on('error', (err) => {
      // If the connection is reset by the server, or if it can't
      // connect at all, or on any sort of error encountered by
      // the connection, the error will be sent here.
      console.error(err);
    });
    
    connection.pipe(process.stdout);
  • A handful of typically asynchronous methods in the Node.js API may still use the throw mechanism to raise exceptions that must be handled using try / catch. There is no comprehensive list of such methods; please refer to the documentation of each method to determine the appropriate error handling mechanism required.

The use of the 'error' event mechanism is most common for stream-based and event emitter-based APIs, which themselves represent a series of asynchronous operations over time (as opposed to a single operation that may pass or fail).

For all EventEmitter objects, if an 'error' event handler is not provided, the error will be thrown, causing the Node.js process to report an unhandled exception and crash unless either: The domain module is used appropriately or a handler has been registered for the process.on('uncaughtException') event.

const EventEmitter = require('events');
const ee = new EventEmitter();

setImmediate(() => {
  // This will crash the process because no 'error' event
  // handler has been added.
  ee.emit('error', new Error('This will crash'));
});

Errors generated in this way cannot be intercepted using try / catch as they are thrown after the calling code has already exited.

Developers must refer to the documentation for each method to determine exactly how errors raised by those methods are propagated.

Node.js style callbacks#

Most asynchronous methods exposed by the Node.js core API follow an idiomatic pattern referred to as a "Node.js style callback". With this pattern, a callback function is passed to the method as an argument. When the operation either completes or an error is raised, the callback function is called with the Error object (if any) passed as the first argument. If no error was raised, the first argument will be passed as null.

const fs = require('fs');

function nodeStyleCallback(err, data) {
 if (err) {
   console.error('There was an error', err);
   return;
 }
 console.log(data);
}

fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);
fs.readFile('/some/file/that/does-exist', nodeStyleCallback)

The JavaScript try / catch mechanism cannot be used to intercept errors generated by asynchronous APIs. A common mistake for beginners is to try to use throw inside a Node.js style callback:

// THIS WILL NOT WORK:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // mistaken assumption: throwing here...
    if (err) {
      throw err;
    }
  });
} catch(err) {
  // This will not catch the throw!
  console.log(err);
}

This will not work because the callback function passed to fs.readFile() is called asynchronously. By the time the callback has been called, the surrounding code (including the try { } catch(err) { } block will have already exited. Throwing an error inside the callback can crash the Node.js process in most cases. If domains are enabled, or a handler has been registered with process.on('uncaughtException'), such errors can be intercepted.

Class: Error#

A generic JavaScript Error object that does not denote any specific circumstance of why the error occurred. Error objects capture a "stack trace" detailing the point in the code at which the Error was instantiated, and may provide a text description of the error.

All errors generated by Node.js, including all System and JavaScript errors, will either be instances of, or inherit from, the Error class.

new Error(message)#

Creates a new Error object and sets the error.message property to the provided text message. If an object is passed as message, the text message is generated by calling message.toString(). The error.stack property will represent the point in the code at which new Error() was called. Stack traces are dependent on V8's stack trace API. Stack traces extend only to either (a) the beginning of synchronous code execution, or (b) the number of frames given by the property Error.stackTraceLimit, whichever is smaller.

Error.captureStackTrace(targetObject[, constructorOpt])#

Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack  // similar to `new Error().stack`

The first line of the trace, instead of being prefixed with ErrorType: message, will be the result of calling targetObject.toString().

The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.

The constructorOpt argument is useful for hiding implementation details of error generation from an end user. For instance:

function MyError() {
  Error.captureStackTrace(this, MyError);
}

// Without passing MyError to captureStackTrace, the MyError
// frame would should up in the .stack property. by passing
// the constructor, we omit that frame and all frames above it.
new MyError().stack

Error.stackTraceLimit#

The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.

If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

error.message#

Returns the string description of error as set by calling new Error(message). The message passed to the constructor will also appear in the first line of the stack trace of the Error, however changing this property after the Error object is created may not change the first line of the stack trace.

const err = new Error('The message');
console.log(err.message);
  // Prints: The message

error.stack#

Returns a string describing the point in the code at which the Error was instantiated.

For example:

Error: Things keep happening!
   at /home/gbusey/file.js:525:2
   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
   at increaseSynergy (/home/gbusey/actors.js:701:6)

The first line is formatted as <error class name>: <error message>, and is followed by a series of stack frames (each line beginning with "at "). Each frame describes a call site within the code that lead to the error being generated. V8 attempts to display a name for each function (by variable name, function name, or object method name), but occasionally it will not be able to find a suitable name. If V8 cannot determine a name for the function, only location information will be displayed for that frame. Otherwise, the determined function name will be displayed with location information appended in parentheses.

It is important to note that frames are only generated for JavaScript functions. If, for example, execution synchronously passes through a C++ addon function called cheetahify, which itself calls a JavaScript function, the frame representing the cheetahify call will not be present in the stack traces:

const cheetahify = require('./native-binding.node');

function makeFaster() {
  // cheetahify *synchronously* calls speedy.
  cheetahify(function speedy() {
    throw new Error('oh no!');
  });
}

makeFaster(); // will throw:
  // /home/gbusey/file.js:6
  //     throw new Error('oh no!');
  //           ^
  // Error: oh no!
  //     at speedy (/home/gbusey/file.js:6:11)
  //     at makeFaster (/home/gbusey/file.js:5:3)
  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)
  //     at Module._compile (module.js:456:26)
  //     at Object.Module._extensions..js (module.js:474:10)
  //     at Module.load (module.js:356:32)
  //     at Function.Module._load (module.js:312:12)
  //     at Function.Module.runMain (module.js:497:10)
  //     at startup (node.js:119:16)
  //     at node.js:906:3

The location information will be one of:

  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • plain-filename.js:line:column, if the frame represents a call internal to Node.js.
  • /absolute/path/to/file.js:line:column, if the frame represents a call in a user program, or its dependencies.

The string representing the stack trace is lazily generated when the error.stack property is accessed.

The number of frames captured by the stack trace is bounded by the smaller of Error.stackTraceLimit or the number of available frames on the current event loop tick.

System-level errors are generated as augmented Error instances, which are detailed below.

Class: RangeError#

A subclass of Error that indicates that a provided argument was not within the set or range of acceptable values for a function; whether that is a numeric range, or outside the set of options for a given function parameter.

For example:

require('net').connect(-1);
  // throws RangeError, port should be > 0 && < 65536

Node.js will generate and throw RangeError instances immediately as a form of argument validation.

Class: ReferenceError#

A subclass of Error that indicates that an attempt is being made to access a variable that is not defined. Such errors commonly indicate typos in code, or an otherwise broken program.

While client code may generate and propagate these errors, in practice, only V8 will do so.

doesNotExist;
  // throws ReferenceError, doesNotExist is not a variable in this program.

ReferenceError instances will have an error.arguments property whose value is an array containing a single element: a string representing the variable that was not defined.

const assert = require('assert');
try {
  doesNotExist;
} catch(err) {
  assert(err.arguments[0], 'doesNotExist');
}

Unless an application is dynamically generating and running code, ReferenceError instances should always be considered a bug in the code or its dependencies.

Class: SyntaxError#

A subclass of Error that indicates that a program is not valid JavaScript. These errors may only be generated and propagated as a result of code evaluation. Code evaluation may happen as a result of eval, Function, require, or vm. These errors are almost always indicative of a broken program.

try {
  require('vm').runInThisContext('binary ! isNotOk');
} catch(err) {
  // err will be a SyntaxError
}

SyntaxError instances are unrecoverable in the context that created them – they may only be caught by other contexts.

Class: TypeError#

A subclass of Error that indicates that a provided argument is not an allowable type. For example, passing a function to a parameter which expects a string would be considered a TypeError.

require('url').parse(function() { });
  // throws TypeError, since it expected a string

Node.js will generate and throw TypeError instances immediately as a form of argument validation.

Exceptions vs. Errors#

A JavaScript exception is a value that is thrown as a result of an invalid operation or as the target of a throw statement. While it is not required that these values are instances of Error or classes which inherit from Error, all exceptions thrown by Node.js or the JavaScript runtime will be instances of Error.

Some exceptions are unrecoverable at the JavaScript layer. Such exceptions will always cause the Node.js process to crash. Examples include assert() checks or abort() calls in the C++ layer.

System Errors#

System errors are generated when exceptions occur within the program's runtime environment. Typically, these are operational errors that occur when an application violates an operating system constraint such as attempting to read a file that does not exist or when the user does not have sufficient permissions.

System errors are typically generated at the syscall level: an exhaustive list of error codes and their meanings is available by running man 2 intro or man 3 errno on most Unices; or online.

In Node.js, system errors are represented as augmented Error objects with added properties.

Class: System Error#

error.code#

error.errno#

Returns a string representing the error code, which is always E followed by a sequence of capital letters, and may be referenced in man 2 intro.

The properties error.code and error.errno are aliases of one another and return the same value.

error.syscall#

Returns a string describing the syscall that failed.

Common System Errors#

This list is not exhaustive, but enumerates many of the common system errors encountered when writing a Node.js program. An exhaustive list may be found here.

  • EACCES (Permission denied): An attempt was made to access a file in a way forbidden by its file access permissions.

  • EADDRINUSE (Address already in use): An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.

  • ECONNREFUSED (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.

  • ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the http and net modules.

  • EEXIST (File exists): An existing file was the target of an operation that required that the target not exist.

  • EISDIR (Is a directory): An operation expected a file, but the given pathname was a directory.

  • EMFILE (Too many open files in system): Maximum number of file descriptors allowable on the system has been reached, and requests for another descriptor cannot be fulfilled until at least one has been closed. This is encountered when opening many files at once in parallel, especially on systems (in particular, OS X) where there is a low file descriptor limit for processes. To remedy a low limit, run ulimit -n 2048 in the same shell that will run the Node.js process.

  • ENOENT (No such file or directory): Commonly raised by fs operations to indicate that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path.

  • ENOTDIR (Not a directory): A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.

  • ENOTEMPTY (Directory not empty): A directory with entries was the target of an operation that requires an empty directory -- usually fs.unlink.

  • EPERM (Operation not permitted): An attempt was made to perform an operation that requires elevated privileges.

  • EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the data. Commonly encountered at the net and http layers, indicative that the remote side of the stream being written to has been closed.

  • ETIMEDOUT (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by http or net -- often a sign that a socket.end() was not properly called.

Events#

Stability: 2 - Stable

Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") periodically emit named events that cause Function objects ("listeners") to be called.

For instance: a net.Server object emits an event each time a peer connects to it; a fs.ReadStream emits an event when the file is opened; a stream emits an event whenever data is available to be read.

All objects that emit events are instances of the EventEmitter class. These objects expose an eventEmitter.on() function that allows one or more Functions to be attached to named events emitted by the object. Typically, event names are camel-cased strings but any valid JavaScript property key can be used.

When the EventEmitter object emits an event, all of the Functions attached to that specific event are called synchronously. Any values returned by the called listeners are ignored and will be discarded.

The following example shows a simple EventEmitter instance with a single listener. The eventEmitter.on() method is used to register listeners, while the eventEmitter.emit() method is used to trigger the event.

const EventEmitter = require('events');
const util = require('util');

function MyEmitter() {
  EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter);

const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
  console.log('an event occurred!');
});
myEmitter.emit('event');

Any object can become an EventEmitter through inheritance. The example above uses the traditional Node.js style prototypical inheritance using the util.inherits() method. It is, however, possible to use ES6 classes as well:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
  console.log('an event occurred!');
});
myEmitter.emit('event');

Passing arguments and this to listeners#

The eventEmitter.emit() method allows an arbitrary set of arguments to be passed to the listener functions. It is important to keep in mind that when an ordinary listener function is called by the EventEmitter, the standard this keyword is intentionally set to reference the EventEmitter to which the listener is attached.

const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
  console.log(a, b, this);
    // Prints:
    //   a b MyEmitter {
    //     domain: null,
    //     _events: { event: [Function] },
    //     _eventsCount: 1,
    //     _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');

It is possible to use ES6 Arrow Functions as listeners, however, when doing so, the this keyword will no longer reference the EventEmitter instance:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  console.log(a, b, this);
    // Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');

Asynchronous vs. Synchronous#

The EventListener calls all listeners synchronously in the order in which they were registered. This is important to ensure the proper sequencing of events and to avoid race conditions or logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the setImmediate() or process.nextTick() methods:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('this happens asynchronously');
  });
});
myEmitter.emit('event', 'a', 'b');

Handling events only once#

When a listener is registered using the eventEmitter.on() method, that listener will be invoked every time the named event is emitted.

const myEmitter = new MyEmitter();
var m = 0;
myEmitter.on('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
  // Prints: 1
myEmitter.emit('event');
  // Prints: 2

Using the eventEmitter.once() method, it is possible to register a listener that is immediately unregistered after it is called.

const myEmitter = new MyEmitter();
var m = 0;
myEmitter.once('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
  // Prints: 1
myEmitter.emit('event');
  // Ignored

Error events#

When an error occurs within an EventEmitter instance, the typical action is for an 'error' event to be emitted. These are treated as a special case within Node.js.

If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.

const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
  // Throws and crashes Node.js

To guard against crashing the Node.js process, developers can either register a listener for the process.on('uncaughtException') event or use the domain module (Note, however, that the domain module has been deprecated).

const myEmitter = new MyEmitter();

process.on('uncaughtException', (err) => {
  console.log('whoops! there was an error');
});

myEmitter.emit('error', new Error('whoops!'));
  // Prints: whoops! there was an error

As a best practice, developers should always register listeners for the 'error' event:

const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
  console.log('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
  // Prints: whoops! there was an error

Class: EventEmitter#

The EventEmitter class is defined and exposed by the events module:

const EventEmitter = require('events');

All EventEmitters emit the event 'newListener' when new listeners are added and 'removeListener' when a listener is removed.

Event: 'newListener'#

  • event String|Symbol The event name
  • listener Function The event handler function

The EventEmitter instance will emit it's own 'newListener' event before a listener is added to it's internal array of listeners.

Listeners registered for the 'newListener' event will be passed the event name and a reference to the listener being added.

The fact that the event is triggered before adding the listener has a subtle but important side effect: any additional listeners registered to the same name within the 'newListener' callback will be inserted before the listener that is in the process of being added.

const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Insert a new listener in front
    myEmitter.on('event', () => {
      console.log('B');
    });
  }
});
myEmitter.on('event', () => {
  console.log('A');
});
myEmitter.emit('event');
  // Prints:
  //   B
  //   A

Event: 'removeListener'#

  • event String|Symbol The event name
  • listener Function The event handler function

The 'removeListener' event is emitted after a listener is removed.

EventEmitter.listenerCount(emitter, event)#

Stability: 0 - Deprecated: Use emitter.listenerCount() instead.

A class method that returns the number of listeners for the given event registered on the given emitter.

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(EventEmitter.listenerCount(myEmitter, 'event'));
  // Prints: 2

EventEmitter.defaultMaxListeners#

By default, a maximum of 10 listeners can be registered for any single event. This limit can be changed for individual EventEmitter instances using the emitter.setMaxListeners(n) method. To change the default for all EventEmitter instances, the EventEmitter.defaultMaxListeners property can be used.

Take caution when setting the EventEmitter.defaultMaxListeners because the change effects all EventEmitter instances, including those created before the change is made. However, calling emitter.setMaxListeners(n) still has precedence over EventEmitter.defaultMaxListeners.

Note that this is not a hard limit. The EventEmitter instance will allow more listeners to be added but will output a trace warning to stderr indicating that a possible EventEmitter memory leak has been detected. For any single EventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners() methods can be used to temporarily avoid this warning:

emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});

emitter.addListener(event, listener)#

Alias for emitter.on(event, listener).

emitter.emit(event[, arg1][, arg2][, ...])#

Synchronously calls each of the listeners registered for event, in the order they were registered, passing the supplied arguments to each.

Returns true if event had listeners, false otherwise.

emitter.getMaxListeners()#

Returns the current max listener value for the EventEmitter which is either set by emitter.setMaxListeners(n) or defaults to EventEmitter.defaultMaxListeners.

emitter.listenerCount(event)#

  • event Value The type of event

Returns the number of listeners listening to the event type.

emitter.listeners(event)#

Returns a copy of the array of listeners for the specified event.

server.on('connection', (stream) => {
  console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
  // Prints: [ [Function] ]

emitter.on(event, listener)#

Adds the listener function to the end of the listeners array for the specified event. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of event and listener will result in the listener being added, and called, multiple times.

server.on('connection', (stream) => {
  console.log('someone connected!');
});

Returns a reference to the EventEmitter so calls can be chained.

emitter.once(event, listener)#

Adds a one time listener function for the event. This listener is invoked only the next time event is triggered, after which it is removed.

server.once('connection', (stream) => {
  console.log('Ah, we have our first user!');
});

Returns a reference to the EventEmitter so calls can be chained.

emitter.removeAllListeners([event])#

Removes all listeners, or those of the specified event.

Note that it is bad practice to remove listeners added elsewhere in the code, particularly when the EventEmitter instance was created by some other component or module (e.g. sockets or file streams).

Returns a reference to the EventEmitter so calls can be chained.

emitter.removeListener(event, listener)#

Removes the specified listener from the listener array for the specified event.

var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);

removeListener will remove, at most, one instance of a listener from the listener array. If any single listener has been added multiple times to the listener array for the specified event, then removeListener must be called multiple times to remove each instance.

Because listeners are managed using an internal array, calling this will change the position indices of any listener registered after the listener being removed. This will not impact the order in which listeners are called, but it will means that any copies of the listener array as returned by the emitter.listeners() method will need to be recreated.

Returns a reference to the EventEmitter so calls can be chained.

emitter.setMaxListeners(n)#

By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) for to indicate an unlimited number of listeners.

Returns a reference to the EventEmitter so calls can be chained.

File System#

Stability: 2 - Stable

File I/O is provided by simple wrappers around standard POSIX functions. To use this module do require('fs'). All the methods have asynchronous and synchronous forms.

The asynchronous form always takes a completion callback as its last argument. The arguments passed to the completion callback depend on the method, but the first argument is always reserved for an exception. If the operation was completed successfully, then the first argument will be null or undefined.

When using the synchronous form any exceptions are immediately thrown. You can use try/catch to handle exceptions or allow them to bubble up.

Here is an example of the asynchronous version:

const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

Here is the synchronous version:

const fs = require('fs');

fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');

With the asynchronous methods there is no guaranteed ordering. So the following is prone to error:

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
  if (err) throw err;
  console.log(`stats: ${JSON.stringify(stats)}`);
});

It could be that fs.stat is executed before fs.rename. The correct way to do this is to chain the callbacks.

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  fs.stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
  });
});

In busy processes, the programmer is strongly encouraged to use the asynchronous versions of these calls. The synchronous versions will block the entire process until they complete--halting all connections.

The relative path to a filename can be used. Remember, however, that this path will be relative to process.cwd().

Most fs functions let you omit the callback argument. If you do, a default callback is used that rethrows errors. To get a trace to the original call site, set the NODE_DEBUG environment variable:

$ cat script.js
function bad() {
  require('fs').readFile('/');
}
bad();

$ env NODE_DEBUG=fs node script.js
fs.js:66
        throw err;
              ^
Error: EISDIR, read
    at rethrow (fs.js:61:21)
    at maybeCallback (fs.js:79:42)
    at Object.fs.readFile (fs.js:153:18)
    at bad (/path/to/script.js:2:17)
    at Object.<anonymous> (/path/to/script.js:5:1)
    <etc.>

Class: fs.FSWatcher#

Objects returned from fs.watch() are of this type.

Event: 'change'#

  • event String The type of fs change
  • filename String The filename that changed (if relevant/available)

Emitted when something changes in a watched directory or file. See more details in fs.watch().

Event: 'error'#

  • error Error object

Emitted when an error occurs.

watcher.close()#

Stop watching for changes on the given fs.FSWatcher.

Class: fs.ReadStream#

ReadStream is a Readable Stream.

Event: 'open'#

  • fd Integer file descriptor used by the ReadStream.

Emitted when the ReadStream's file is opened.

Class: fs.Stats#

Objects returned from fs.stat(), fs.lstat() and fs.fstat() and their synchronous counterparts are of this type.

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (only valid with fs.lstat())
  • stats.isFIFO()
  • stats.isSocket()

For a regular file util.inspect(stats) would return a string very similar to this:

{ dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

Please note that atime, mtime, birthtime, and ctime are instances of Date object and to compare the values of these objects you should use appropriate methods. For most general uses getTime() will return the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC and this integer should be sufficient for any comparison, however there are additional methods which can be used for displaying fuzzy information. More details can be found in the MDN JavaScript Reference page.

Stat Time Values#

The times in the stat object have the following semantics:

  • atime "Access Time" - Time when file data last accessed. Changed by the mknod(2), utimes(2), and read(2) system calls.
  • mtime "Modified Time" - Time when file data last modified. Changed by the mknod(2), utimes(2), and write(2) system calls.
  • ctime "Change Time" - Time when file status was last changed (inode data modification). Changed by the chmod(2), chown(2), link(2), mknod(2), rename(2), unlink(2), utimes(2), read(2), and write(2) system calls.
  • birthtime "Birth Time" - Time of file creation. Set once when the file is created. On filesystems where birthtime is not available, this field may instead hold either the ctime or 1970-01-01T00:00Z (ie, unix epoch timestamp 0). On Darwin and other FreeBSD variants, also set if the atime is explicitly set to an earlier value than the current birthtime using the utimes(2) system call.

Prior to Node v0.12, the ctime held the birthtime on Windows systems. Note that as of v0.12, ctime is not "creation time", and on Unix systems, it never was.

Class: fs.WriteStream#

WriteStream is a Writable Stream.

Event: 'open'#

  • fd Integer file descriptor used by the WriteStream.

Emitted when the WriteStream's file is opened.

writeStream.bytesWritten#

The number of bytes written so far. Does not include data that is still queued for writing.

fs.access(path[, mode], callback)#

Tests a user's permissions for the file specified by path. mode is an optional integer that specifies the accessibility checks to be performed. The following constants define the possible values of mode. It is possible to create a mask consisting of the bitwise OR of two or more values.

  • fs.F_OK - File is visible to the calling process. This is useful for determining if a file exists, but says nothing about rwx permissions. Default if no mode is specified.
  • fs.R_OK - File can be read by the calling process.
  • fs.W_OK - File can be written by the calling process.
  • fs.X_OK - File can be executed by the calling process. This has no effect on Windows (will behave like fs.F_OK).

The final argument, callback, is a callback function that is invoked with a possible error argument. If any of the accessibility checks fail, the error argument will be populated. The following example checks if the file /etc/passwd can be read and written by the current process.

fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) {
  console.log(err ? 'no access!' : 'can read/write');
});

fs.accessSync(path[, mode])#

Synchronous version of fs.access(). This throws if any accessibility checks fail, and does nothing otherwise.

fs.appendFile(file, data[, options], callback)#

  • file String | Integer filename or file descriptor
  • data String | Buffer
  • options Object | String
    • encoding String | Null default = 'utf8'
    • mode Number default = 0o666
    • flag String default = 'a'
  • callback Function

Asynchronously append data to a file, creating the file if it does not yet exist. data can be a string or a buffer.

Example:

fs.appendFile('message.txt', 'data to append', (err) => {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

If options is a string, then it specifies the encoding. Example:

fs.appendFile('message.txt', 'data to append', 'utf8', callback);

Any specified file descriptor has to have been opened for appending.

Note: Specified file descriptors will not be closed automatically.

fs.appendFileSync(file, data[, options])#

The synchronous version of fs.appendFile(). Returns undefined.

fs.chmod(path, mode, callback)#

Asynchronous chmod(2). No arguments other than a possible exception are given to the completion callback.

fs.chmodSync(path, mode)#

Synchronous chmod(2). Returns undefined.

fs.chown(path, uid, gid, callback)#

Asynchronous chown(2). No arguments other than a possible exception are given to the completion callback.

fs.chownSync(path, uid, gid)#

Synchronous chown(2). Returns undefined.

fs.close(fd, callback)#

Asynchronous close(2). No arguments other than a possible exception are given to the completion callback.

fs.closeSync(fd)#

Synchronous close(2). Returns undefined.

fs.createReadStream(path[, options])#

Returns a new ReadStream object. (See Readable Stream).

Be aware that, unlike the default value set for highWaterMark on a readable stream (16 kb), the stream returned by this method has a default value of 64 kb for the same parameter.

options is an object or string with the following defaults:

{ flags: 'r',
  encoding: null,
  fd: null,
  mode: 0o666,
  autoClose: true
}

options can include start and end values to read a range of bytes from the file instead of the entire file. Both start and end are inclusive and start at 0. The encoding can be any one of those accepted by Buffer.

If fd is specified, ReadStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. Note that fd should be blocking; non-blocking fds should be passed to net.Socket.

If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is your responsibility to close it and make sure there's no file descriptor leak. If autoClose is set to true (default behavior), on error or end the file descriptor will be closed automatically.

mode sets the file mode (permission and sticky bits), but only if the file was created.

An example to read the last 10 bytes of a file which is 100 bytes long:

fs.createReadStream('sample.txt', {start: 90, end: 99});

If options is a string, then it specifies the encoding.

fs.createWriteStream(path[, options])#

Returns a new WriteStream object. (See Writable Stream).

options is an object or string with the following defaults:

{ flags: 'w',
  defaultEncoding: 'utf8',
  fd: null,
  mode: 0o666 }

options may also include a start option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of r+ rather than the default mode w. The defaultEncoding can be any one of those accepted by Buffer.

Like ReadStream, if fd is specified, WriteStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. Note that fd should be blocking; non-blocking fds should be passed to net.Socket.

If options is a string, then it specifies the encoding.

fs.exists(path, callback)#

Stability: 0 - Deprecated: Use fs.stat() or fs.access() instead.

Test whether or not the given path exists by checking with the file system. Then call the callback argument with either true or false. Example:

fs.exists('/etc/passwd', (exists) => {
  console.log(exists ? 'it\'s there' : 'no passwd!');
});

fs.exists() should not be used to check if a file exists before calling fs.open(). Doing so introduces a race condition since other processes may change the file's state between the two calls. Instead, user code should call fs.open() directly and handle the error raised if the file is non-existent.

fs.existsSync(path)#

Stability: 0 - Deprecated: Use fs.statSync() or fs.accessSync() instead.

Synchronous version of fs.exists(). Returns true if the file exists, false otherwise.

fs.fchmod(fd, mode, callback)#

Asynchronous fchmod(2). No arguments other than a possible exception are given to the completion callback.

fs.fchmodSync(fd, mode)#

Synchronous fchmod(2). Returns undefined.

fs.fchown(fd, uid, gid, callback)#

Asynchronous fchown(2). No arguments other than a possible exception are given to the completion callback.

fs.fchownSync(fd, uid, gid)#

Synchronous fchown(2). Returns undefined.

fs.fstat(fd, callback)#

Asynchronous fstat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd.

fs.fstatSync(fd)#

Synchronous fstat(2). Returns an instance of fs.Stats.

fs.fsync(fd, callback)#

Asynchronous fsync(2). No arguments other than a possible exception are given to the completion callback.

fs.fsyncSync(fd)#

Synchronous fsync(2). Returns undefined.

fs.ftruncate(fd, len, callback)#

Asynchronous ftruncate(2). No arguments other than a possible exception are given to the completion callback.

fs.ftruncateSync(fd, len)#

Synchronous ftruncate(2). Returns undefined.

fs.futimes(fd, atime, mtime, callback)#

Change the file timestamps of a file referenced by the supplied file descriptor.

fs.futimesSync(fd, atime, mtime)#

Synchronous version of fs.futimes(). Returns undefined.

fs.lchmod(path, mode, callback)#

Asynchronous lchmod(2). No arguments other than a possible exception are given to the completion callback.

Only available on Mac OS X.

fs.lchmodSync(path, mode)#

Synchronous lchmod(2). Returns undefined.

fs.lchown(path, uid, gid, callback)#

Asynchronous lchown(2). No arguments other than a possible exception are given to the completion callback.

fs.lchownSync(path, uid, gid)#

Synchronous lchown(2). Returns undefined.

fs.link(srcpath, dstpath, callback)#

Asynchronous link(2). No arguments other than a possible exception are given to the completion callback.

fs.linkSync(srcpath, dstpath)#

Synchronous link(2). Returns undefined.

fs.lstat(path, callback)#

Asynchronous lstat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.

fs.lstatSync(path)#

Synchronous lstat(2). Returns an instance of fs.Stats.

fs.mkdir(path[, mode], callback)#

Asynchronous mkdir(2). No arguments other than a possible exception are given to the completion callback. mode defaults to 0o777.

fs.mkdirSync(path[, mode])#

Synchronous mkdir(2). Returns undefined.

fs.open(path, flags[, mode], callback)#

Asynchronous file open. See open(2). flags can be:

  • 'r' - Open file for reading. An exception occurs if the file does not exist.

  • 'r+' - Open file for reading and writing. An exception occurs if the file does not exist.

  • 'rs' - Open file for reading in synchronous mode. Instructs the operating system to bypass the local file system cache.

    This is primarily useful for opening files on NFS mounts as it allows you to skip the potentially stale local cache. It has a very real impact on I/O performance so don't use this flag unless you need it.

    Note that this doesn't turn fs.open() into a synchronous blocking call. If that's what you want then you should be using fs.openSync()

  • 'rs+' - Open file for reading and writing, telling the OS to open it synchronously. See notes for 'rs' about using this with caution.

  • 'w' - Open file for writing. The file is created (if it does not exist) or truncated (if it exists).

  • 'wx' - Like 'w' but fails if path exists.

  • 'w+' - Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).

  • 'wx+' - Like 'w+' but fails if path exists.

  • 'a' - Open file for appending. The file is created if it does not exist.

  • 'ax' - Like 'a' but fails if path exists.

  • 'a+' - Open file for reading and appending. The file is created if it does not exist.

  • 'ax+' - Like 'a+' but fails if path exists.

mode sets the file mode (permission and sticky bits), but only if the file was created. It defaults to 0666, readable and writeable.

The callback gets two arguments (err, fd).

The exclusive flag 'x' (O_EXCL flag in open(2)) ensures that path is newly created. On POSIX systems, path is considered to exist even if it is a symlink to a non-existent file. The exclusive flag may or may not work with network file systems.

flags can also be a number as documented by open(2); commonly used constants are available from require('constants'). On Windows, flags are translated to their equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE, or O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.openSync(path, flags[, mode])#

Synchronous version of fs.open(). Returns an integer representing the file descriptor.

fs.read(fd, buffer, offset, length, position, callback)#

Read data from the file specified by fd.

buffer is the buffer that the data will be written to.

offset is the offset in the buffer to start writing at.

length is an integer specifying the number of bytes to read.

position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.

The callback is given the three arguments, (err, bytesRead, buffer).

fs.readdir(path, callback)#

Asynchronous readdir(3). Reads the contents of a directory. The callback gets two arguments (err, files) where files is an array of the names of the files in the directory excluding '.' and '..'.

fs.readdirSync(path)#

Synchronous readdir(3). Returns an array of filenames excluding '.' and '..'.

fs.readFile(file[, options], callback)#

  • file String | Integer filename or file descriptor
  • options Object | String
    • encoding String | Null default = null
    • flag String default = 'r'
  • callback Function

Asynchronously reads the entire contents of a file. Example:

fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  console.log(data);
});

The callback is passed two arguments (err, data), where data is the contents of the file.

If no encoding is specified, then the raw buffer is returned.

If options is a string, then it specifies the encoding. Example:

fs.readFile('/etc/passwd', 'utf8', callback);

Any specified file descriptor has to support reading.

Note: Specified file descriptors will not be closed automatically.

fs.readFileSync(file[, options])#

Synchronous version of fs.readFile. Returns the contents of the file.

If the encoding option is specified then this function returns a string. Otherwise it returns a buffer.

fs.readlink(path, callback)#

Asynchronous readlink(2). The callback gets two arguments (err, linkString).

fs.readlinkSync(path)#

Synchronous readlink(2). Returns the symbolic link's string value.

fs.realpath(path[, cache], callback)#

Asynchronous realpath(2). The callback gets two arguments (err, resolvedPath). May use process.cwd to resolve relative paths. cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths.

Example:

var cache = {'/etc':'/private/etc'};
fs.realpath('/etc/passwd', cache, (err, resolvedPath) => {
  if (err) throw err;
  console.log(resolvedPath);
});

fs.readSync(fd, buffer, offset, length, position)#

Synchronous version of fs.read(). Returns the number of bytesRead.

fs.realpathSync(path[, cache])#

Synchronous realpath(2). Returns the resolved path. cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths.

fs.rename(oldPath, newPath, callback)#

Asynchronous rename(2). No arguments other than a possible exception are given to the completion callback.

fs.renameSync(oldPath, newPath)#

Synchronous rename(2). Returns undefined.

fs.rmdir(path, callback)#

Asynchronous rmdir(2). No arguments other than a possible exception are given to the completion callback.

fs.rmdirSync(path)#

Synchronous rmdir(2). Returns undefined.

fs.stat(path, callback)#

Asynchronous stat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. See the fs.Stats section below for more information.

fs.statSync(path)#

Synchronous stat(2). Returns an instance of fs.Stats.

fs.symlink(target, path[, type], callback)#

Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms). Note that Windows junction points require the destination path to be absolute. When using 'junction', the target argument will automatically be normalized to absolute path.

Here is an example below:

fs.symlink('./foo', './new-port');

It would create a symlic link named with "new-port" that points to "foo".

fs.symlinkSync(target, path[, type])#

Synchronous symlink(2). Returns undefined.

fs.truncate(path, len, callback)#

Asynchronous truncate(2). No arguments other than a possible exception are given to the completion callback. A file descriptor can also be passed as the first argument. In this case, fs.ftruncate() is called.

fs.truncateSync(path, len)#

Synchronous truncate(2). Returns undefined.

fs.unlink(path, callback)#

Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback.

fs.unlinkSync(path)#

Synchronous unlink(2). Returns undefined.

fs.unwatchFile(filename[, listener])#

Stop watching for changes on filename. If listener is specified, only that particular listener is removed. Otherwise, all listeners are removed and you have effectively stopped watching filename.

Calling fs.unwatchFile() with a filename that is not being watched is a no-op, not an error.

Note: fs.watch() is more efficient than fs.watchFile() and fs.unwatchFile(). fs.watch() should be used instead of fs.watchFile() and fs.unwatchFile() when possible.

fs.utimes(path, atime, mtime, callback)#

Change file timestamps of the file referenced by the supplied path.

Note: the arguments atime and mtime of the following related functions does follow the below rules:

  • If the value is a numberable string like '123456789', the value would get converted to corresponding number.
  • If the value is NaN or Infinity, the value would get converted to Date.now().

fs.utimesSync(path, atime, mtime)#

Synchronous version of fs.utimes(). Returns undefined.

fs.watch(filename[, options][, listener])#

Watch for changes on filename, where filename is either a file or a directory. The returned object is a fs.FSWatcher.

The second argument is optional. The options if provided should be an object. The supported boolean members are persistent and recursive. persistent indicates whether the process should continue to run as long as files are being watched. recursive indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See Caveats below).

The default is { persistent: true, recursive: false }.

The listener callback gets two arguments (event, filename). event is either 'rename' or 'change', and filename is the name of the file which triggered the event.

Caveats#

The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.

The recursive option is only supported on OS X and Windows.

Availability#

This feature depends on the underlying operating system providing a way to be notified of filesystem changes.

  • On Linux systems, this uses inotify.
  • On BSD systems, this uses kqueue.
  • On OS X, this uses kqueue for files and 'FSEvents' for directories.
  • On SunOS systems (including Solaris and SmartOS), this uses event ports.
  • On Windows systems, this feature depends on ReadDirectoryChangesW.

If the underlying functionality is not available for some reason, then fs.watch will not be able to function. For example, watching files or directories on network file systems (NFS, SMB, etc.) often doesn't work reliably or at all.

You can still use fs.watchFile, which uses stat polling, but it is slower and less reliable.

Filename Argument#

Providing filename argument in the callback is only supported on Linux and Windows. Even on supported platforms, filename is not always guaranteed to be provided. Therefore, don't assume that filename argument is always provided in the callback, and have some fallback logic if it is null.

fs.watch('somedir', (event, filename) => {
  console.log(`event is: ${event}`);
  if (filename) {
    console.log(`filename provided: ${filename}`);
  } else {
    console.log('filename not provided');
  }
});

fs.watchFile(filename[, options], listener)#

Watch for changes on filename. The callback listener will be called each time the file is accessed.

The options argument may be omitted. If provided, it should be an object. The options object may contain a boolean named persistent that indicates whether the process should continue to run as long as files are being watched. The options object may specify an interval property indicating how often the target should be polled in milliseconds. The default is { persistent: true, interval: 5007 }.

The listener gets two arguments the current stat object and the previous stat object:

fs.watchFile('message.text', (curr, prev) => {
  console.log(`the current mtime is: ${curr.mtime}`);
  console.log(`the previous mtime was: ${prev.mtime}`);
});

These stat objects are instances of fs.Stat.

If you want to be notified when the file was modified, not just accessed, you need to compare curr.mtime and prev.mtime.

Note: when an fs.watchFile operation results in an ENOENT error, it will invoke the listener once, with all the fields zeroed (or, for dates, the Unix Epoch). In Windows, blksize and blocks fields will be undefined, instead of zero. If the file is created later on, the listener will be called again, with the latest stat objects. This is a change in functionality since v0.10.

Note: fs.watch() is more efficient than fs.watchFile and fs.unwatchFile. fs.watch should be used instead of fs.watchFile and fs.unwatchFile when possible.

fs.write(fd, buffer, offset, length[, position], callback)#

Write buffer to the file specified by fd.

offset and length determine the part of the buffer to be written.

position refers to the offset from the beginning of the file where this data should be written. If typeof position !== 'number', the data will be written at the current position. See pwrite(2).

The callback will be given three arguments (err, written, buffer) where written specifies how many bytes were written from buffer.

Note that it is unsafe to use fs.write multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.write(fd, data[, position[, encoding]], callback)#

Write data to the file specified by fd. If data is not a Buffer instance then the value will be coerced to a string.

position refers to the offset from the beginning of the file where this data should be written. If typeof position !== 'number' the data will be written at the current position. See pwrite(2).

encoding is the expected string encoding.

The callback will receive the arguments (err, written, string) where written specifies how many bytes the passed string required to be written. Note that bytes written is not the same as string characters. See Buffer.byteLength.

Unlike when writing buffer, the entire string must be written. No substring may be specified. This is because the byte offset of the resulting data may not be the same as the string offset.

Note that it is unsafe to use fs.write multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.writeFile(file, data[, options], callback)#

  • file String | Integer filename or file descriptor
  • data String | Buffer
  • options Object | String
    • encoding String | Null default = 'utf8'
    • mode Number default = 0o666
    • flag String default = 'w'
  • callback Function

Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer.

The encoding option is ignored if data is a buffer. It defaults to 'utf8'.

Example:

fs.writeFile('message.txt', 'Hello Node.js', (err) => {
  if (err) throw err;
  console.log('It\'s saved!');
});

If options is a string, then it specifies the encoding. Example:

fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);

Any specified file descriptor has to support writing.

Note that it is unsafe to use fs.writeFile multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

Note: Specified file descriptors will not be closed automatically.

fs.writeFileSync(file, data[, options])#

The synchronous version of fs.writeFile(). Returns undefined.

fs.writeSync(fd, buffer, offset, length[, position])#

fs.writeSync(fd, data[, position[, encoding]])#

Synchronous versions of fs.write(). Returns the number of bytes written.

Global Objects#

These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

Class: Buffer#

  • {Function}

Used to handle binary data. See the buffer section.

__dirname#

  • {String}

The name of the directory that the currently executing script resides in.

Example: running node example.js from /Users/mjr

console.log(__dirname);
// /Users/mjr

__dirname isn't actually a global but rather local to each module.

__filename#

  • {String}

The filename of the code being executed. This is the resolved absolute path of this code file. For a main program this is not necessarily the same filename used in the command line. The value inside a module is the path to that module file.

Example: running node example.js from /Users/mjr

console.log(__filename);
// /Users/mjr/example.js

__filename isn't actually a global but rather local to each module.

clearInterval(t)#

Stop a timer that was previously created with setInterval(). The callback will not execute.

The timer functions are global variables. See the timers section.

clearTimeout(t)#

Stop a timer that was previously created with setTimeout(). The callback will not execute.

console#

  • {Object}

Used to print to stdout and stderr. See the console section.

exports#

A reference to the module.exports that is shorter to type. See module system documentation for details on when to use exports and when to use module.exports.

exports isn't actually a global but rather local to each module.

See the module system documentation for more information.

global#

  • {Object} The global namespace object.

In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside an Node.js module will be local to that module.

module#

  • {Object}

A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require().

module isn't actually a global but rather local to each module.

See the module system documentation for more information.

process#

  • {Object}

The process object. See the process object section.

require()#

  • {Function}

To require modules. See the Modules section. require isn't actually a global but rather local to each module.

require.cache#

  • Object

Modules are cached in this object when they are required. By deleting a key value from this object, the next require will reload the module.

require.extensions#

Stability: 0 - Deprecated
  • Object

Instruct require on how to handle certain file extensions.

Process files with the extension .sjs as .js:

require.extensions['.sjs'] = require.extensions['.js'];

Deprecated In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.

Since the Module system is locked, this feature will probably never go away. However, it may have subtle bugs and complexities that are best left untouched.

require.resolve()#

Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.

setInterval(cb, ms)#

Run callback cb repeatedly every ms milliseconds. Note that the actual interval may vary, depending on external factors like OS timer granularity and system load. It's never less than ms but it may be longer.

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

setTimeout(cb, ms)#

Run callback cb after at least ms milliseconds. The actual delay depends on external factors like OS timer granularity and system load.

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

HTTP#

Stability: 2 - Stable

To use the HTTP server and client one must require('http').

The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possibly chunk-encoded, messages. The interface is careful to never buffer entire requests or responses--the user is able to stream data.

HTTP message headers are represented by an object like this:

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }

Keys are lowercased. Values are not modified.

In order to support the full spectrum of possible HTTP applications, Node.js's HTTP API is very low-level. It deals with stream handling and message parsing only. It parses a message into headers and body but it does not parse the actual headers or the body.

See message.headers for details on how duplicate headers are handled.

The raw headers as they were received are retained in the rawHeaders property, which is an array of [key, value, key2, value2, ...]. For example, the previous message header object might have a rawHeaders list like the following:

[ 'ConTent-Length', '123456',
  'content-LENGTH', '123',
  'content-type', 'text/plain',
  'CONNECTION', 'keep-alive',
  'Host', 'mysite.com',
  'accepT', '*/*' ]

Class: http.Agent#

The HTTP Agent is used for pooling sockets used in HTTP client requests.

The HTTP Agent also defaults client requests to using Connection:keep-alive. If no pending HTTP requests are waiting on a socket to become free the socket is closed. This means that Node.js's pool has the benefit of keep-alive when under load but still does not require developers to manually close the HTTP clients using KeepAlive.

If you opt into using HTTP KeepAlive, you can create an Agent object with that flag set to true. (See the constructor options below.) Then, the Agent will keep unused sockets in a pool for later use. They will be explicitly marked so as to not keep the Node.js process running. However, it is still a good idea to explicitly destroy() KeepAlive agents when they are no longer in use, so that the Sockets will be shut down.

Sockets are removed from the agent's pool when the socket emits either a 'close' event or a special 'agentRemove' event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of:

http.get(options, (res) => {
  // Do stuff
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

Alternatively, you could just opt out of pooling entirely using agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // create a new agent just for this one request
}, (res) => {
  // Do stuff with response
})

new Agent(options)#

  • options Object Set of configurable options to set on the agent. Can have the following fields:
    • keepAlive Boolean Keep sockets around in a pool to be used by other requests in the future. Default = false
    • keepAliveMsecs Integer When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. Only relevant if keepAlive is set to true.
    • maxSockets Number Maximum number of sockets to allow per host. Default = Infinity.
    • maxFreeSockets Number Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256.

The default http.globalAgent that is used by http.request() has all of these values set to their respective defaults.

To configure any of them, you must create your own http.Agent object.

const http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.destroy()#

Destroy any sockets that are currently in use by the agent.

It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them.

agent.freeSockets#

An object which contains arrays of sockets currently awaiting use by the Agent when HTTP KeepAlive is used. Do not modify.

agent.getName(options)#

Get a unique name for a set of request options, to determine whether a connection can be reused. In the http agent, this returns host:port:localAddress. In the https agent, the name includes the CA, cert, ciphers, and other HTTPS/TLS-specific options that determine socket reusability.

agent.maxFreeSockets#

By default set to 256. For Agents supporting HTTP KeepAlive, this sets the maximum number of sockets that will be left open in the free state.

agent.maxSockets#

By default set to Infinity. Determines how many concurrent sockets the agent can have open per origin. Origin is either a 'host:port' or 'host:port:localAddress' combination.

agent.requests#

An object which contains queues of requests that have not yet been assigned to sockets. Do not modify.

agent.sockets#

An object which contains arrays of sockets currently in use by the Agent. Do not modify.

Class: http.ClientRequest#

This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued. The header is still mutable using the setHeader(name, value), getHeader(name), removeHeader(name) API. The actual header will be sent along with the first data chunk or when closing the connection.

To get the response, add a listener for 'response' to the request object. 'response' will be emitted from the request object when the response headers have been received. The 'response' event is executed with one argument which is an instance of http.IncomingMessage.

During the 'response' event, one can add listeners to the response object; particularly to listen for the 'data' event.

If no 'response' handler is added, then the response will be entirely discarded. However, if you add a 'response' event handler, then you must consume the data from the response object, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. Until the data is consumed, the 'end' event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.

Note: Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not.

The request implements the Writable Stream interface. This is an EventEmitter with the following events:

Event: 'abort'#

function () { }

Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().

Event: 'connect'#

function (response, socket, head) { }

Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed.

A client server pair that show you how to listen for the 'connect' event.

const http = require('http');
const net = require('net');
const url = require('url');

// Create an HTTP tunneling proxy
var proxy = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
proxy.on('connect', (req, cltSocket, head) => {
  // connect to an origin server
  var srvUrl = url.parse(`http://${req.url}`);
  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
    cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // make a request to a tunneling proxy
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80'
  };

  var req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});

Event: 'continue'#

function () { }

Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body.

Event: 'response'#

function (response) { }

Emitted when a response is received to this request. This event is emitted only once. The response argument will be an instance of http.IncomingMessage.

Options:

  • host: A domain name or IP address of the server to issue the request to.
  • port: Port of remote server.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath)

Event: 'socket'#

function (socket) { }

Emitted after a socket is assigned to this request.

Event: 'upgrade'#

function (response, socket, head) { }

Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed.

A client server pair that show you how to listen for the 'upgrade' event.

const http = require('http');

// Create an HTTP server
var srv = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
srv.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// now that server is running
srv.listen(1337, '127.0.0.1', () => {

  // make a request
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

  var req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});

request.abort()#

Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed.

request.end([data][, encoding][, callback])#

Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. If the request is chunked, this will send the terminating '0\r\n\r\n'.

If data is specified, it is equivalent to calling response.write(data, encoding) followed by request.end(callback).

If callback is specified, it will be called when the request stream is finished.

request.flushHeaders()#

Flush the request headers.

For efficiency reasons, Node.js normally buffers the request headers until you call request.end() or write the first chunk of request data. It then tries hard to pack the request headers and data into a single TCP packet.

That's usually what you want (it saves a TCP round-trip) but not when the first data isn't sent until possibly much later. request.flushHeaders() lets you bypass the optimization and kickstart the request.

request.setNoDelay([noDelay])#

Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.

request.setSocketKeepAlive([enable][, initialDelay])#

Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.

request.setTimeout(timeout[, callback])#

Once a socket is assigned to this request and is connected socket.setTimeout() will be called.

  • timeout {Number} Milliseconds before a request is considered to be timed out.
  • callback {Function} Optional function to be called when a timeout occurs. Same as binding to the timeout event.

request.write(chunk[, encoding][, callback])#

Sends a chunk of the body. By calling this method many times, the user can stream a request body to a server--in that case it is suggested to use the ['Transfer-Encoding', 'chunked'] header line when creating the request.

The chunk argument should be a Buffer or a string.

The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.

The callback argument is optional and will be called when this chunk of data is flushed.

Returns request.

Class: http.Server#

This is an EventEmitter with the following events:

Event: 'checkContinue'#

function (request, response) { }

Emitted each time a request with an http Expect: 100-continue is received. If this event isn't listened for, the server will automatically respond with a 100 Continue as appropriate.

Handling this event involves calling response.writeContinue() if the client should continue to send the request body, or generating an appropriate HTTP response (e.g., 400 Bad Request) if the client should not continue to send the request body.

Note that when this event is emitted and handled, the 'request' event will not be emitted.

Event: 'clientError'#

function (exception, socket) { }

If a client connection emits an 'error' event, it will be forwarded here.

socket is the net.Socket object that the error originated from.

Event: 'close'#

function () { }

Emitted when the server closes.

Event: 'connect'#

function (request, socket, head) { }

Emitted each time a client requests a http CONNECT method. If this event isn't listened for, then clients requesting a CONNECT method will have their connections closed.

  • request is the arguments for the http request, as it is in the request event.
  • socket is the network socket between the server and client.
  • head is an instance of Buffer, the first packet of the tunneling stream, this may be empty.

After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket.

Event: 'connection'#

function (socket) { }

When a new TCP stream is established. socket is an object of type net.Socket. Usually users will not want to access this event. In particular, the socket will not emit 'readable' events because of how the protocol parser attaches to the socket. The socket can also be accessed at request.connection.

Event: 'request'#

function (request, response) { }

Emitted each time there is a request. Note that there may be multiple requests per connection (in the case of keep-alive connections). request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse.

Event: 'upgrade'#

function (request, socket, head) { }

Emitted each time a client requests a http upgrade. If this event isn't listened for, then clients requesting an upgrade will have their connections closed.

  • request is the arguments for the http request, as it is in the request event.
  • socket is the network socket between the server and client.
  • head is an instance of Buffer, the first packet of the upgraded stream, this may be empty.

After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket.

server.close([callback])#

Stops the server from accepting new connections. See net.Server.close().

server.listen(handle[, callback])#

  • handle Object
  • callback Function

The handle object can be set to either a server or socket (anything with an underlying _handle member), or a {fd: <n>} object.

This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket.

Listening on a file descriptor is not supported on Windows.

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen().

Returns server.

server.listen(path[, callback])#

Start a UNIX socket server listening for connections on the given path.

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen(path).

server.listen(port[, hostname][, backlog][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

To listen to a unix socket, supply a filename instead of port and hostname.

Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. The default value of this parameter is 511 (not 512).

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen(port).

server.maxHeadersCount#

Limits maximum incoming headers count, equal to 1000 by default. If set to 0 - no limit will be applied.

server.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Sets the timeout value for sockets, and emits a 'timeout' event on the Server object, passing the socket as an argument, if a timeout occurs.

If there is a 'timeout' event listener on the Server object, then it will be called with the timed-out socket as an argument.

By default, the Server's timeout value is 2 minutes, and sockets are destroyed automatically if they time out. However, if you assign a callback to the Server's 'timeout' event, then you are responsible for handling socket timeouts.

Returns server.

server.timeout#

  • Number Default = 120000 (2 minutes)

The number of milliseconds of inactivity before a socket is presumed to have timed out.

Note that the socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections.

Set to 0 to disable any kind of automatic timeout behavior on incoming connections.

Class: http.ServerResponse#

This object is created internally by a HTTP server--not by the user. It is passed as the second parameter to the 'request' event.

The response implements the Writable Stream interface. This is an EventEmitter with the following events:

Event: 'close'#

function () { }

Indicates that the underlying connection was terminated before response.end() was called or able to flush.

Event: 'finish'#

function () { }

Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet.

After this event, no more events will be emitted on the response object.

response.addTrailers(headers)#

This method adds HTTP trailing headers (a header but at the end of the message) to the response.

Trailers will only be emitted if chunked encoding is used for the response; if it is not (e.g., if the request was HTTP/1.0), they will be silently discarded.

Note that HTTP requires the Trailer header to be sent if you intend to emit trailers, with a list of the header fields in its value. E.g.,

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end();

Attempting to set a trailer field name that contains invalid characters will result in a TypeError being thrown.

response.end([data][, encoding][, callback])#

This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, response.end(), MUST be called on each response.

If data is specified, it is equivalent to calling response.write(data, encoding) followed by response.end(callback).

If callback is specified, it will be called when the response stream is finished.

response.finished#

Boolean value that indicates whether the response has completed. Starts as false. After response.end() executes, the value will be true.

response.getHeader(name)#

Reads out a header that's already been queued but not sent to the client. Note that the name is case insensitive. This can only be called before headers get implicitly flushed.

Example:

var contentType = response.getHeader('content-type');

response.headersSent#

Boolean (read-only). True if headers were sent, false otherwise.

response.removeHeader(name)#

Removes a header that's queued for implicit sending.

Example:

response.removeHeader('Content-Encoding');

response.sendDate#

When true, the Date header will be automatically generated and sent in the response if it is not already present in the headers. Defaults to true.

This should only be disabled for testing; HTTP requires the Date header in responses.

response.setHeader(name, value)#

Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here if you need to send multiple headers with the same name.

Example:

response.setHeader('Content-Type', 'text/html');

or

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

Attempting to set a header field name that contains invalid characters will result in a TypeError being thrown.

response.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Sets the Socket's timeout value to msecs. If a callback is provided, then it is added as a listener on the 'timeout' event on the response object.

If no 'timeout' listener is added to the request, the response, or the server, then sockets are destroyed when they time out. If you assign a handler on the request, the response, or the server's 'timeout' events, then it is your responsibility to handle timed out sockets.

Returns response.

response.statusCode#

When using implicit headers (not calling response.writeHead() explicitly), this property controls the status code that will be sent to the client when the headers get flushed.

Example:

response.statusCode = 404;

After response header was sent to the client, this property indicates the status code which was sent out.

response.statusMessage#

When using implicit headers (not calling response.writeHead() explicitly), this property controls the status message that will be sent to the client when the headers get flushed. If this is left as undefined then the standard message for the status code will be used.

Example:

response.statusMessage = 'Not found';

After response header was sent to the client, this property indicates the status message which was sent out.

response.write(chunk[, encoding][, callback])#

If this method is called and response.writeHead() has not been called, it will switch to implicit header mode and flush the implicit headers.

This sends a chunk of the response body. This method may be called multiple times to provide successive parts of the body.

chunk can be a string or a buffer. If chunk is a string, the second parameter specifies how to encode it into a byte stream. By default the encoding is 'utf8'. The last parameter callback will be called when this chunk of data is flushed.

Note: This is the raw HTTP body and has nothing to do with higher-level multi-part body encodings that may be used.

The first time response.write() is called, it will send the buffered header information and the first body to the client. The second time response.write() is called, Node.js assumes you're going to be streaming data, and sends that separately. That is, the response is buffered up to the first chunk of body.

Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is free again.

response.writeContinue()#

Sends a HTTP/1.1 100 Continue message to the client, indicating that the request body should be sent. See the 'checkContinue' event on Server.

response.writeHead(statusCode[, statusMessage][, headers])#

Sends a response header to the request. The status code is a 3-digit HTTP status code, like 404. The last argument, headers, are the response headers. Optionally one can give a human-readable statusMessage as the second argument.

Example:

var body = 'hello world';
response.writeHead(200, {
  'Content-Length': body.length,
  'Content-Type': 'text/plain' });

This method must only be called once on a message and it must be called before response.end() is called.

If you call response.write() or response.end() before calling this, the implicit/mutable headers will be calculated and call this function for you.

Note that Content-Length is given in bytes not characters. The above example works because the string 'hello world' contains only single byte characters. If the body contains higher coded characters then Buffer.byteLength() should be used to determine the number of bytes in a given encoding. And Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not.

Class: http.IncomingMessage#

An IncomingMessage object is created by http.Server or http.ClientRequest and passed as the first argument to the 'request' and 'response' event respectively. It may be used to access response status, headers and data.

It implements the Readable Stream interface, as well as the following additional events, methods, and properties.

Event: 'close'#

function () { }

Indicates that the underlying connection was closed. Just like 'end', this event occurs only once per response.

message.headers#

The request/response headers object.

Key-value pairs of header names and values. Header names are lower-cased. Example:

// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers);

Duplicates in raw headers are handled in the following ways, depending on the header name:

  • Duplicates of age, authorization, content-length, content-type, etag, expires, from, host, if-modified-since, if-unmodified-since, last-modified, location, max-forwards, proxy-authorization, referer, retry-after, or user-agent are discarded.
  • set-cookie is always an array. Duplicates are added to the array.
  • For all other headers, the values are joined together with ', '.

message.httpVersion#

In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. Probably either '1.1' or '1.0'.

Also response.httpVersionMajor is the first integer and response.httpVersionMinor is the second.

message.method#

Only valid for request obtained from http.Server.

The request method as a string. Read only. Example: 'GET', 'DELETE'.

message.rawHeaders#

The raw request/response headers list exactly as they were received.

Note that the keys and values are in the same list. It is not a list of tuples. So, the even-numbered offsets are key values, and the odd-numbered offsets are the associated values.

Header names are not lowercased, and duplicates are not merged.

// Prints something like:
//
// [ 'user-agent',
//   'this is invalid because there can be only one',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);

message.rawTrailers#

The raw request/response trailer keys and values exactly as they were received. Only populated at the 'end' event.

message.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Calls message.connection.setTimeout(msecs, callback).

Returns message.

message.statusCode#

Only valid for response obtained from http.ClientRequest.

The 3-digit HTTP response status code. E.G. 404.

message.statusMessage#

Only valid for response obtained from http.ClientRequest.

message.socket#

The net.Socket object associated with the connection.

With HTTPS support, use request.socket.getPeerCertificate() to obtain the client's authentication details.

The HTTP response status message (reason phrase). E.G. OK or Internal Server Error.

message.trailers#

The request/response trailers object. Only populated at the 'end' event.

message.url#

Only valid for request obtained from http.Server.

Request URL string. This contains only the URL that is present in the actual HTTP request. If the request is:

GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n

Then request.url will be:

'/status?name=ryan'

If you would like to parse the URL into its parts, you can use require('url').parse(request.url). Example:

node> require('url').parse('/status?name=ryan')
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status' }

If you would like to extract the params from the query string, you can use the require('querystring').parse function, or pass true as the second argument to require('url').parse. Example:

node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: { name: 'ryan' },
  pathname: '/status' }

http.METHODS#

  • Array

A list of the HTTP methods that are supported by the parser.

http.STATUS_CODES#

  • Object

A collection of all the standard HTTP response status codes, and the short description of each. For example, http.STATUS_CODES[404] === 'Not Found'.

http.createClient([port][, host])#

Stability: 0 - Deprecated: Use http.request() instead.

Constructs a new HTTP client. port and host refer to the server to be connected to.

http.createServer([requestListener])#

Returns a new instance of http.Server.

The requestListener is a function which is automatically added to the 'request' event.

http.get(options[, callback])#

Since most requests are GET requests without bodies, Node.js provides this convenience method. The only difference between this method and http.request() is that it sets the method to GET and calls req.end() automatically.

Example:

http.get('http://www.google.com/index.html', (res) => {
  console.log(`Got response: ${res.statusCode}`);
  // consume response body
  res.resume();
}).on('error', (e) => {
  console.log(`Got error: ${e.message}`);
});

http.globalAgent#

Global instance of Agent which is used as the default for all http client requests.

http.request(options[, callback])#

Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

Options:

  • protocol: Protocol to use. Defaults to 'http:'.
  • host: A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
  • hostname: Alias for host. To support url.parse() hostname is preferred over host.
  • family: IP address family to use when resolving host and hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.
  • port: Port of remote server. Defaults to 80.
  • localAddress: Local interface to bind for network connections.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • path: Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
  • headers: An object containing request headers.
  • auth: Basic authentication i.e. 'user:password' to compute an Authorization header.
  • agent: Controls Agent behavior. When an Agent is used request will default to Connection: keep-alive. Possible values:
    • undefined (default): use http.globalAgent for this host and port.
    • Agent object: explicitly use the passed in Agent.
    • false: opts out of connection pooling with an Agent, defaults request to Connection: close.

The optional callback parameter will be added as a one time listener for the 'response' event.

http.request() returns an instance of the http.ClientRequest class. The ClientRequest instance is a writable stream. If one needs to upload a file with a POST request, then write to the ClientRequest object.

Example:

var postData = querystring.stringify({
  'msg' : 'Hello World!'
});

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': postData.length
  }
};

var req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.')
  })
});

req.on('error', (e) => {
  console.log(`problem with request: ${e.message}`);
});

// write data to request body
req.write(postData);
req.end();

Note that in the example req.end() was called. With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.

If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an 'error' event is emitted on the returned request object. As with all 'error' events, if no listeners are registered the error will be thrown.

There are a few special headers that should be noted.

  • Sending a 'Connection: keep-alive' will notify Node.js that the connection to the server should be persisted until the next request.

  • Sending a 'Content-length' header will disable the default chunked encoding.

  • Sending an 'Expect' header will immediately send the request headers. Usually, when sending 'Expect: 100-continue', you should both set a timeout and listen for the 'continue' event. See RFC2616 Section 8.2.3 for more information.

  • Sending an Authorization header will override using the auth option to compute basic authentication.

HTTPS#

Stability: 2 - Stable

HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module.

Class: https.Agent#

An Agent object for HTTPS similar to http.Agent. See https.request() for more information.

Class: https.Server#

This class is a subclass of tls.Server and emits events same as http.Server. See http.Server for more information.

server.setTimeout(msecs, callback)#

See http.Server#setTimeout().

server.timeout#

See http.Server#timeout.

https.createServer(options[, requestListener])#

Returns a new HTTPS web server object. The options is similar to tls.createServer(). The requestListener is a function which is automatically added to the 'request' event.

Example:

// curl -k https://localhost:8000/
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

Or

const https = require('https');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('server.pfx')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

server.close([callback])#

See http.close() for details.

server.listen(handle[, callback])#

server.listen(path[, callback])#

server.listen(port[, host][, backlog][, callback])#

See http.listen() for details.

https.get(options, callback)#

Like http.get() but for HTTPS.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

Example:

const https = require('https');

https.get('https://encrypted.google.com/', (res) => {
  console.log('statusCode: ', res.statusCode);
  console.log('headers: ', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });

}).on('error', (e) => {
  console.error(e);
});

https.globalAgent#

Global instance of https.Agent for all HTTPS client requests.

https.request(options, callback)#

Makes a request to a secure web server.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

All options from http.request() are valid.

Example:

const https = require('https');

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET'
};

var req = https.request(options, (res) => {
  console.log('statusCode: ', res.statusCode);
  console.log('headers: ', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });
});
req.end();

req.on('error', (e) => {
  console.error(e);
});

The options argument has the following options

  • host: A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
  • hostname: Alias for host. To support url.parse() hostname is preferred over host.
  • family: IP address family to use when resolving host and hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.
  • port: Port of remote server. Defaults to 443.
  • localAddress: Local interface to bind for network connections.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • path: Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
  • headers: An object containing request headers.
  • auth: Basic authentication i.e. 'user:password' to compute an Authorization header.
  • agent: Controls Agent behavior. When an Agent is used request will default to Connection: keep-alive. Possible values:
    • undefined (default): use globalAgent for this host and port.
    • Agent object: explicitly use the passed in Agent.
    • false: opts out of connection pooling with an Agent, defaults request to Connection: close.

The following options from tls.connect() can also be specified. However, a globalAgent silently ignores these.

  • pfx: Certificate, Private key and CA certificates to use for SSL. Default null.
  • key: Private key to use for SSL. Default null.
  • passphrase: A string of passphrase for the private key or pfx. Default null.
  • cert: Public x509 certificate to use. Default null.
  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.
  • rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Default true.
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

In order to specify these options, use a custom Agent.

Example:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
options.agent = new https.Agent(options);

var req = https.request(options, (res) => {
  ...
}

Alternatively, opt out of connection pooling by not using an Agent.

Example:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
  agent: false
};

var req = https.request(options, (res) => {
  ...
}

Modules#

Stability: 3 - Locked

Node.js has a simple module loading system. In Node.js, files and modules are in one-to-one correspondence. As an example, foo.js loads the module circle.js in the same directory.

The contents of foo.js:

const circle = require('./circle.js');
console.log( `The area of a circle of radius 4 is ${circle.area(4)}`);

The contents of circle.js:

const PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

The module circle.js has exported the functions area() and circumference(). To add functions and objects to the root of your module, you can add them to the special exports object.

Variables local to the module will be private, as though the module was wrapped in a function. In this example the variable PI is private to circle.js.

If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.

Below, bar.js makes use of the square module, which exports a constructor:

const square = require('./square.js');
var mySquare = square(2);
console.log(`The area of my square is ${mySquare.area()}`);

The square module is defined in square.js:

// assigning to exports will not modify module, must use module.exports
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

The module system is implemented in the require("module") module.

Accessing the main module#

When a file is run directly from Node.js, require.main is set to its module. That means that you can determine whether a file has been run directly by testing

require.main === module

For a file foo.js, this will be true if run via node foo.js, but false if run by require('./foo').

Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename.

Addenda: Package Manager Tips#

The semantics of Node.js's require() function were designed to be general enough to support a number of reasonable directory structures. Package manager programs such as dpkg, rpm, and npm will hopefully find it possible to build native packages from Node.js modules without modification.

Below we give a suggested directory structure that could work:

Let's say that we wanted to have the folder at /usr/lib/node/<some-package>/<some-version> hold the contents of a specific version of a package.

Packages can depend on one another. In order to install package foo, you may have to install a specific version of package bar. The bar package may itself have dependencies, and in some cases, these dependencies may even collide or form cycles.

Since Node.js looks up the realpath of any modules it loads (that is, resolves symlinks), and then looks for their dependencies in the node_modules folders as described above, this situation is very simple to resolve with the following architecture:

  • /usr/lib/node/foo/1.2.3/ - Contents of the foo package, version 1.2.3.
  • /usr/lib/node/bar/4.3.2/ - Contents of the bar package that foo depends on.
  • /usr/lib/node/foo/1.2.3/node_modules/bar - Symbolic link to /usr/lib/node/bar/4.3.2/.
  • /usr/lib/node/bar/4.3.2/node_modules/* - Symbolic links to the packages that bar depends on.

Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.

When the code in the foo package does require('bar'), it will get the version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar. Then, when the code in the bar package calls require('quux'), it'll get the version that is symlinked into /usr/lib/node/bar/4.3.2/node_modules/quux.

Furthermore, to make the module lookup process even more optimal, rather than putting packages directly in /usr/lib/node, we could put them in /usr/lib/node_modules/<name>/<version>. Then Node.js will not bother looking for missing dependencies in /usr/node_modules or /node_modules.

In order to make modules available to the Node.js REPL, it might be useful to also add the /usr/lib/node_modules folder to the $NODE_PATH environment variable. Since the module lookups using node_modules folders are all relative, and based on the real path of the files making the calls to require(), the packages themselves can be anywhere.

All Together...#

To get the exact filename that will be loaded when require() is called, use the require.resolve() function.

Putting together all of the above, here is the high-level algorithm in pseudocode of what require.resolve does:

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.json is a file, parse X.json to a JavaScript Object.  STOP
4. If X.node is a file, load X.node as binary addon.  STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. let M = X + (json main field)
   c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon.  STOP

LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_AS_FILE(DIR/X)
   b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   c. DIR = path join(PARTS[0 .. I] + "node_modules")
   b. DIRS = DIRS + DIR
   c. let I = I - 1
5. return DIRS

Caching#

Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.

Multiple calls to require('foo') may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

If you want to have a module execute code multiple times, then export a function, and call that function.

Module Caching Caveats#

Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files.

Core Modules#

Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation.

The core modules are defined within Node.js's source and are located in the lib/ folder.

Core modules are always preferentially loaded if their identifier is passed to require(). For instance, require('http') will always return the built in HTTP module, even if there is a file by that name.

Cycles#

When there are circular require() calls, a module might not have finished executing when it is returned.

Consider this situation:

a.js:

console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');

b.js:

console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');

main.js:

console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.

By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:

$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true

If you have cyclic module dependencies in your program, make sure to plan accordingly.

File Modules#

If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js, .json, and finally .node.

.js files are interpreted as JavaScript text files, and .json files are parsed as JSON text files. .node files are interpreted as compiled addon modules loaded with dlopen.

A required module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js.

A required module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it.

Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder.

If the given path does not exist, require() will throw an Error with its code property set to 'MODULE_NOT_FOUND'.

Folders as Modules#

It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to require() as an argument.

The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:

{ "name" : "some-library",
  "main" : "./lib/some-library.js" }

If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.

This is the extent of Node.js's awareness of package.json files.

If there is no package.json file present in the directory, then Node.js will attempt to load an index.js or index.node file out of that directory. For example, if there was no package.json file in the above example, then require('./some-library') would attempt to load:

  • ./some-library/index.js
  • ./some-library/index.node

Loading from node_modules Folders#

If the module identifier passed to require() is not a native module, and does not begin with '/', '../', or './', then Node.js starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node will not append node_modules to a path already ending in node_modules.

If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached.

For example, if the file at '/home/ry/projects/foo.js' called require('bar.js'), then Node.js would look in the following locations, in this order:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

This allows programs to localize their dependencies, so that they do not clash.

You can require specific files or sub modules distributed with a module by including a path suffix after the module name. For instance require('example-module/path/to/file') would resolve path/to/file relative to where example-module is located. The suffixed path follows the same module resolution semantics.

Loading from the global folders#

If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)

NODE_PATH was originally created to support loading modules from varying paths before the current module resolution algorithm was frozen.

NODE_PATH is still supported, but is less necessary now that the Node.js ecosystem has settled on a convention for locating dependent modules. Sometimes deployments that rely on NODE_PATH show surprising behavior when people are unaware that NODE_PATH must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the NODE_PATH is searched.

Additionally, Node.js will search in the following locations:

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/lib/node

Where $HOME is the user's home directory, and $PREFIX is Node.js's configured node_prefix.

These are mostly for historic reasons. You are highly encouraged to place your dependencies locally in node_modules folders. They will be loaded faster, and more reliably.

The module Object#

  • {Object}

In each module, the module free variable is a reference to the object representing the current module. For convenience, module.exports is also accessible via the exports module-global. module isn't actually a global but rather local to each module.

module.children#

  • Array

The module objects required by this one.

module.exports#

  • Object

The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what you want to do.

For example suppose we were making a module called a.js

const EventEmitter = require('events');

module.exports = new EventEmitter();

// Do some work, and after some time emit
// the 'ready' event from the module itself.
setTimeout(() => {
  module.exports.emit('ready');
}, 1000);

Then in another file we could do

const a = require('./a');
a.on('ready', () => {
  console.log('module a is ready');
});

Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work:

x.js:

setTimeout(() => {
  module.exports = { a: 'hello' };
}, 0);

y.js:

const x = require('./x');
console.log(x.a);

exports alias#

The exports variable that is available within a module starts as a reference to module.exports. As with any variable, if you assign a new value to it, it is no longer bound to the previous value.

To illustrate the behavior, imagine this hypothetical implementation of require():

function require(...) {
  // ...
  function (module, exports) {
    // Your module code here
    exports = some_func;        // re-assigns exports, exports is no longer
                                // a shortcut, and nothing is exported.
    module.exports = some_func; // makes your module export 0
  } (module, module.exports);
  return module;
}

As a guideline, if the relationship between exports and module.exports seems like magic to you, ignore exports and only use module.exports.

module.filename#

  • String

The fully resolved filename to the module.

module.id#

  • String

The identifier for the module. Typically this is the fully resolved filename.

module.loaded#

  • Boolean

Whether or not the module is done loading, or is in the process of loading.

module.parent#

  • Module Object

The module that first required this one.

module.require(id)#

  • id String
  • Return: Object module.exports from the resolved module

The module.require method provides a way to load a module as if require() was called from the original module.

Note that in order to do this, you must get a reference to the module object. Since require() returns the module.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.

net#

Stability: 2 - Stable

The net module provides you with an asynchronous network wrapper. It contains functions for creating both servers and clients (called streams). You can include this module with require('net');.

Class: net.Server#

This class is used to create a TCP or local server.

net.Server is an EventEmitter with the following events:

Event: 'close'#

Emitted when the server closes. Note that if connections exist, this event is not emitted until all connections are ended.

Event: 'connection'#

  • Socket object The connection object

Emitted when a new connection is made. socket is an instance of net.Socket.

Event: 'error'#

  • Error Object

Emitted when an error occurs. The 'close' event will be called directly following this event. See example in discussion of server.listen.

Event: 'listening'#

Emitted when the server has been bound after calling server.listen.

server.address()#

Returns the bound address, the address family name and port of the server as reported by the operating system. Useful to find which port was assigned when giving getting an OS-assigned address. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

Example:

var server = net.createServer((socket) => {
  socket.end('goodbye\n');
});

// grab a random port.
server.listen(() => {
  address = server.address();
  console.log('opened server on %j', address);
});

Don't call server.address() until the 'listening' event has been emitted.

server.close([callback])#

Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed.

server.connections#

Stability: 0 - Deprecated: Use server.getConnections instead.

The number of concurrent connections on the server.

This becomes null when sending a socket to a child with child_process.fork(). To poll forks and get current number of active connections use asynchronous server.getConnections instead.

server.getConnections(callback)#

Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks.

Callback should take two arguments err and count.

server.listen(handle[, backlog][, callback])#

  • handle Object
  • backlog Number
  • callback Function

The handle object can be set to either a server or socket (anything with an underlying _handle member), or a {fd: <n>} object.

This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket.

Listening on a file descriptor is not supported on Windows.

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

The parameter backlog behaves the same as in [server.listen(port, \[host\], \[backlog\], \[callback\])][].

server.listen(options[, callback])#

  • options Object - Required. Supports the following properties:
    • port Number - Optional.
    • host String - Optional.
    • backlog Number - Optional.
    • path String - Optional.
    • exclusive Boolean - Optional.
  • callback Function - Optional.

The port, host, and backlog properties of options, as well as the optional callback function, behave as they do on a call to [server.listen(port, \[host\], \[backlog\], \[callback\])][]. Alternatively, the path option can be used to specify a UNIX socket.

If exclusive is false (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When exclusive is true, the handle is not shared, and attempted port sharing results in an error. An example which listens on an exclusive port is shown below.

server.listen({
  host: 'localhost',
  port: 80,
  exclusive: true
});

server.listen(path[, backlog][, callback])#

  • path String
  • backlog Number
  • callback Function

Start a local socket server listening for connections on the given path.

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

On UNIX, the local domain is usually known as the UNIX domain. The path is a filesystem path name. It is subject to the same naming conventions and permissions checks as would be done on file creation, will be visible in the filesystem, and will persist until unlinked.

On Windows, the local domain is implemented using a named pipe. The path must refer to an entry in \\?\pipe\ or \\.\pipe\. Any characters are permitted, but the latter may do some processing of pipe names, such as resolving .. sequences. Despite appearances, the pipe name space is flat. Pipes will not persist, they are removed when the last reference to them is closed. Do not forget JavaScript string escaping requires paths to be specified with double-backslashes, such as:

net.createServer().listen(
    path.join('\\\\?\\pipe', process.cwd(), 'myctl'))

The parameter backlog behaves the same as in [server.listen(port, \[host\], \[backlog\], \[callback\])][].

server.listen(port[, hostname][, backlog][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. The default value of this parameter is 511 (not 512).

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

One issue some users run into is getting EADDRINUSE errors. This means that another server is already running on the requested port. One way of handling this would be to wait a second and then try again. This can be done with

server.on('error', (e) => {
  if (e.code == 'EADDRINUSE') {
    console.log('Address in use, retrying...');
    setTimeout(() => {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});

(Note: All sockets in Node.js set SO_REUSEADDR already)

server.maxConnections#

Set this property to reject connections when the server's connection count gets high.

It is not recommended to use this option once a socket has been sent to a child with child_process.fork().

server.ref()#

Opposite of unref, calling ref on a previously unrefd server will not let the program exit if it's the only server left (the default behavior). If the server is refd calling ref again will have no effect.

Returns server.

server.unref()#

Calling unref on a server will allow the program to exit if this is the only active server in the event system. If the server is already unrefd calling unref again will have no effect.

Returns server.

Class: net.Socket#

This object is an abstraction of a TCP or local socket. net.Socket instances implement a duplex Stream interface. They can be created by the user and used as a client (with connect()) or they can be created by Node.js and passed to the user through the 'connection' event of a server.

new net.Socket(options)#

Construct a new socket object.

options is an object with the following defaults:

{ fd: null,
  allowHalfOpen: false,
  readable: false,
  writable: false
}

fd allows you to specify the existing file descriptor of socket. Set readable and/or writable to true to allow reads and/or writes on this socket (NOTE: Works only when fd is passed). About allowHalfOpen, refer to createServer() and 'end' event.

net.Socket instances are EventEmitter with the following events:

Event: 'close'#

  • had_error Boolean true if the socket had a transmission error.

Emitted once the socket is fully closed. The argument had_error is a boolean which says if the socket was closed due to a transmission error.

Event: 'connect'#

Emitted when a socket connection is successfully established. See connect().

Event: 'data'#

  • Buffer object

Emitted when data is received. The argument data will be a Buffer or String. Encoding of data is set by socket.setEncoding(). (See the Readable Stream section for more information.)

Note that the data will be lost if there is no listener when a Socket emits a 'data' event.

Event: 'drain'#

Emitted when the write buffer becomes empty. Can be used to throttle uploads.

See also: the return values of socket.write()

Event: 'end'#

Emitted when the other end of the socket sends a FIN packet.

By default (allowHalfOpen == false) the socket will destroy its file descriptor once it has written out its pending write queue. However, by setting allowHalfOpen == true the socket will not automatically end() its side allowing the user to write arbitrary amounts of data, with the caveat that the user is required to end() their side now.

Event: 'error'#

  • Error object

Emitted when an error occurs. The 'close' event will be called directly following this event.

Event: 'lookup'#

Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets.

  • err {Error | Null} The error object. See dns.lookup().
  • address {String} The IP address.
  • family {String | Null} The address type. See dns.lookup().

Event: 'timeout'#

Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user must manually close the connection.

See also: socket.setTimeout()

socket.address()#

Returns the bound address, the address family name and port of the socket as reported by the operating system. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

socket.bufferSize#

net.Socket has the property that socket.write() always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket - the network connection simply might be too slow. Node.js will internally queue up the data written to a socket and send it out over the wire when it is possible. (Internally it is polling on the socket's file descriptor for being writable).

The consequence of this internal buffering is that memory may grow. This property shows the number of characters currently buffered to be written. (Number of characters is approximately equal to the number of bytes to be written, but the buffer may contain strings, and the strings are lazily encoded, so the exact number of bytes is not known.)

Users who experience large or growing bufferSize should attempt to "throttle" the data flows in their program with pause() and resume().

socket.bytesRead#

The amount of received bytes.

socket.bytesWritten#

The amount of bytes sent.

socket.connect(options[, connectListener])#

Opens the connection for a given socket.

For TCP sockets, options argument should be an object which specifies:

  • port: Port the client should connect to (Required).

  • host: Host the client should connect to. Defaults to 'localhost'.

  • localAddress: Local interface to bind to for network connections.

  • localPort: Local port to bind to for network connections.

  • family : Version of IP stack. Defaults to 4.

  • lookup : Custom lookup function. Defaults to dns.lookup.

For local domain sockets, options argument should be an object which specifies:

  • path: Path the client should connect to (Required).

Normally this method is not needed, as net.createConnection opens the socket. Use this only if you are implementing a custom Socket.

This function is asynchronous. When the 'connect' event is emitted the socket is established. If there is a problem connecting, the 'connect' event will not be emitted, the 'error' event will be emitted with the exception.

The connectListener parameter will be added as a listener for the 'connect' event.

socket.connect(path[, connectListener])#

socket.connect(port[, host][, connectListener])#

As [socket.connect(options\[, connectListener\])][], with options either as either {port: port, host: host} or {path: path}.

socket.destroy()#

Ensures that no more I/O activity happens on this socket. Only necessary in case of errors (parse error or so).

socket.end([data][, encoding])#

Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data.

If data is specified, it is equivalent to calling socket.write(data, encoding) followed by socket.end().

socket.localAddress#

The string representation of the local IP address the remote client is connecting on. For example, if you are listening on '0.0.0.0' and the client connects on '192.168.1.1', the value would be '192.168.1.1'.

socket.localPort#

The numeric representation of the local port. For example, 80 or 21.

socket.pause()#

Pauses the reading of data. That is, 'data' events will not be emitted. Useful to throttle back an upload.

socket.ref()#

Opposite of unref, calling ref on a previously unrefd socket will not let the program exit if it's the only socket left (the default behavior). If the socket is refd calling ref again will have no effect.

Returns socket.

socket.remoteAddress#

The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'. Value may be undefined if the socket is destroyed (for example, if the client disconnected).

socket.remoteFamily#

The string representation of the remote IP family. 'IPv4' or 'IPv6'.

socket.remotePort#

The numeric representation of the remote port. For example, 80 or 21.

socket.resume()#

Resumes reading after a call to pause().

socket.setEncoding([encoding])#

Set the encoding for the socket as a Readable Stream. See stream.setEncoding() for more information.

socket.setKeepAlive([enable][, initialDelay])#

Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket. enable defaults to false.

Set initialDelay (in milliseconds) to set the delay between the last data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting. Defaults to 0.

Returns socket.

socket.setNoDelay([noDelay])#

Disables the Nagle algorithm. By default TCP connections use the Nagle algorithm, they buffer data before sending it off. Setting true for noDelay will immediately fire off data each time socket.write() is called. noDelay defaults to true.

Returns socket.

socket.setTimeout(timeout[, callback])#

Sets the socket to timeout after timeout milliseconds of inactivity on the socket. By default net.Socket do not have a timeout.

When an idle timeout is triggered the socket will receive a 'timeout' event but the connection will not be severed. The user must manually end() or destroy() the socket.

If timeout is 0, then the existing idle timeout is disabled.

The optional callback parameter will be added as a one time listener for the 'timeout' event.

Returns socket.

socket.unref()#

Calling unref on a socket will allow the program to exit if this is the only active socket in the event system. If the socket is already unrefd calling unref again will have no effect.

Returns socket.

socket.write(data[, encoding][, callback])#

Sends data on the socket. The second parameter specifies the encoding in the case of a string--it defaults to UTF8 encoding.

Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is again free.

The optional callback parameter will be executed when the data is finally written out - this may not be immediately.

net.connect(options[, connectListener])#

A factory function, which returns a new net.Socket and automatically connects with the supplied options.

The options are passed to both the net.Socket constructor and the socket.connect method.

The connectListener parameter will be added as a listener for the 'connect' event once.

Here is an example of a client of the previously described echo server:

const net = require('net');
const client = net.connect({port: 8124}, () => { //'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});

To connect on the socket /tmp/echo.sock the second line would just be changed to

const client = net.connect({path: '/tmp/echo.sock'});

net.connect(path[, connectListener])#

A factory function, which returns a new unix net.Socket and automatically connects to the supplied path.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.connect(port[, host][, connectListener])#

A factory function, which returns a new net.Socket and automatically connects to the supplied port and host.

If host is omitted, 'localhost' will be assumed.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createConnection(options[, connectListener])#

A factory function, which returns a new net.Socket and automatically connects with the supplied options.

The options are passed to both the net.Socket constructor and the socket.connect method.

The connectListener parameter will be added as a listener for the 'connect' event once.

Here is an example of a client of the previously described echo server:

const net = require('net');
const client = net.connect({port: 8124},
    () => { //'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});

To connect on the socket /tmp/echo.sock the second line would just be changed to

const client = net.connect({path: '/tmp/echo.sock'});

net.createConnection(path[, connectListener])#

A factory function, which returns a new unix net.Socket and automatically connects to the supplied path.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createConnection(port[, host][, connectListener])#

A factory function, which returns a new net.Socket and automatically connects to the supplied port and host.

If host is omitted, 'localhost' will be assumed.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createServer([options][, connectionListener])#

Creates a new server. The connectionListener argument is automatically set as a listener for the 'connection' event.

options is an object with the following defaults:

{
  allowHalfOpen: false,
  pauseOnConnect: false
}

If allowHalfOpen is true, then the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. The socket becomes non-readable, but still writable. You should call the end() method explicitly. See 'end' event for more information.

If pauseOnConnect is true, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. This allows connections to be passed between processes without any data being read by the original process. To begin reading data from a paused socket, call resume().

Here is an example of an echo server which listens for connections on port 8124:

const net = require('net');
const server = net.createServer((c) => { //'connection' listener
  console.log('client connected');
  c.on('end', () => {
    console.log('client disconnected');
  });
  c.write('hello\r\n');
  c.pipe(c);
});
server.listen(8124, () => { //'listening' listener
  console.log('server bound');
});

Test this by using telnet:

telnet localhost 8124

To listen on the socket /tmp/echo.sock the third line from the last would just be changed to

server.listen('/tmp/echo.sock', () => { //'listening' listener

Use nc to connect to a UNIX domain socket server:

nc -U /tmp/echo.sock

net.isIP(input)#

Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.

net.isIPv4(input)#

Returns true if input is a version 4 IP address, otherwise returns false.

net.isIPv6(input)#

Returns true if input is a version 6 IP address, otherwise returns false.

[server.listen(port, \[host\], \[backlog\], \[callback\])]: #net_server_listen_port_hostname_backlog_callback [socket.connect(options\[, connectListener\])]: #net_socket_connect_options_connectlistener

OS#

Stability: 2 - Stable

Provides a few basic operating-system related utility functions.

Use require('os') to access this module.

os.EOL#

A constant defining the appropriate End-of-line marker for the operating system.

os.arch()#

Returns the operating system CPU architecture. Possible values are 'x64', 'arm' and 'ia32'. Returns the value of process.arch.

os.cpus()#

Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of milliseconds the CPU/core spent in: user, nice, sys, idle, and irq).

Example inspection of os.cpus:

[ { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 252020,
       nice: 0,
       sys: 30340,
       idle: 1070356870,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 306960,
       nice: 0,
       sys: 26980,
       idle: 1071569080,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 248450,
       nice: 0,
       sys: 21750,
       idle: 1070919370,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 256880,
       nice: 0,
       sys: 19430,
       idle: 1070905480,
       irq: 20 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 511580,
       nice: 20,
       sys: 40900,
       idle: 1070842510,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 291660,
       nice: 0,
       sys: 34360,
       idle: 1070888000,
       irq: 10 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 308260,
       nice: 0,
       sys: 55410,
       idle: 1071129970,
       irq: 880 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 266450,
       nice: 1480,
       sys: 34920,
       idle: 1072572010,
       irq: 30 } } ]

Note that since nice values are UNIX centric in Windows the nice values of all processors are always 0.

os.endianness()#

Returns the endianness of the CPU. Possible values are 'BE' for big endian or 'LE' for little endian.

os.freemem()#

Returns the amount of free system memory in bytes.

os.homedir()#

Returns the home directory of the current user.

os.hostname()#

Returns the hostname of the operating system.

os.loadavg()#

Returns an array containing the 1, 5, and 15 minute load averages.

The load average is a measure of system activity, calculated by the operating system and expressed as a fractional number. As a rule of thumb, the load average should ideally be less than the number of logical CPUs in the system.

The load average is a very UNIX-y concept; there is no real equivalent on Windows platforms. That is why this function always returns [0, 0, 0] on Windows.

os.networkInterfaces()#

Get a list of network interfaces:

{ lo:
   [ { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true },
     { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       internal: true } ],
  eth0:
   [ { address: '192.168.1.108',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '01:02:03:0a:0b:0c',
       internal: false },
     { address: 'fe80::a00:27ff:fe4e:66a1',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '01:02:03:0a:0b:0c',
       internal: false } ] }

Note that due to the underlying implementation this will only return network interfaces that have been assigned an address.

os.platform()#

Returns the operating system platform. Possible values are 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'. Returns the value of process.platform.

os.release()#

Returns the operating system release.

os.tmpdir()#

Returns the operating system's default directory for temporary files.

os.totalmem()#

Returns the total amount of system memory in bytes.

os.type()#

Returns the operating system name. For example 'Linux' on Linux, 'Darwin' on OS X and 'Windows_NT' on Windows.

os.uptime()#

Returns the system uptime in seconds.

Path#

Stability: 2 - Stable

This module contains utilities for handling and transforming file paths. Almost all these methods perform only string transformations. The file system is not consulted to check whether paths are valid.

Use require('path') to use this module. The following methods are provided:

path.basename(p[, ext])#

Return the last portion of a path. Similar to the Unix basename command.

Example:

path.basename('/foo/bar/baz/asdf/quux.html')
// returns
'quux.html'

path.basename('/foo/bar/baz/asdf/quux.html', '.html')
// returns
'quux'

path.delimiter#

The platform-specific path delimiter, ; or ':'.

An example on *nix:

console.log(process.env.PATH)
// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'

process.env.PATH.split(path.delimiter)
// returns
['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']

An example on Windows:

console.log(process.env.PATH)
// 'C:\Windows\system32;C:\Windows;C:\Program Files\node\'

process.env.PATH.split(path.delimiter)
// returns
['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\']

path.dirname(p)#

Return the directory name of a path. Similar to the Unix dirname command.

Example:

path.dirname('/foo/bar/baz/asdf/quux')
// returns
'/foo/bar/baz/asdf'

path.extname(p)#

Return the extension of the path, from the last '.' to end of string in the last portion of the path. If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string. Examples:

path.extname('index.html')
// returns
'.html'

path.extname('index.coffee.md')
// returns
'.md'

path.extname('index.')
// returns
'.'

path.extname('index')
// returns
''

path.extname('.index')
// returns
''

path.format(pathObject)#

Returns a path string from an object, the opposite of path.parse above.

path.format({
    root : "/",
    dir : "/home/user/dir",
    base : "file.txt",
    ext : ".txt",
    name : "file"
})
// returns
'/home/user/dir/file.txt'

path.isAbsolute(path)#

Determines whether path is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory.

Posix examples:

path.isAbsolute('/foo/bar') // true
path.isAbsolute('/baz/..')  // true
path.isAbsolute('qux/')     // false
path.isAbsolute('.')        // false

Windows examples:

path.isAbsolute('//server')  // true
path.isAbsolute('C:/foo/..') // true
path.isAbsolute('bar\\baz')  // false
path.isAbsolute('.')         // false

Note: If the path string passed as parameter is a zero-length string, unlike other path module functions, it will be used as-is and false will be returned.

path.join([path1][, path2][, ...])#

Join all arguments together and normalize the resulting path.

Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown.

Example:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns
'/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws exception
TypeError: Arguments to path.join must be strings

Note: If the arguments to join have zero-length strings, unlike other path module functions, they will be ignored. If the joined path string is a zero-length string then '.' will be returned, which represents the current working directory.

path.normalize(p)#

Normalize a string path, taking care of '..' and '.' parts.

When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used.

Example:

path.normalize('/foo/bar//baz/asdf/quux/..')
// returns
'/foo/bar/baz/asdf'

Note: If the path string passed as argument is a zero-length string then '.' will be returned, which represents the current working directory.

path.parse(pathString)#

Returns an object from a path string.

An example on *nix:

path.parse('/home/user/dir/file.txt')
// returns
{
    root : "/",
    dir : "/home/user/dir",
    base : "file.txt",
    ext : ".txt",
    name : "file"
}

An example on Windows:

path.parse('C:\\path\\dir\\index.html')
// returns
{
    root : "C:\\",
    dir : "C:\\path\\dir",
    base : "index.html",
    ext : ".html",
    name : "index"
}

path.posix#

Provide access to aforementioned path methods but always interact in a posix compatible way.

path.relative(from, to)#

Solve the relative path from from to to.

At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve, which means we see that:

path.resolve(from, path.relative(from, to)) == path.resolve(to)

Examples:

path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb')
// returns
'..\\..\\impl\\bbb'

path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')
// returns
'../../impl/bbb'

Note: If the arguments to relative have zero-length strings then the current working directory will be used instead of the zero-length strings. If both the paths are the same then a zero-length string will be returned.

path.resolve([from ...], to)#

Resolves to to an absolute path.

If to isn't already absolute from arguments are prepended in right to left order, until an absolute path is found. If after using all from paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. Non-string from arguments are ignored.

Another way to think of it is as a sequence of cd commands in a shell.

path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')

Is similar to:

cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd

The difference is that the different paths don't need to exist and may also be files.

Examples:

path.resolve('/foo/bar', './baz')
// returns
'/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/')
// returns
'/tmp/file'

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// if currently in /home/myself/node, it returns
'/home/myself/node/wwwroot/static_files/gif/image.gif'

Note: If the arguments to resolve have zero-length strings then the current working directory will be used instead of them.

path.sep#

The platform-specific file separator. '\\' or '/'.

An example on *nix:

'foo/bar/baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

An example on Windows:

'foo\\bar\\baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

path.win32#

Provide access to aforementioned path methods but always interact in a win32 compatible way.

process#

The process object is a global object and can be accessed from anywhere. It is an instance of EventEmitter.

Event: 'beforeExit'#

This event is emitted when Node.js empties its event loop and has nothing else to schedule. Normally, Node.js exits when there is no work scheduled, but a listener for 'beforeExit' can make asynchronous calls, and cause Node.js to continue.

'beforeExit' is not emitted for conditions causing explicit termination, such as process.exit() or uncaught exceptions, and should not be used as an alternative to the 'exit' event unless the intention is to schedule more work.

Event: 'exit'#

Emitted when the process is about to exit. There is no way to prevent the exiting of the event loop at this point, and once all 'exit' listeners have finished running the process will exit. Therefore you must only perform synchronous operations in this handler. This is a good hook to perform checks on the module's state (like for unit tests). The callback takes one argument, the code the process is exiting with.

This event is only emitted when Node.js exits explicitly by process.exit() or implicitly by the event loop draining.

Example of listening for 'exit':

process.on('exit', (code) => {
  // do *NOT* do this
  setTimeout(() => {
    console.log('This will not run');
  }, 0);
  console.log('About to exit with code:', code);
});

Event: 'message'#

  • message Object a parsed JSON object or primitive value
  • sendHandle Handle object a net.Socket or net.Server object, or undefined.

Messages sent by ChildProcess.send() are obtained using the 'message' event on the child's process object.

Event: 'rejectionHandled'#

Emitted whenever a Promise was rejected and an error handler was attached to it (for example with .catch()) later than after an event loop turn. This event is emitted with the following arguments:

  • p the promise that was previously emitted in an 'unhandledRejection' event, but which has now gained a rejection handler.

There is no notion of a top level for a promise chain at which rejections can always be handled. Being inherently asynchronous in nature, a promise rejection can be be handled at a future point in time — possibly much later than the event loop turn it takes for the 'unhandledRejection' event to be emitted.

Another way of stating this is that, unlike in synchronous code where there is an ever-growing list of unhandled exceptions, with promises there is a growing-and-shrinking list of unhandled rejections. In synchronous code, the 'uncaughtException' event tells you when the list of unhandled exceptions grows. And in asynchronous code, the 'unhandledRejection' event tells you when the list of unhandled rejections grows, while the 'rejectionHandled' event tells you when the list of unhandled rejections shrinks.

For example using the rejection detection hooks in order to keep a map of all the rejected promise reasons at a given time:

const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {
  unhandledRejections.set(p, reason);
});
process.on('rejectionHandled', (p) => {
  unhandledRejections.delete(p);
});

This map will grow and shrink over time, reflecting rejections that start unhandled and then become handled. You could record the errors in some error log, either periodically (probably best for long-running programs, allowing you to clear the map, which in the case of a very buggy program could grow indefinitely) or upon process exit (more convenient for scripts).

Event: 'uncaughtException'#

Emitted when an exception bubbles all the way back to the event loop. If a listener is added for this exception, the default action (which is to print a stack trace and exit) will not occur.

Example of listening for 'uncaughtException':

process.on('uncaughtException', (err) => {
  console.log(`Caught exception: ${err}`);
});

setTimeout(() => {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

Note that 'uncaughtException' is a very crude mechanism for exception handling.

Do not use it as the Node.js equivalent of On Error Resume Next. An unhandled exception means your application - and by extension Node.js itself - is in an undefined state. Blindly resuming means anything could happen.

Think of resuming as pulling the power cord when you are upgrading your system. Nine out of ten times nothing happens - but the 10th time, your system is bust.

'uncaughtException' should be used to perform synchronous cleanup before shutting down the process. It is not safe to resume normal operation after 'uncaughtException'. If you do use it, restart your application after every unhandled exception!

You have been warned.

Event: 'unhandledRejection'#

Emitted whenever a Promise is rejected and no error handler is attached to the promise within a turn of the event loop. When programming with promises exceptions are encapsulated as rejected promises. Such promises can be caught and handled using promise.catch(...) and rejections are propagated through a promise chain. This event is useful for detecting and keeping track of promises that were rejected whose rejections were not handled yet. This event is emitted with the following arguments:

  • reason the object with which the promise was rejected (usually an Error instance).
  • p the promise that was rejected.

Here is an example that logs every unhandled rejection to the console

process.on('unhandledRejection', (reason, p) => {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

For example, here is a rejection that will trigger the 'unhandledRejection' event:

somePromise.then((res) => {
  return reportToUser(JSON.parse(res)); // note the typo
}); // no `.catch` or `.then`

Here is an example of a coding pattern that will also trigger 'unhandledRejection':

function SomeResource() {
  // Initially set the loaded status to a rejected promise
  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));
}

var resource = new SomeResource();
// no .catch or .then on resource.loaded for at least a turn

In cases like this, you may not want to track the rejection as a developer error like you would for other 'unhandledRejection' events. To address this, you can either attach a dummy .catch(function() { }) handler to resource.loaded, preventing the 'unhandledRejection' event from being emitted, or you can use the 'rejectionHandled' event. Below is an explanation of how to do that.

Exit Codes#

Node.js will normally exit with a 0 status code when no more async operations are pending. The following status codes are used in other cases:

  • 1 Uncaught Fatal Exception - There was an uncaught exception, and it was not handled by a domain or an 'uncaughtException' event handler.
  • 2 - Unused (reserved by Bash for builtin misuse)
  • 3 Internal JavaScript Parse Error - The JavaScript source code internal in Node.js's bootstrapping process caused a parse error. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 4 Internal JavaScript Evaluation Failure - The JavaScript source code internal in Node.js's bootstrapping process failed to return a function value when evaluated. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 5 Fatal Error - There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix FATAL ERROR.
  • 6 Non-function Internal Exception Handler - There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, and could not be called.
  • 7 Internal Exception Handler Run-Time Failure - There was an uncaught exception, and the internal fatal exception handler function itself threw an error while attempting to handle it. This can happen, for example, if a process.on('uncaughtException') or domain.on('error') handler throws an error.
  • 8 - Unused. In previous versions of Node.js, exit code 8 sometimes indicated an uncaught exception.
  • 9 - Invalid Argument - Either an unknown option was specified, or an option requiring a value was provided without a value.
  • 10 Internal JavaScript Run-Time Failure - The JavaScript source code internal in Node.js's bootstrapping process threw an error when the bootstrapping function was called. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 12 Invalid Debug Argument - The --debug and/or --debug-brk options were set, but an invalid port number was chosen.
  • >128 Signal Exits - If Node.js receives a fatal signal such as SIGKILL or SIGHUP, then its exit code will be 128 plus the value of the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code.

Signal Events#

Emitted when the processes receives a signal. See sigaction(2) for a list of standard POSIX signal names such as SIGINT, SIGHUP, etc.

Example of listening for SIGINT:

// Start reading from stdin so we don't exit.
process.stdin.resume();

process.on('SIGINT', () => {
  console.log('Got SIGINT.  Press Control-D to exit.');
});

An easy way to send the SIGINT signal is with Control-C in most terminal programs.

Note:

  • SIGUSR1 is reserved by Node.js to start the debugger. It's possible to install a listener but that won't stop the debugger from starting.
  • SIGTERM and SIGINT have default handlers on non-Windows platforms that resets the terminal mode before exiting with code 128 + signal number. If one of these signals has a listener installed, its default behavior will be removed (Node.js will no longer exit).
  • SIGPIPE is ignored by default. It can have a listener installed.
  • SIGHUP is generated on Windows when the console window is closed, and on other platforms under various similar conditions, see signal(7). It can have a listener installed, however Node.js will be unconditionally terminated by Windows about 10 seconds later. On non-Windows platforms, the default behavior of SIGHUP is to terminate Node.js, but once a listener has been installed its default behavior will be removed.
  • SIGTERM is not supported on Windows, it can be listened on.
  • SIGINT from the terminal is supported on all platforms, and can usually be generated with CTRL+C (though this may be configurable). It is not generated when terminal raw mode is enabled.
  • SIGBREAK is delivered on Windows when CTRL+BREAK is pressed, on non-Windows platforms it can be listened on, but there is no way to send or generate it.
  • SIGWINCH is delivered when the console has been resized. On Windows, this will only happen on write to the console when the cursor is being moved, or when a readable tty is used in raw mode.
  • SIGKILL cannot have a listener installed, it will unconditionally terminate Node.js on all platforms.
  • SIGSTOP cannot have a listener installed.

Note that Windows does not support sending Signals, but Node.js offers some emulation with process.kill(), and child_process.kill(). Sending signal 0 can be used to test for the existence of a process. Sending SIGINT, SIGTERM, and SIGKILL cause the unconditional termination of the target process.

process.abort()#

This causes Node.js to emit an abort. This will cause Node.js to exit and generate a core file.

process.arch#

What processor architecture you're running on: 'arm', 'ia32', or 'x64'.

console.log('This processor architecture is ' + process.arch);

process.argv#

An array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments.

// print process.argv
process.argv.forEach((val, index, array) => {
  console.log(`${index}: ${val}`);
});

This will generate:

$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four

process.chdir(directory)#

Changes the current working directory of the process or throws an exception if that fails.

console.log(`Starting directory: ${process.cwd()}`);
try {
  process.chdir('/tmp');
  console.log(`New directory: ${process.cwd()}`);
}
catch (err) {
  console.log(`chdir: ${err}`);
}

process.config#

An Object containing the JavaScript representation of the configure options that were used to compile the current Node.js executable. This is the same as the config.gypi file that was produced when running the ./configure script.

An example of the possible output looks like:

{ target_defaults:
   { cflags: [],
     default_configuration: 'Release',
     defines: [],
     include_dirs: [],
     libraries: [] },
  variables:
   { host_arch: 'x64',
     node_install_npm: 'true',
     node_prefix: '',
     node_shared_cares: 'false',
     node_shared_http_parser: 'false',
     node_shared_libuv: 'false',
     node_shared_zlib: 'false',
     node_use_dtrace: 'false',
     node_use_openssl: 'true',
     node_shared_openssl: 'false',
     strict_aliasing: 'true',
     target_arch: 'x64',
     v8_use_snapshot: 'true' } }

process.connected#

  • Boolean Set to false after process.disconnect() is called

If process.connected is false, it is no longer possible to send messages.

process.cwd()#

Returns the current working directory of the process.

console.log(`Current directory: ${process.cwd()}`);

process.disconnect()#

Close the IPC channel to the parent process, allowing this child to exit gracefully once there are no other connections keeping it alive.

Identical to the parent process's ChildProcess.disconnect().

If Node.js was not spawned with an IPC channel, process.disconnect() will be undefined.

process.env#

An object containing the user environment. See environ(7).

An example of this object looks like:

{ TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node' }

You can write to this object, but changes won't be reflected outside of your process. That means that the following won't work:

$ node -e 'process.env.foo = "bar"' && echo $foo

But this will:

process.env.foo = 'bar';
console.log(process.env.foo);

process.execArgv#

This is the set of Node.js-specific command line options from the executable that started the process. These options do not show up in process.argv, and do not include the Node.js executable, the name of the script, or any options following the script name. These options are useful in order to spawn child processes with the same execution environment as the parent.

Example:

$ node --harmony script.js --version

results in process.execArgv:

['--harmony']

and process.argv:

['/usr/local/bin/node', 'script.js', '--version']

process.execPath#

This is the absolute pathname of the executable that started the process.

Example:

/usr/local/bin/node

process.exit([code])#

Ends the process with the specified code. If omitted, exit uses the 'success' code 0.

To exit with a 'failure' code:

process.exit(1);

The shell that executed Node.js should see the exit code as 1.

process.exitCode#

A number which will be the process exit code, when the process either exits gracefully, or is exited via process.exit() without specifying a code.

Specifying a code to process.exit(code) will override any previous setting of process.exitCode.

process.getegid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the effective group identity of the process. (See getegid(2).) This is the numerical group id, not the group name.

if (process.getegid) {
  console.log(`Current gid: ${process.getegid()}`);
}

process.geteuid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the effective user identity of the process. (See geteuid(2).) This is the numerical userid, not the username.

if (process.geteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
}

process.getgid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the group identity of the process. (See getgid(2).) This is the numerical group id, not the group name.

if (process.getgid) {
  console.log(`Current gid: ${process.getgid()}`);
}

process.getgroups()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Returns an array with the supplementary group IDs. POSIX leaves it unspecified if the effective group ID is included but Node.js ensures it always is.

process.getuid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the user identity of the process. (See getuid(2).) This is the numerical userid, not the username.

if (process.getuid) {
  console.log(`Current uid: ${process.getuid()}`);
}

process.hrtime()#

Returns the current high-resolution real time in a [seconds, nanoseconds] tuple Array. It is relative to an arbitrary time in the past. It is not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals.

You may pass in the result of a previous call to process.hrtime() to get a diff reading, useful for benchmarks and measuring intervals:

var time = process.hrtime();
// [ 1800216, 25 ]

setTimeout(() => {
  var diff = process.hrtime(time);
  // [ 1, 552 ]

  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
  // benchmark took 1000000527 nanoseconds
}, 1000);

process.initgroups(user, extra_group)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Reads /etc/group and initializes the group access list, using all groups of which the user is a member. This is a privileged operation, meaning you need to be root or have the CAP_SETGID capability.

user is a user name or user ID. extra_group is a group name or group ID.

Some care needs to be taken when dropping privileges. Example:

console.log(process.getgroups());         // [ 0 ]
process.initgroups('bnoordhuis', 1000);   // switch user
console.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000);                     // drop root gid
console.log(process.getgroups());         // [ 27, 30, 46, 1000 ]

process.kill(pid[, signal])#

Send a signal to a process. pid is the process id and signal is the string describing the signal to send. Signal names are strings like SIGINT or SIGHUP. If omitted, the signal will be SIGTERM. See Signal Events and kill(2) for more information.

Will throw an error if target does not exist, and as a special case, a signal of 0 can be used to test for the existence of a process. Windows platforms will throw an error if the pid is used to kill a process group.

Note that even though the name of this function is process.kill, it is really just a signal sender, like the kill system call. The signal sent may do something other than kill the target process.

Example of sending a signal to yourself:

process.on('SIGHUP', () => {
  console.log('Got SIGHUP signal.');
});

setTimeout(() => {
  console.log('Exiting.');
  process.exit(0);
}, 100);

process.kill(process.pid, 'SIGHUP');

Note: When SIGUSR1 is received by Node.js it starts the debugger, see Signal Events.

process.mainModule#

Alternate way to retrieve require.main. The difference is that if the main module changes at runtime, require.main might still refer to the original main module in modules that were required before the change occurred. Generally it's safe to assume that the two refer to the same module.

As with require.main, it will be undefined if there was no entry script.

process.memoryUsage()#

Returns an object describing the memory usage of the Node.js process measured in bytes.

const util = require('util');

console.log(util.inspect(process.memoryUsage()));

This will generate:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 }

heapTotal and heapUsed refer to V8's memory usage.

process.nextTick(callback[, arg][, ...])#

  • callback Function

Once the current event loop turn runs to completion, call the callback function.

This is not a simple alias to setTimeout(fn, 0), it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop.

console.log('start');
process.nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback

This is important in developing APIs where you want to give the user the chance to assign event handlers after an object has been constructed, but before any I/O has occurred.

function MyThing(options) {
  this.setupOptions(options);

  process.nextTick(() => {
    this.startDoingStuff();
  }.bind(this));
}

var thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.

It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}

This API is hazardous. If you do this:

maybeSync(true, function() {
  foo();
});
bar();

then it's not clear whether foo() or bar() will be called first.

This approach is much better:

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

Note: the nextTick queue is completely drained on each pass of the event loop before additional I/O is processed. As a result, recursively setting nextTick callbacks will block any I/O from happening, just like a while(true); loop.

process.pid#

The PID of the process.

console.log(`This process is pid ${process.pid}`);

process.platform#

What platform you're running on: 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'

console.log(`This platform is ${process.platform}`);

process.release#

An Object containing metadata related to the current release, including URLs for the source tarball and headers-only tarball.

process.release contains the following properties:

  • name: a string with a value that will always be 'node' for Node.js. For legacy io.js releases, this will be 'io.js'.
  • sourceUrl: a complete URL pointing to a .tar.gz file containing the source of the current release.
  • headersUrl: a complete URL pointing to a .tar.gz file containing only the header files for the current release. This file is significantly smaller than the full source file and can be used for compiling add-ons against Node.js.
  • libUrl: a complete URL pointing to an node.lib file matching the architecture and version of the current release. This file is used for compiling add-ons against Node.js. This property is only present on Windows builds of Node.js and will be missing on all other platforms.

e.g.

{ name: 'node',
  sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz',
  headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz',
  libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' }

In custom builds from non-release versions of the source tree, only the name property may be present. The additional properties should not be relied upon to exist.

process.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object

When Node.js is spawned with an IPC channel attached, it can send messages to its parent process using process.send(). Each will be received as a 'message' event on the parent's ChildProcess object.

If Node.js was not spawned with an IPC channel, process.send() will be undefined.

process.setegid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the effective group identity of the process. (See setegid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID.

if (process.getegid && process.setegid) {
  console.log(`Current gid: ${process.getegid()}`);
  try {
    process.setegid(501);
    console.log(`New gid: ${process.getegid()}`);
  }
  catch (err) {
    console.log(`Failed to set gid: ${err}`);
  }
}

process.seteuid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the effective user identity of the process. (See seteuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID.

if (process.geteuid && process.seteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
  try {
    process.seteuid(501);
    console.log(`New uid: ${process.geteuid()}`);
  }
  catch (err) {
    console.log(`Failed to set uid: ${err}`);
  }
}

process.setgid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the group identity of the process. (See setgid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID.

if (process.getgid && process.setgid) {
  console.log(`Current gid: ${process.getgid()}`);
  try {
    process.setgid(501);
    console.log(`New gid: ${process.getgid()}`);
  }
  catch (err) {
    console.log(`Failed to set gid: ${err}`);
  }
}

process.setgroups(groups)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the supplementary group IDs. This is a privileged operation, meaning you need to be root or have the CAP_SETGID capability.

The list can contain group IDs, group names or both.

process.setuid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the user identity of the process. (See setuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID.

if (process.getuid && process.setuid) {
  console.log(`Current uid: ${process.getuid()}`);
  try {
    process.setuid(501);
    console.log(`New uid: ${process.getuid()}`);
  }
  catch (err) {
    console.log(`Failed to set uid: ${err}`);
  }
}

process.stderr#

A writable stream to stderr (on fd 2).

process.stderr and process.stdout are unlike other streams in Node.js in that they cannot be closed (end() will throw), they never emit the finish event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.)

process.stdin#

A Readable Stream for stdin (on fd 0).

Example of opening standard input and listening for both events:

process.stdin.setEncoding('utf8');

process.stdin.on('readable', () => {
  var chunk = process.stdin.read();
  if (chunk !== null) {
    process.stdout.write(`data: ${chunk}`);
  }
});

process.stdin.on('end', () => {
  process.stdout.write('end');
});

As a Stream, process.stdin can also be used in "old" mode that is compatible with scripts written for node.js prior to v0.10. For more information see Stream compatibility.

In "old" Streams mode the stdin stream is paused by default, so one must call process.stdin.resume() to read from it. Note also that calling process.stdin.resume() itself would switch stream to "old" mode.

If you are starting a new project you should prefer a more recent "new" Streams mode over "old" one.

process.stdout#

A Writable Stream to stdout (on fd 1).

For example, a console.log equivalent could look like this:

console.log = function(msg) {
  process.stdout.write(`${msg}\n`);
};

process.stderr and process.stdout are unlike other streams in Node.js in that they cannot be closed (end() will throw), they never emit the 'finish' event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.)

To check if Node.js is being run in a TTY context, read the isTTY property on process.stderr, process.stdout, or process.stdin:

$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

See the tty docs for more information.

process.title#

Getter/setter to set what is displayed in ps.

When used as a setter, the maximum length is platform-specific and probably short.

On Linux and OS X, it's limited to the size of the binary name plus the length of the command line arguments because it overwrites the argv memory.

v0.8 allowed for longer process title strings by also overwriting the environ memory but that was potentially insecure/confusing in some (rather obscure) cases.

process.umask([mask])#

Sets or reads the process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the old mask if mask argument is given, otherwise returns the current mask.

const newmask = 0o022;
const oldmask = process.umask(newmask);
console.log(
  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`
);

process.uptime()#

Number of seconds Node.js has been running.

process.version#

A compiled-in property that exposes NODE_VERSION.

console.log(`Version: ${process.version}`);

process.versions#

A property exposing version strings of Node.js and its dependencies.

console.log(process.versions);

Will print something like:

{ http_parser: '2.3.0',
  node: '1.1.1',
  v8: '4.1.0.14',
  uv: '1.3.0',
  zlib: '1.2.8',
  ares: '1.10.0-DEV',
  modules: '43',
  icu: '55.1',
  openssl: '1.0.1k' }

punycode#

Stability: 2 - Stable

Punycode.js is bundled with Node.js v0.6.2+. Use require('punycode') to access it. (To use it with other Node.js versions, use npm to install the punycode module first.)

punycode.decode(string)#

Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols.

// decode domain name parts
punycode.decode('maana-pta'); // 'mañana'
punycode.decode('--dqo34k'); // '☃-⌘'

punycode.encode(string)#

Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols.

// encode domain name parts
punycode.encode('mañana'); // 'maana-pta'
punycode.encode('☃-⌘'); // '--dqo34k'

punycode.toASCII(domain)#

Converts a Unicode string representing a domain name to Punycode. Only the non-ASCII parts of the domain name will be converted, i.e. it doesn't matter if you call it with a domain that's already in ASCII.

// encode domain names
punycode.toASCII('mañana.com'); // 'xn--maana-pta.com'
punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'

punycode.toUnicode(domain)#

Converts a Punycode string representing a domain name to Unicode. Only the Punycoded parts of the domain name will be converted, i.e. it doesn't matter if you call it on a string that has already been converted to Unicode.

// decode domain names
punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'
punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'

punycode.ucs2#

punycode.ucs2.decode(string)#

Creates an array containing the numeric code point values of each Unicode symbol in the string. While JavaScript uses UCS-2 internally, this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16.

punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]
// surrogate pair for U+1D306 tetragram for centre:
punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306]

punycode.ucs2.encode(codePoints)#

Creates a string based on an array of numeric code point values.

punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'
punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06'

punycode.version#

A string representing the current Punycode.js version number.

Query String#

Stability: 2 - Stable

This module provides utilities for dealing with query strings. It provides the following methods:

querystring.escape#

The escape function used by querystring.stringify, provided so that it could be overridden if necessary.

querystring.parse(str[, sep][, eq][, options])#

Deserialize a query string to an object. Optionally override the default separator ('&') and assignment ('=') characters.

Options object may contain maxKeys property (equal to 1000 by default), it'll be used to limit processed keys. Set it to 0 to remove key count limitation.

Options object may contain decodeURIComponent property (querystring.unescape by default), it can be used to decode a non-utf8 encoding string if necessary.

Example:

querystring.parse('foo=bar&baz=qux&baz=quux&corge')
// returns
{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }

// Suppose gbkDecodeURIComponent function already exists,
// it can decode `gbk` encoding string
querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null,
  { decodeURIComponent: gbkDecodeURIComponent })
// returns
{ w: '中文', foo: 'bar' }

querystring.stringify(obj[, sep][, eq][, options])#

Serialize an object to a query string. Optionally override the default separator ('&') and assignment ('=') characters.

Options object may contain encodeURIComponent property (querystring.escape by default), it can be used to encode string with non-utf8 encoding if necessary.

Example:

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
// returns
'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
// returns
'foo:bar;baz:qux'

// Suppose gbkEncodeURIComponent function already exists,
// it can encode string with `gbk` encoding
querystring.stringify({ w: '中文', foo: 'bar' }, null, null,
  { encodeURIComponent: gbkEncodeURIComponent })
// returns
'w=%D6%D0%CE%C4&foo=bar'

querystring.unescape#

The unescape function used by querystring.parse, provided so that it could be overridden if necessary.

It will try to use decodeURIComponent in the first place, but if that fails it falls back to a safer equivalent that doesn't throw on malformed URLs.

Readline#

Stability: 2 - Stable

To use this module, do require('readline'). Readline allows reading of a stream (such as process.stdin) on a line-by-line basis.

Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. Here's how to allow your program to gracefully exit:

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log('Thank you for your valuable feedback:', answer);

  rl.close();
});

Class: Interface#

The class that represents a readline interface with an input and output stream.

rl.close()#

Closes the Interface instance, relinquishing control on the input and output streams. The 'close' event will also be emitted.

rl.pause()#

Pauses the readline input stream, allowing it to be resumed later if needed.

Note that this doesn't immediately pause the stream of events. Several events may be emitted after calling pause, including line.

rl.prompt([preserveCursor])#

Readies readline for input from the user, putting the current setPrompt options on a new line, giving the user a new spot to write. Set preserveCursor to true to prevent the cursor placement being reset to 0.

This will also resume the input stream used with createInterface if it has been paused.

If output is set to null or undefined when calling createInterface, the prompt is not written.

rl.question(query, callback)#

Prepends the prompt with query and invokes callback with the user's response. Displays the query to the user, and then invokes callback with the user's response after it has been typed.

This will also resume the input stream used with createInterface if it has been paused.

If output is set to null or undefined when calling createInterface, nothing is displayed.

Example usage:

interface.question('What is your favorite food?', (answer) => {
  console.log(`Oh, so your favorite food is ${answer}`);
});

rl.resume()#

Resumes the readline input stream.

rl.setPrompt(prompt)#

Sets the prompt, for example when you run node on the command line, you see > , which is Node.js's prompt.

rl.write(data[, key])#

Writes data to output stream, unless output is set to null or undefined when calling createInterface. key is an object literal to represent a key sequence; available if the terminal is a TTY.

This will also resume the input stream if it has been paused.

Example:

rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});

Events#

Event: 'close'#

function () {}

Emitted when close() is called.

Also emitted when the input stream receives its 'end' event. The Interface instance should be considered "finished" once this is emitted. For example, when the input stream receives ^D, respectively known as EOT.

This event is also called if there is no SIGINT event listener present when the input stream receives a ^C, respectively known as SIGINT.

Event: 'line'#

function (line) {}

Emitted whenever the input stream receives a \n, usually received when the user hits enter, or return. This is a good hook to listen for user input.

Example of listening for 'line':

rl.on('line', (cmd) => {
  console.log(`You just typed: ${cmd}`);
});

Event: 'pause'#

function () {}

Emitted whenever the input stream is paused.

Also emitted whenever the input stream is not paused and receives the SIGCONT event. (See events SIGTSTP and SIGCONT)

Example of listening for 'pause':

rl.on('pause', () => {
  console.log('Readline paused.');
});

Event: 'resume'#

function () {}

Emitted whenever the input stream is resumed.

Example of listening for 'resume':

rl.on('resume', () => {
  console.log('Readline resumed.');
});

Event: 'SIGCONT'#

function () {}

This does not work on Windows.

Emitted whenever the input stream is sent to the background with ^Z, respectively known as SIGTSTP, and then continued with fg(1). This event only emits if the stream was not paused before sending the program to the background.

Example of listening for SIGCONT:

rl.on('SIGCONT', () => {
  // `prompt` will automatically resume the stream
  rl.prompt();
});

Event: 'SIGINT'#

function () {}

Emitted whenever the input stream receives a ^C, respectively known as SIGINT. If there is no SIGINT event listener present when the input stream receives a SIGINT, pause will be triggered.

Example of listening for SIGINT:

rl.on('SIGINT', () => {
  rl.question('Are you sure you want to exit?', (answer) => {
    if (answer.match(/^y(es)?$/i)) rl.pause();
  });
});

Event: 'SIGTSTP'#

function () {}

This does not work on Windows.

Emitted whenever the input stream receives a ^Z, respectively known as SIGTSTP. If there is no SIGTSTP event listener present when the input stream receives a SIGTSTP, the program will be sent to the background.

When the program is resumed with fg, the 'pause' and SIGCONT events will be emitted. You can use either to resume the stream.

The 'pause' and SIGCONT events will not be triggered if the stream was paused before the program was sent to the background.

Example of listening for SIGTSTP:

rl.on('SIGTSTP', () => {
  // This will override SIGTSTP and prevent the program from going to the
  // background.
  console.log('Caught SIGTSTP.');
});

Example: Tiny CLI#

Here's an example of how to use all these together to craft a tiny command line interface:

const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

rl.setPrompt('OHAI> ');
rl.prompt();

rl.on('line', (line) => {
  switch(line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log('Say what? I might have heard `' + line.trim() + '`');
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  process.exit(0);
});

Example: Read File Stream Line-by-Line#

A common case for readline's input option is to pass a filesystem readable stream to it. This is how one could craft line-by-line parsing of a file:

const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('sample.txt')
});

rl.on('line', function (line) {
  console.log('Line from file:', line);
});

readline.clearLine(stream, dir)#

Clears current line of given TTY stream in a specified direction. dir should have one of following values:

  • -1 - to the left from cursor
  • 1 - to the right from cursor
  • 0 - the entire line

readline.clearScreenDown(stream)#

Clears the screen from the current position of the cursor down.

readline.createInterface(options)#

Creates a readline Interface instance. Accepts an options Object that takes the following values:

  • input - the readable stream to listen to (Required).

  • output - the writable stream to write readline data to (Optional).

  • completer - an optional function that is used for Tab autocompletion. See below for an example of using this.

  • terminal - pass true if the input and output streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking isTTY on the output stream upon instantiation.

  • historySize - maximum number of history lines retained. Defaults to 30.

The completer function is given the current line entered by the user, and is supposed to return an Array with 2 entries:

  1. An Array with matching entries for the completion.

  2. The substring that was used for the matching.

Which ends up looking something like: [[substr1, substr2, ...], originalsubstring].

Example:

function completer(line) {
  var completions = '.help .error .exit .quit .q'.split(' ')
  var hits = completions.filter((c) => { return c.indexOf(line) == 0 })
  // show all completions if none found
  return [hits.length ? hits : completions, line]
}

Also completer can be run in async mode if it accepts two arguments:

function completer(linePartial, callback) {
  callback(null, [['123'], linePartial]);
}

createInterface is commonly used with process.stdin and process.stdout in order to accept user input:

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

Once you have a readline instance, you most commonly listen for the 'line' event.

If terminal is true for this instance then the output stream will get the best compatibility if it defines an output.columns property, and fires a 'resize' event on the output if/when the columns ever change (process.stdout does this automatically when it is a TTY).

readline.cursorTo(stream, x, y)#

Move cursor to the specified position in a given TTY stream.

readline.moveCursor(stream, dx, dy)#

Move cursor relative to it's current position in a given TTY stream.

REPL#

Stability: 2 - Stable

A Read-Eval-Print-Loop (REPL) is available both as a standalone program and easily includable in other programs. The REPL provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out.

By executing node without any arguments from the command-line you will be dropped into the REPL. It has simplistic emacs line-editing.

mjr:~$ node
Type '.help' for options.
> a = [ 1, 2, 3];
[ 1, 2, 3 ]
> a.forEach(function (v) {
...   console.log(v);
...   });
1
2
3

For advanced line-editors, start Node.js with the environmental variable NODE_NO_READLINE=1. This will start the main and debugger REPL in canonical terminal settings which will allow you to use with rlwrap.

For example, you could add this to your bashrc file:

alias node="env NODE_NO_READLINE=1 rlwrap node"

Environment Variable Options#

The built-in repl (invoked by running node or node -i) may be controlled via the following environment variables:

  • NODE_REPL_HISTORY - When a valid path is given, persistent REPL history will be saved to the specified file rather than .node_repl_history in the user's home directory. Setting this value to "" will disable persistent REPL history.
  • NODE_REPL_HISTORY_SIZE - defaults to 1000. Controls how many lines of history will be persisted if history is available. Must be a positive number.
  • NODE_REPL_MODE - may be any of sloppy, strict, or magic. Defaults to magic, which will automatically run "strict mode only" statements in strict mode.

Persistent History#

By default, the REPL will persist history between node REPL sessions by saving to a .node_repl_history file in the user's home directory. This can be disabled by setting the environment variable NODE_REPL_HISTORY="".

NODE_REPL_HISTORY_FILE#

Stability: 0 - Deprecated: Use NODE_REPL_HISTORY instead.

Previously in Node.js/io.js v2.x, REPL history was controlled by using a NODE_REPL_HISTORY_FILE environment variable, and the history was saved in JSON format. This variable has now been deprecated, and your REPL history will automatically be converted to using plain text. The new file will be saved to either your home directory, or a directory defined by the NODE_REPL_HISTORY variable, as documented below.

REPL Features#

Inside the REPL, Control+D will exit. Multi-line expressions can be input. Tab completion is supported for both global and local variables.

Core modules will be loaded on-demand into the environment. For example, accessing fs will require() the fs module as global.fs.

The special variable _ (underscore) contains the result of the last expression.

> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4

The REPL provides access to any variables in the global scope. You can expose a variable to the REPL explicitly by assigning it to the context object associated with each REPLServer. For example:

// repl_test.js
const repl = require('repl');
var msg = 'message';

repl.start('> ').context.m = msg;

Things in the context object appear as local within the REPL:

mjr:~$ node repl_test.js
> m
'message'

There are a few special REPL commands:

  • .break - While inputting a multi-line expression, sometimes you get lost or just don't care about completing it. .break will start over.
  • .clear - Resets the context object to an empty object and clears any multi-line expression.
  • .exit - Close the I/O stream, which will cause the REPL to exit.
  • .help - Show this list of special commands.
  • .save - Save the current REPL session to a file

    .save ./file/to/save.js

  • .load - Load a file into the current REPL session.

    .load ./file/to/load.js

The following key combinations in the REPL have these special effects:

  • <ctrl>C - Similar to the .break keyword. Terminates the current command. Press twice on a blank line to forcibly exit.
  • <ctrl>D - Similar to the .exit keyword.
  • <tab> - Show both global and local(scope) variables

Customizing Object displays in the REPL#

The REPL module internally uses util.inspect(), when printing values. However, util.inspect delegates the call to the object's inspect() function, if it has one. You can read more about this delegation here.

For example, if you have defined an inspect() function on an object, like this:

> var obj = { foo: 'this will not show up in the inspect() output' };
undefined
> obj.inspect = function() {
...   return { bar: 'baz' };
... };
[Function]

and try to print obj in REPL, it will invoke the custom inspect() function:

> obj
{ bar: 'baz' }

Class: REPLServer#

This inherits from Readline Interface with the following events:

Event: 'exit'#

function () {}

Emitted when the user exits the REPL in any of the defined ways. Namely, typing .exit at the repl, pressing Ctrl+C twice to signal SIGINT, or pressing Ctrl+D to signal 'end' on the input stream.

Example of listening for exit:

replServer.on('exit', () => {
  console.log('Got "exit" event from repl!');
  process.exit();
});

Event: 'reset'#

function (context) {}

Emitted when the REPL's context is reset. This happens when you type .clear. If you start the repl with { useGlobal: true } then this event will never be emitted.

Example of listening for reset:

// Extend the initial repl context.
var replServer = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
replServer.on('reset', (context) => {
  console.log('repl has a new context');
  someExtension.extend(context);
});

replServer.defineCommand(keyword, cmd)#

  • keyword String
  • cmd Object|Function

Makes a command available in the REPL. The command is invoked by typing a . followed by the keyword. The cmd is an object with the following values:

  • help - help text to be displayed when .help is entered (Optional).
  • action - a function to execute, potentially taking in a string argument, when the command is invoked, bound to the REPLServer instance (Required).

If a function is provided instead of an object for cmd, it is treated as the action.

Example of defining a command:

// repl_test.js
const repl = require('repl');

var replServer = repl.start();
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action: function(name) {
    this.write(`Hello, ${name}!\n');
    this.displayPrompt();
  }
});

Example of invoking that command from the REPL:

> .sayhello Node.js User
Hello, Node.js User!

replServer.displayPrompt([preserveCursor])#

  • preserveCursor Boolean

Like readline.prompt except also adding indents with ellipses when inside blocks. The preserveCursor argument is passed to readline.prompt. This is used primarily with defineCommand. It's also used internally to render each prompt line.

repl.start(options)#

Returns and starts a REPLServer instance, that inherits from Readline Interface. Accepts an "options" Object that takes the following values:

  • prompt - the prompt and stream for all I/O. Defaults to > .

  • input - the readable stream to listen to. Defaults to process.stdin.

  • output - the writable stream to write readline data to. Defaults to process.stdout.

  • terminal - pass true if the stream should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking isTTY on the output stream upon instantiation.

  • eval - function that will be used to eval each given line. Defaults to an async wrapper for eval(). See below for an example of a custom eval.

  • useColors - a boolean which specifies whether or not the writer function should output colors. If a different writer function is set then this does nothing. Defaults to the repl's terminal value.

  • useGlobal - if set to true, then the repl will use the global object, instead of running scripts in a separate context. Defaults to false.

  • ignoreUndefined - if set to true, then the repl will not output the return value of command if it's undefined. Defaults to false.

  • writer - the function to invoke for each command that gets evaluated which returns the formatting (including coloring) to display. Defaults to util.inspect.

  • replMode - controls whether the repl runs all commands in strict mode, default mode, or a hybrid mode ("magic" mode.) Acceptable values are:

    • repl.REPL_MODE_SLOPPY - run commands in sloppy mode.
    • repl.REPL_MODE_STRICT - run commands in strict mode. This is equivalent to prefacing every repl statement with 'use strict'.
    • repl.REPL_MODE_MAGIC - attempt to run commands in default mode. If they fail to parse, re-try in strict mode.

You can use your own eval function if it has following signature:

function eval(cmd, context, filename, callback) {
  callback(null, result);
}

On tab completion - eval will be called with .scope as an input string. It is expected to return an array of scope names to be used for the auto-completion.

Multiple REPLs may be started against the same running instance of Node.js. Each will share the same global object but will have unique I/O.

Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:

const net = require('net');
const repl = require('repl');
var connections = 0;

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout
});

net.createServer((socket) => {
  connections += 1;
  repl.start({
    prompt: 'Node.js via Unix socket> ',
    input: socket,
    output: socket
  }).on('exit', () => {
    socket.end();
  })
}).listen('/tmp/node-repl-sock');

net.createServer((socket) => {
  connections += 1;
  repl.start({
    prompt: 'Node.js via TCP socket> ',
    input: socket,
    output: socket
  }).on('exit', () => {
    socket.end();
  });
}).listen(5001);

Running this program from the command line will start a REPL on stdin. Other REPL clients may connect through the Unix socket or TCP socket. telnet is useful for connecting to TCP sockets, and socat can be used to connect to both Unix and TCP sockets.

By starting a REPL from a Unix socket-based server instead of stdin, you can connect to a long-running Node.js process without restarting it.

For an example of running a "full-featured" (terminal) REPL over a net.Server and net.Socket instance, see: https://gist.github.com/2209310

For an example of running a REPL instance over curl(1), see: https://gist.github.com/2053342

Stream#

Stability: 2 - Stable

A stream is an abstract interface implemented by various objects in Node.js. For example a request to an HTTP server is a stream, as is stdout. Streams are readable, writable, or both. All streams are instances of EventEmitter.

You can load the Stream base classes by doing require('stream'). There are base classes provided for Readable streams, Writable streams, Duplex streams, and Transform streams.

This document is split up into 3 sections:

  1. The first section explains the parts of the API that you need to be aware of to use streams in your programs.
  2. The second section explains the parts of the API that you need to use if you implement your own custom streams yourself. The API is designed to make this easy for you to do.
  3. The third section goes into more depth about how streams work, including some of the internal mechanisms and functions that you should probably not modify unless you definitely know what you are doing.

API for Stream Consumers#

Streams can be either Readable, Writable, or both (Duplex).

All streams are EventEmitters, but they also have other custom methods and properties depending on whether they are Readable, Writable, or Duplex.

If a stream is both Readable and Writable, then it implements all of the methods and events below. So, a Duplex or Transform stream is fully described by this API, though their implementation may be somewhat different.

It is not necessary to implement Stream interfaces in order to consume streams in your programs. If you are implementing streaming interfaces in your own program, please also refer to API for Stream Implementors below.

Almost all Node.js programs, no matter how simple, use Streams in some way. Here is an example of using Streams in an Node.js program:

const http = require('http');

var server = http.createServer( (req, res) => {
  // req is an http.IncomingMessage, which is a Readable Stream
  // res is an http.ServerResponse, which is a Writable Stream

  var body = '';
  // we want to get the data as utf8 strings
  // If you don't set an encoding, then you'll get Buffer objects
  req.setEncoding('utf8');

  // Readable streams emit 'data' events once a listener is added
  req.on('data', (chunk) => {
    body += chunk;
  });

  // the end event tells you that you have entire body
  req.on('end', () => {
    try {
      var data = JSON.parse(body);
    } catch (er) {
      // uh oh!  bad json!
      res.statusCode = 400;
      return res.end(`error: ${er.message}`);
    }

    // write back something interesting to the user:
    res.write(typeof data);
    res.end();
  });
});

server.listen(1337);

// $ curl localhost:1337 -d '{}'
// object
// $ curl localhost:1337 -d '"foo"'
// string
// $ curl localhost:1337 -d 'not json'
// error: Unexpected token o

Class: stream.Duplex#

Duplex streams are streams that implement both the Readable and Writable interfaces. See above for usage.

Examples of Duplex streams include:

Class: stream.Readable#

The Readable stream interface is the abstraction for a source of data that you are reading from. In other words, data comes out of a Readable stream.

A Readable stream will not start emitting data until you indicate that you are ready to receive it.

Readable streams have two "modes": a flowing mode and a paused mode. When in flowing mode, data is read from the underlying system and provided to your program as fast as possible. In paused mode, you must explicitly call stream.read() to get chunks of data out. Streams start out in paused mode.

Note: If no data event handlers are attached, and there are no pipe() destinations, and the stream is switched into flowing mode, then data will be lost.

You can switch to flowing mode by doing any of the following:

  • Adding a 'data' event handler to listen for data.
  • Calling the resume() method to explicitly open the flow.
  • Calling the pipe() method to send the data to a Writable.

You can switch back to paused mode by doing either of the following:

  • If there are no pipe destinations, by calling the pause() method.
  • If there are pipe destinations, by removing any 'data' event handlers, and removing all pipe destinations by calling the unpipe() method.

Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data.

Examples of readable streams include:

Event: 'close'#

Emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. The event indicates that no more events will be emitted, and no further computation will occur.

Not all streams will emit the 'close' event.

Event: 'data'#

  • chunk Buffer | String The chunk of data.

Attaching a 'data' event listener to a stream that has not been explicitly paused will switch the stream into flowing mode. Data will then be passed as soon as it is available.

If you just want to get all the data out of the stream as fast as possible, this is the best way to do so.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
});

Event: 'end'#

This event fires when there will be no more data to read.

Note that the 'end' event will not fire unless the data is completely consumed. This can be done by switching into flowing mode, or by calling read() repeatedly until you get to the end.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
});
readable.on('end', () => {
  console.log('there will be no more data.');
});

Event: 'error'#

  • Error Object

Emitted if there was an error receiving data.

Event: 'readable'#

When a chunk of data can be read from the stream, it will emit a 'readable' event.

In some cases, listening for a 'readable' event will cause some data to be read into the internal buffer from the underlying system, if it hadn't already.

var readable = getReadableStreamSomehow();
readable.on('readable', () => {
  // there is some data to read now
});

Once the internal buffer is drained, a 'readable' event will fire again when more data is available.

The 'readable' event is not emitted in the "flowing" mode with the sole exception of the last one, on end-of-stream.

The 'readable' event indicates that the stream has new information: either new data is available or the end of the stream has been reached. In the former case, .read() will return that data. In the latter case, .read() will return null. For instance, in the following example, foo.txt is an empty file:

const fs = require('fs');
var rr = fs.createReadStream('foo.txt');
rr.on('readable', () => {
  console.log('readable:', rr.read());
});
rr.on('end', () => {
  console.log('end');
});

The output of running this script is:

bash-3.2$ node test.js
readable: null
end

readable.isPaused()#

  • Return: Boolean

This method returns whether or not the readable has been explicitly paused by client code (using readable.pause() without a corresponding readable.resume()).

var readable = new stream.Readable

readable.isPaused() // === false
readable.pause()
readable.isPaused() // === true
readable.resume()
readable.isPaused() // === false

readable.pause()#

  • Return: this

This method will cause a stream in flowing mode to stop emitting 'data' events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
  readable.pause();
  console.log('there will be no more data for 1 second');
  setTimeout(() => {
    console.log('now data will start flowing again');
    readable.resume();
  }, 1000);
});

readable.pipe(destination[, options])#

  • destination Writable Stream The destination for writing data
  • options Object Pipe options
    • end Boolean End the writer when the reader ends. Default = true

This method pulls all the data out of a readable stream, and writes it to the supplied destination, automatically managing the flow so that the destination is not overwhelmed by a fast readable stream.

Multiple destinations can be piped to safely.

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt'
readable.pipe(writable);

This function returns the destination stream, so you can set up pipe chains like so:

var r = fs.createReadStream('file.txt');
var z = zlib.createGzip();
var w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);

For example, emulating the Unix cat command:

process.stdin.pipe(process.stdout);

By default end() is called on the destination when the source stream emits end, so that destination is no longer writable. Pass { end: false } as options to keep the destination stream open.

This keeps writer open so that "Goodbye" can be written at the end.

reader.pipe(writer, { end: false });
reader.on('end', () => {
  writer.end('Goodbye\n');
});

Note that process.stderr and process.stdout are never closed until the process exits, regardless of the specified options.

readable.read([size])#

  • size Number Optional argument to specify how much data to read.
  • Return String | Buffer | null

The read() method pulls some data out of the internal buffer and returns it. If there is no data available, then it will return null.

If you pass in a size argument, then it will return that many bytes. If size bytes are not available, then it will return null, unless we've ended, in which case it will return the data remaining in the buffer.

If you do not specify a size argument, then it will return all the data in the internal buffer.

This method should only be called in paused mode. In flowing mode, this method is called automatically until the internal buffer is drained.

var readable = getReadableStreamSomehow();
readable.on('readable', () => {
  var chunk;
  while (null !== (chunk = readable.read())) {
    console.log('got %d bytes of data', chunk.length);
  }
});

If this method returns a data chunk, then it will also trigger the emission of a 'data' event.

Note that calling readable.read([size]) after the 'end' event has been triggered will return null. No runtime error will be raised.

readable.resume()#

  • Return: this

This method will cause the readable stream to resume emitting data events.

This method will switch the stream into flowing mode. If you do not want to consume the data from a stream, but you do want to get to its 'end' event, you can call readable.resume() to open the flow of data.

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
  console.log('got to the end, but did not read anything');
});

readable.setEncoding(encoding)#

  • encoding String The encoding to use.
  • Return: this

Call this function to cause the stream to return strings of the specified encoding instead of Buffer objects. For example, if you do readable.setEncoding('utf8'), then the output data will be interpreted as UTF-8 data, and returned as strings. If you do readable.setEncoding('hex'), then the data will be encoded in hexadecimal string format.

This properly handles multi-byte characters that would otherwise be potentially mangled if you simply pulled the Buffers directly and called buf.toString(encoding) on them. If you want to read the data as strings, always use this method.

var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', (chunk) => {
  assert.equal(typeof chunk, 'string');
  console.log('got %d characters of string data', chunk.length);
});

readable.unpipe([destination])#

  • destination Writable Stream Optional specific stream to unpipe

This method will remove the hooks set up for a previous pipe() call.

If the destination is not specified, then all pipes are removed.

If the destination is specified, but no pipe is set up for it, then this is a no-op.

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt',
// but only for the first second
readable.pipe(writable);
setTimeout(() => {
  console.log('stop writing to file.txt');
  readable.unpipe(writable);
  console.log('manually close the file stream');
  writable.end();
}, 1000);

readable.unshift(chunk)#

  • chunk Buffer | String Chunk of data to unshift onto the read queue

This is useful in certain cases where a stream is being consumed by a parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party.

Note that stream.unshift(chunk) cannot be called after the 'end' event has been triggered; a runtime error will be raised.

If you find that you must often call stream.unshift(chunk) in your programs, consider implementing a Transform stream instead. (See API for Stream Implementors, below.)

// Pull off a header delimited by \n\n
// use unshift() if we get too much
// Call the callback with (error, header, stream)
const StringDecoder = require('string_decoder').StringDecoder;
function parseHeader(stream, callback) {
  stream.on('error', callback);
  stream.on('readable', onReadable);
  var decoder = new StringDecoder('utf8');
  var header = '';
  function onReadable() {
    var chunk;
    while (null !== (chunk = stream.read())) {
      var str = decoder.write(chunk);
      if (str.match(/\n\n/)) {
        // found the header boundary
        var split = str.split(/\n\n/);
        header += split.shift();
        var remaining = split.join('\n\n');
        var buf = new Buffer(remaining, 'utf8');
        if (buf.length)
          stream.unshift(buf);
        stream.removeListener('error', callback);
        stream.removeListener('readable', onReadable);
        // now the body of the message can be read from the stream.
        callback(null, header, stream);
      } else {
        // still reading the header.
        header += str;
      }
    }
  }
}

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not end the reading process by resetting the internal reading state of the stream. This can cause unexpected results if unshift is called during a read (i.e. from within a _read implementation on a custom stream). Following the call to unshift with an immediate stream.push('') will reset the reading state appropriately, however it is best to simply avoid calling unshift while in the process of performing a read.

readable.wrap(stream)#

  • stream Stream An "old style" readable stream

Versions of Node.js prior to v0.10 had streams that did not implement the entire Streams API as it is today. (See "Compatibility" below for more information.)

If you are using an older Node.js library that emits 'data' events and has a pause() method that is advisory only, then you can use the wrap() method to create a Readable stream that uses the old stream as its data source.

You will very rarely ever need to call this function, but it exists as a convenience for interacting with old Node.js programs and libraries.

For example:

const OldReader = require('./old-api-module.js').OldReader;
const Readable = require('stream').Readable;
const oreader = new OldReader;
const myReader = new Readable().wrap(oreader);

myReader.on('readable', () => {
  myReader.read(); // etc.
});

Class: stream.Transform#

Transform streams are Duplex streams where the output is in some way computed from the input. They implement both the Readable and Writable interfaces. See above for usage.

Examples of Transform streams include:

Class: stream.Writable#

The Writable stream interface is an abstraction for a destination that you are writing data to.

Examples of writable streams include:

Event: 'drain'#

If a writable.write(chunk) call returns false, then the 'drain' event will indicate when it is appropriate to begin writing more data to the stream.

// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
  var i = 1000000;
  write();
  function write() {
    var ok = true;
    do {
      i -= 1;
      if (i === 0) {
        // last time!
        writer.write(data, encoding, callback);
      } else {
        // see if we should continue, or wait
        // don't pass the callback, because we're not done yet.
        ok = writer.write(data, encoding);
      }
    } while (i > 0 && ok);
    if (i > 0) {
      // had to stop early!
      // write some more once it drains
      writer.once('drain', write);
    }
  }
}

Event: 'error'#

  • Error object

Emitted if there was an error when writing or piping data.

Event: 'finish'#

When the end() method has been called, and all data has been flushed to the underlying system, this event is emitted.

var writer = getWritableStreamSomehow();
for (var i = 0; i < 100; i ++) {
  writer.write('hello, #${i}!\n');
}
writer.end('this is the end\n');
writer.on('finish', () => {
  console.error('all writes are now complete.');
});

Event: 'pipe'#

  • src Readable Stream source stream that is piping to this writable

This is emitted whenever the pipe() method is called on a readable stream, adding this writable to its set of destinations.

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('pipe', (src) => {
  console.error('something is piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);

Event: 'unpipe'#

This is emitted whenever the unpipe() method is called on a readable stream, removing this writable from its set of destinations.

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('unpipe', (src) => {
  console.error('something has stopped piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);
reader.unpipe(writer);

writable.cork()#

Forces buffering of all writes.

Buffered data will be flushed either at .uncork() or at .end() call.

writable.end([chunk][, encoding][, callback])#

  • chunk String | Buffer Optional data to write
  • encoding String The encoding, if chunk is a String
  • callback Function Optional callback for when the stream is finished

Call this method when no more data will be written to the stream. If supplied, the callback is attached as a listener on the 'finish' event.

Calling write() after calling end() will raise an error.

// write 'hello, ' and then end with 'world!'
var file = fs.createWriteStream('example.txt');
file.write('hello, ');
file.end('world!');
// writing more now is not allowed!

writable.setDefaultEncoding(encoding)#

  • encoding String The new default encoding

Sets the default encoding for a writable stream.

writable.uncork()#

Flush all data, buffered since .cork() call.

writable.write(chunk[, encoding][, callback])#

  • chunk String | Buffer The data to write
  • encoding String The encoding, if chunk is a String
  • callback Function Callback for when this chunk of data is flushed
  • Returns: Boolean True if the data was handled completely.

This method writes some data to the underlying system, and calls the supplied callback once the data has been fully handled.

The return value indicates if you should continue writing right now. If the data had to be buffered internally, then it will return false. Otherwise, it will return true.

This return value is strictly advisory. You MAY continue to write, even if it returns false. However, writes will be buffered in memory, so it is best not to do this excessively. Instead, wait for the 'drain' event before writing more data.

API for Stream Implementors#

To implement any sort of stream, the pattern is the same:

  1. Extend the appropriate parent class in your own subclass. (The util.inherits method is particularly helpful for this.)
  2. Call the appropriate parent class constructor in your constructor, to be sure that the internal mechanisms are set up properly.
  3. Implement one or more specific methods, as detailed below.

The class to extend and the method(s) to implement depend on the sort of stream class you are writing:

Use-case

Class

Method(s) to implement

Reading only

Readable

_read

Writing only

Writable

_write, _writev

Reading and writing

Duplex

_read, _write, _writev

Operate on written data, then read the result

Transform

_transform, _flush

In your implementation code, it is very important to never call the methods described in API for Stream Consumers above. Otherwise, you can potentially cause adverse side effects in programs that consume your streaming interfaces.

Class: stream.Duplex#

A "duplex" stream is one that is both Readable and Writable, such as a TCP socket connection.

Note that stream.Duplex is an abstract class designed to be extended with an underlying implementation of the _read(size) and _write(chunk, encoding, callback) methods as you would with a Readable or Writable stream class.

Since JavaScript doesn't have multiple prototypal inheritance, this class prototypally inherits from Readable, and then parasitically from Writable. It is thus up to the user to implement both the lowlevel _read(n) method as well as the lowlevel _write(chunk, encoding, callback) method on extension duplex classes.

new stream.Duplex(options)#

  • options Object Passed to both Writable and Readable constructors. Also has the following fields:
    • allowHalfOpen Boolean Default=true. If set to false, then the stream will automatically end the readable side when the writable side ends and vice versa.
    • readableObjectMode Boolean Default=false. Sets objectMode for readable side of the stream. Has no effect if objectMode is true.
    • writableObjectMode Boolean Default=false. Sets objectMode for writable side of the stream. Has no effect if objectMode is true.

In classes that extend the Duplex class, make sure to call the constructor so that the buffering settings can be properly initialized.

Class: stream.PassThrough#

This is a trivial implementation of a Transform stream that simply passes the input bytes across to the output. Its purpose is mainly for examples and testing, but there are occasionally use cases where it can come in handy as a building block for novel sorts of streams.

Class: stream.Readable#

stream.Readable is an abstract class designed to be extended with an underlying implementation of the _read(size) method.

Please see above under API for Stream Consumers for how to consume streams in your programs. What follows is an explanation of how to implement Readable streams in your programs.

new stream.Readable(options)#

  • options Object
    • highWaterMark Number The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for objectMode streams
    • encoding String If specified, then buffers will be decoded to strings using the specified encoding. Default=null
    • objectMode Boolean Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false

In classes that extend the Readable class, make sure to call the Readable constructor so that the buffering settings can be properly initialized.

readable._read(size)#

  • size Number Number of bytes to read asynchronously

Note: Implement this method, but do NOT call it directly.

This method is prefixed with an underscore because it is internal to the class that defines it and should only be called by the internal Readable class methods. All Readable stream implementations must provide a _read method to fetch data from the underlying resource.

When _read is called, if data is available from the resource, _read should start pushing that data into the read queue by calling this.push(dataChunk). _read should continue reading from the resource and pushing data until push returns false, at which point it should stop reading from the resource. Only when _read is called again after it has stopped should it start reading more data from the resource and pushing that data onto the queue.

Note: once the _read() method is called, it will not be called again until the push method is called.

The size argument is advisory. Implementations where a "read" is a single call that returns data can use this to know how much data to fetch. Implementations where that is not relevant, such as TCP or TLS, may ignore this argument, and simply provide data whenever it becomes available. There is no need, for example to "wait" until size bytes are available before calling stream.push(chunk).

readable.push(chunk[, encoding])#

  • chunk Buffer | null | String Chunk of data to push into the read queue
  • encoding String Encoding of String chunks. Must be a valid Buffer encoding, such as 'utf8' or 'ascii'
  • return Boolean Whether or not more pushes should be performed

Note: This method should be called by Readable implementors, NOT by consumers of Readable streams.

If a value other than null is passed, The push() method adds a chunk of data into the queue for subsequent stream processors to consume. If null is passed, it signals the end of the stream (EOF), after which no more data can be written.

The data added with push can be pulled out by calling the read() method when the 'readable' event fires.

This API is designed to be as flexible as possible. For example, you may be wrapping a lower-level source which has some sort of pause/resume mechanism, and a data callback. In those cases, you could wrap the low-level source object by doing something like this:

// source is an object with readStop() and readStart() methods,
// and an `ondata` member that gets called when it has data, and
// an `onend` member that gets called when the data is over.

util.inherits(SourceWrapper, Readable);

function SourceWrapper(options) {
  Readable.call(this, options);

  this._source = getLowlevelSourceObject();
  var self = this;

  // Every time there's data, we push it into the internal buffer.
  this._source.ondata = function(chunk) {
    // if push() returns false, then we need to stop reading from source
    if (!self.push(chunk))
      self._source.readStop();
  };

  // When the source ends, we push the EOF-signaling `null` chunk
  this._source.onend = function() {
    self.push(null);
  };
}

// _read will be called when the stream wants to pull more data in
// the advisory size argument is ignored in this case.
SourceWrapper.prototype._read = function(size) {
  this._source.readStart();
};

Example: A Counting Stream#

This is a basic example of a Readable stream. It emits the numerals from 1 to 1,000,000 in ascending order, and then ends.

const Readable = require('stream').Readable;
const util = require('util');
util.inherits(Counter, Readable);

function Counter(opt) {
  Readable.call(this, opt);
  this._max = 1000000;
  this._index = 1;
}

Counter.prototype._read = function() {
  var i = this._index++;
  if (i > this._max)
    this.push(null);
  else {
    var str = '' + i;
    var buf = new Buffer(str, 'ascii');
    this.push(buf);
  }
};

Example: SimpleProtocol v1 (Sub-optimal)#

This is similar to the parseHeader function described above, but implemented as a custom stream. Also, note that this implementation does not convert the incoming data to a string.

However, this would be better implemented as a Transform stream. See below for a better implementation.

// A parser for a simple data protocol.
// The "header" is a JSON object, followed by 2 \n characters, and
// then a message body.
//
// NOTE: This can be done more simply as a Transform stream!
// Using Readable directly for this is sub-optimal.  See the
// alternative example below under the Transform section.

const Readable = require('stream').Readable;
const util = require('util');

util.inherits(SimpleProtocol, Readable);

function SimpleProtocol(source, options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(source, options);

  Readable.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;

  // source is a readable stream, such as a socket or file
  this._source = source;

  var self = this;
  source.on('end', () => {
    self.push(null);
  });

  // give it a kick whenever the source is readable
  // read(0) will not consume any bytes
  source.on('readable', () => {
    self.read(0);
  });

  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._read = function(n) {
  if (!this._inBody) {
    var chunk = this._source.read();

    // if the source doesn't have data, we don't have data yet.
    if (chunk === null)
      return this.push('');

    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
      this.push('');
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // now, because we got some extra data, unshift the rest
      // back into the read queue so that our consumer will see it.
      var b = chunk.slice(split);
      this.unshift(b);
      // calling unshift by itself does not reset the reading state
      // of the stream; since we're inside _read, doing an additional
      // push('') will reset the state appropriately.
      this.push('');

      // and let them know that we are done parsing the header.
      this.emit('header', this.header);
    }
  } else {
    // from there on, just provide the data to our consumer.
    // careful not to push(null), since that would indicate EOF.
    var chunk = this._source.read();
    if (chunk) this.push(chunk);
  }
};

// Usage:
// var parser = new SimpleProtocol(source);
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

Class: stream.Transform#

A "transform" stream is a duplex stream where the output is causally connected in some way to the input, such as a zlib stream or a crypto stream.

There is no requirement that the output be the same size as the input, the same number of chunks, or arrive at the same time. For example, a Hash stream will only ever have a single chunk of output which is provided when the input is ended. A zlib stream will produce output that is either much smaller or much larger than its input.

Rather than implement the _read() and _write() methods, Transform classes must implement the _transform() method, and may optionally also implement the _flush() method. (See below.)

new stream.Transform(options)#

  • options Object Passed to both Writable and Readable constructors.

In classes that extend the Transform class, make sure to call the constructor so that the buffering settings can be properly initialized.

Events: 'finish' and 'end'#

The 'finish' and 'end' events are from the parent Writable and Readable classes respectively. The 'finish' event is fired after .end() is called and all chunks have been processed by _transform, end is fired after all data has been output which is after the callback in _flush has been called.

transform._flush(callback)#

  • callback Function Call this function (optionally with an error argument) when you are done flushing any remaining data.

Note: This function MUST NOT be called directly. It MAY be implemented by child classes, and if so, will be called by the internal Transform class methods only.

In some cases, your transform operation may need to emit a bit more data at the end of the stream. For example, a Zlib compression stream will store up some internal state so that it can optimally compress the output. At the end, however, it needs to do the best it can with what is left, so that the data will be complete.

In those cases, you can implement a _flush method, which will be called at the very end, after all the written data is consumed, but before emitting end to signal the end of the readable side. Just like with _transform, call transform.push(chunk) zero or more times, as appropriate, and call callback when the flush operation is complete.

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

transform._transform(chunk, encoding, callback)#

  • chunk Buffer | String The chunk to be transformed. Will always be a buffer unless the decodeStrings option was set to false.
  • encoding String If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case.
  • callback Function Call this function (optionally with an error argument and data) when you are done processing the supplied chunk.

Note: This function MUST NOT be called directly. It should be implemented by child classes, and called by the internal Transform class methods only.

All Transform stream implementations must provide a _transform method to accept input and produce output.

_transform should do whatever has to be done in this specific Transform class, to handle the bytes being written, and pass them off to the readable portion of the interface. Do asynchronous I/O, process things, and so on.

Call transform.push(outputChunk) 0 or more times to generate output from this input chunk, depending on how much data you want to output as a result of this chunk.

Call the callback function only when the current chunk is completely consumed. Note that there may or may not be output as a result of any particular input chunk. If you supply a second argument to the callback it will be passed to the push method. In other words the following are equivalent:

transform.prototype._transform = function (data, encoding, callback) {
  this.push(data);
  callback();
};

transform.prototype._transform = function (data, encoding, callback) {
  callback(null, data);
};

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

Example: SimpleProtocol parser v2#

The example above of a simple protocol parser can be implemented simply by using the higher level Transform stream class, similar to the parseHeader and SimpleProtocol v1 examples above.

In this example, rather than providing the input as an argument, it would be piped into the parser, which is a more idiomatic Node.js stream approach.

const util = require('util');
const Transform = require('stream').Transform;
util.inherits(SimpleProtocol, Transform);

function SimpleProtocol(options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(options);

  Transform.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;
  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
  if (!this._inBody) {
    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // and let them know that we are done parsing the header.
      this.emit('header', this.header);

      // now, because we got some extra data, emit this first.
      this.push(chunk.slice(split));
    }
  } else {
    // from there on, just provide the data to our consumer as-is.
    this.push(chunk);
  }
  done();
};

// Usage:
// var parser = new SimpleProtocol();
// source.pipe(parser)
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

Class: stream.Writable#

stream.Writable is an abstract class designed to be extended with an underlying implementation of the _write(chunk, encoding, callback) method.

Please see above under API for Stream Consumers for how to consume writable streams in your programs. What follows is an explanation of how to implement Writable streams in your programs.

new stream.Writable(options)#

  • options Object
    • highWaterMark Number Buffer level when write() starts returning false. Default=16kb, or 16 for objectMode streams
    • decodeStrings Boolean Whether or not to decode strings into Buffers before passing them to _write(). Default=true
    • objectMode Boolean Whether or not the write(anyObj) is a valid operation. If set you can write arbitrary data instead of only Buffer / String data. Default=false

In classes that extend the Writable class, make sure to call the constructor so that the buffering settings can be properly initialized.

writable._write(chunk, encoding, callback)#

  • chunk Buffer | String The chunk to be written. Will always be a buffer unless the decodeStrings option was set to false.
  • encoding String If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case.
  • callback Function Call this function (optionally with an error argument) when you are done processing the supplied chunk.

All Writable stream implementations must provide a _write() method to send data to the underlying resource.

Note: This function MUST NOT be called directly. It should be implemented by child classes, and called by the internal Writable class methods only.

Call the callback using the standard callback(error) pattern to signal that the write completed successfully or with an error.

If the decodeStrings flag is set in the constructor options, then chunk may be a string rather than a Buffer, and encoding will indicate the sort of string that it is. This is to support implementations that have an optimized handling for certain string data encodings. If you do not explicitly set the decodeStrings option to false, then you can safely ignore the encoding argument, and assume that chunk will always be a Buffer.

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

writable._writev(chunks, callback)#

  • chunks Array The chunks to be written. Each chunk has following format: { chunk: ..., encoding: ... }.
  • callback Function Call this function (optionally with an error argument) when you are done processing the supplied chunks.

Note: This function MUST NOT be called directly. It may be implemented by child classes, and called by the internal Writable class methods only.

This function is completely optional to implement. In most cases it is unnecessary. If implemented, it will be called with all the chunks that are buffered in the write queue.

Simplified Constructor API#

In simple cases there is now the added benefit of being able to construct a stream without inheritance.

This can be done by passing the appropriate methods as constructor options:

Examples:

Duplex#

var duplex = new stream.Duplex({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  },
  write: function(chunk, encoding, next) {
    // sets this._write under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

// or

var duplex = new stream.Duplex({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  },
  writev: function(chunks, next) {
    // sets this._writev under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

Readable#

var readable = new stream.Readable({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  }
});

Transform#

var transform = new stream.Transform({
  transform: function(chunk, encoding, next) {
    // sets this._transform under the hood

    // generate output as many times as needed
    // this.push(chunk);

    // call when the current chunk is consumed
    next();
  },
  flush: function(done) {
    // sets this._flush under the hood

    // generate output as many times as needed
    // this.push(chunk);

    done();
  }
});

Writable#

var writable = new stream.Writable({
  write: function(chunk, encoding, next) {
    // sets this._write under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

// or

var writable = new stream.Writable({
  writev: function(chunks, next) {
    // sets this._writev under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

Streams: Under the Hood#

Buffering#

Both Writable and Readable streams will buffer data on an internal object which can be retrieved from _writableState.getBuffer() or _readableState.buffer, respectively.

The amount of data that will potentially be buffered depends on the highWaterMark option which is passed into the constructor.

Buffering in Readable streams happens when the implementation calls stream.push(chunk). If the consumer of the Stream does not call stream.read(), then the data will sit in the internal queue until it is consumed.

Buffering in Writable streams happens when the user calls stream.write(chunk) repeatedly, even when write() returns false.

The purpose of streams, especially with the pipe() method, is to limit the buffering of data to acceptable levels, so that sources and destinations of varying speed will not overwhelm the available memory.

Compatibility with Older Node.js Versions#

In versions of Node.js prior to v0.10, the Readable stream interface was simpler, but also less powerful and less useful.

  • Rather than waiting for you to call the read() method, 'data' events would start emitting immediately. If you needed to do some I/O to decide how to handle data, then you had to store the chunks in some kind of buffer so that they would not be lost.
  • The pause() method was advisory, rather than guaranteed. This meant that you still had to be prepared to receive 'data' events even when the stream was in a paused state.

In Node.js v0.10, the Readable class described below was added. For backwards compatibility with older Node.js programs, Readable streams switch into "flowing mode" when a 'data' event handler is added, or when the resume() method is called. The effect is that, even if you are not using the new read() method and 'readable' event, you no longer have to worry about losing 'data' chunks.

Most programs will continue to function normally. However, this introduces an edge case in the following conditions:

  • No 'data' event handler is added.
  • The resume() method is never called.
  • The stream is not piped to any writable destination.

For example, consider the following code:

// WARNING!  BROKEN!
net.createServer((socket) => {

  // we add an 'end' method, but never consume the data
  socket.on('end', () => {
    // It will never get here.
    socket.end('I got your message (but didnt read it)\n');
  });

}).listen(1337);

In versions of Node.js prior to v0.10, the incoming message data would be simply discarded. However, in Node.js v0.10 and beyond, the socket will remain paused forever.

The workaround in this situation is to call the resume() method to start the flow of data:

// Workaround
net.createServer((socket) => {

  socket.on('end', () => {
    socket.end('I got your message (but didnt read it)\n');
  });

  // start the flow of data, discarding it.
  socket.resume();

}).listen(1337);

In addition to new Readable streams switching into flowing mode, pre-v0.10 style streams can be wrapped in a Readable class using the wrap() method.

Object Mode#

Normally, Streams operate on Strings and Buffers exclusively.

Streams that are in object mode can emit generic JavaScript values other than Buffers and Strings.

A Readable stream in object mode will always return a single item from a call to stream.read(size), regardless of what the size argument is.

A Writable stream in object mode will always ignore the encoding argument to stream.write(data, encoding).

The special value null still retains its special value for object mode streams. That is, for object mode readable streams, null as a return value from stream.read() indicates that there is no more data, and stream.push(null) will signal the end of stream data (EOF).

No streams in Node.js core are object mode streams. This pattern is only used by userland streaming libraries.

You should set objectMode in your stream child class constructor on the options object. Setting objectMode mid-stream is not safe.

For Duplex streams objectMode can be set exclusively for readable or writable side with readableObjectMode and writableObjectMode respectively. These options can be used to implement parsers and serializers with Transform streams.

const util = require('util');
const StringDecoder = require('string_decoder').StringDecoder;
const Transform = require('stream').Transform;
util.inherits(JSONParseStream, Transform);

// Gets \n-delimited JSON string data, and emits the parsed objects
function JSONParseStream() {
  if (!(this instanceof JSONParseStream))
    return new JSONParseStream();

  Transform.call(this, { readableObjectMode : true });

  this._buffer = '';
  this._decoder = new StringDecoder('utf8');
}

JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
  this._buffer += this._decoder.write(chunk);
  // split on newlines
  var lines = this._buffer.split(/\r?\n/);
  // keep the last partial line buffered
  this._buffer = lines.pop();
  for (var l = 0; l < lines.length; l++) {
    var line = lines[l];
    try {
      var obj = JSON.parse(line);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

JSONParseStream.prototype._flush = function(cb) {
  // Just handle any leftover
  var rem = this._buffer.trim();
  if (rem) {
    try {
      var obj = JSON.parse(rem);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

stream.read(0)#

There are some cases where you want to trigger a refresh of the underlying readable stream mechanisms, without actually consuming any data. In that case, you can call stream.read(0), which will always return null.

If the internal read buffer is below the highWaterMark, and the stream is not currently reading, then calling read(0) will trigger a low-level _read call.

There is almost never a need to do this. However, you will see some cases in Node.js's internals where this is done, particularly in the Readable stream class internals.

stream.push('')#

Pushing a zero-byte string or Buffer (when not in Object mode) has an interesting side effect. Because it is a call to stream.push(), it will end the reading process. However, it does not add any data to the readable buffer, so there's nothing for a user to consume.

Very rarely, there are cases where you have no data to provide now, but the consumer of your stream (or, perhaps, another bit of your own code) will know when to check again, by calling stream.read(0). In those cases, you may call stream.push('').

So far, the only use case for this functionality is in the tls.CryptoStream class, which is deprecated in Node.js/io.js v1.0. If you find that you have to use stream.push(''), please consider another approach, because it almost certainly indicates that something is horribly wrong.

StringDecoder#

Stability: 2 - Stable

To use this module, do require('string_decoder'). StringDecoder decodes a buffer to a string. It is a simple interface to buffer.toString() but provides additional support for utf8.

const StringDecoder = require('string_decoder').StringDecoder;
const decoder = new StringDecoder('utf8');

const cent = new Buffer([0xC2, 0xA2]);
console.log(decoder.write(cent));

const euro = new Buffer([0xE2, 0x82, 0xAC]);
console.log(decoder.write(euro));

Class: StringDecoder#

Accepts a single argument, encoding which defaults to 'utf8'.

decoder.end()#

Returns any trailing bytes that were left in the buffer.

decoder.write(buffer)#

Returns a decoded string.

Timers#

Stability: 3 - Locked

All of the timer functions are globals. You do not need to require() this module in order to use them.

clearImmediate(immediateObject)#

Stops an immediate from triggering.

clearInterval(intervalObject)#

Stops an interval from triggering.

clearTimeout(timeoutObject)#

Prevents a timeout from triggering.

ref()#

If you had previously unref()d a timer you can call ref() to explicitly request the timer hold the program open. If the timer is already refd calling ref again will have no effect.

Returns the timer.

setImmediate(callback[, arg][, ...])#

To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout and setInterval. Returns an immediateObject for possible use with clearImmediate(). Optionally you can also pass arguments to the callback.

Callbacks for immediates are queued in the order in which they were created. The entire callback queue is processed every event loop iteration. If you queue an immediate from inside an executing callback, that immediate won't fire until the next event loop iteration.

setInterval(callback, delay[, arg][, ...])#

To schedule the repeated execution of callback every delay milliseconds. Returns a intervalObject for possible use with clearInterval(). Optionally you can also pass arguments to the callback.

To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the delay.

setTimeout(callback, delay[, arg][, ...])#

To schedule execution of a one-time callback after delay milliseconds. Returns a timeoutObject for possible use with clearTimeout(). Optionally you can also pass arguments to the callback.

It is important to note that your callback will probably not be called in exactly delay milliseconds - Node.js makes no guarantees about the exact timing of when the callback will fire, nor of the ordering things will fire in. The callback will be called as close as possible to the time specified.

To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, the timeout is executed immediately, as if the delay was set to 1.

unref()#

The opaque value returned by setTimeout and setInterval also has the method timer.unref() which will allow you to create a timer that is active but if it is the only item left in the event loop, it won't keep the program running. If the timer is already unrefd calling unref again will have no effect.

In the case of setTimeout when you unref you create a separate timer that will wakeup the event loop, creating too many of these may adversely effect event loop performance -- use wisely.

Returns the timer.

TLS (SSL)#

Stability: 2 - Stable

Use require('tls') to access this module.

The tls module uses OpenSSL to provide Transport Layer Security and/or Secure Socket Layer: encrypted stream communication.

TLS/SSL is a public/private key infrastructure. Each client and each server must have a private key. A private key is created like this:

openssl genrsa -out ryans-key.pem 2048

All servers and some clients need to have a certificate. Certificates are public keys signed by a Certificate Authority or self-signed. The first step to getting a certificate is to create a "Certificate Signing Request" (CSR) file. This is done with:

openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem

To create a self-signed certificate with the CSR, do this:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

Alternatively you can send the CSR to a Certificate Authority for signing.

For Perfect Forward Secrecy, it is required to generate Diffie-Hellman parameters:

openssl dhparam -outform PEM -out dhparam.pem 2048

To create .pfx or .p12, do this:

openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
    -certfile ca-cert.pem -out agent5.pfx
  • in: certificate
  • inkey: private key
  • certfile: all CA certs concatenated in one file like cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

Client-initiated renegotiation attack mitigation#

The TLS protocol lets the client renegotiate certain aspects of the TLS session. Unfortunately, session renegotiation requires a disproportional amount of server-side resources, which makes it a potential vector for denial-of-service attacks.

To mitigate this, renegotiations are limited to three times every 10 minutes. An error is emitted on the tls.TLSSocket instance when the threshold is exceeded. The limits are configurable:

  • tls.CLIENT_RENEG_LIMIT: renegotiation limit, default is 3.

  • tls.CLIENT_RENEG_WINDOW: renegotiation window in seconds, default is 10 minutes.

Don't change the defaults unless you know what you are doing.

To test your server, connect to it with openssl s_client -connect address:port and tap R<CR> (that's the letter R followed by a carriage return) a few times.

Modifying the Default TLS Cipher suite#

Node.js is built with a default suite of enabled and disabled TLS ciphers. Currently, the default cipher suite is:

ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-AES256-GCM-SHA384:
DHE-RSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:
DHE-RSA-AES128-SHA256:
ECDHE-RSA-AES256-SHA384:
DHE-RSA-AES256-SHA384:
ECDHE-RSA-AES256-SHA256:
DHE-RSA-AES256-SHA256:
HIGH:
!aNULL:
!eNULL:
!EXPORT:
!DES:
!RC4:
!MD5:
!PSK:
!SRP:
!CAMELLIA

This default can be overriden entirely using the --tls-cipher-list command line switch. For instance, the following makes ECDHE-RSA-AES128-GCM-SHA256:!RC4 the default TLS cipher suite:

node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"

Note that the default cipher suite included within Node.js has been carefully selected to reflect current security best practices and risk mitigation. Changing the default cipher suite can have a significant impact on the security of an application. The --tls-cipher-list switch should by used only if absolutely necessary.

NPN and SNI#

NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS handshake extensions allowing you:

  • NPN - to use one TLS server for multiple protocols (HTTP, SPDY)
  • SNI - to use one TLS server for multiple hostnames with different SSL certificates.

Perfect Forward Secrecy#

The term "Forward Secrecy" or "Perfect Forward Secrecy" describes a feature of key-agreement (i.e. key-exchange) methods. Practically it means that even if the private key of a (your) server is compromised, communication can only be decrypted by eavesdroppers if they manage to obtain the key-pair specifically generated for each session.

This is achieved by randomly generating a key pair for key-agreement on every handshake (in contrary to the same key for all sessions). Methods implementing this technique, thus offering Perfect Forward Secrecy, are called "ephemeral".

Currently two methods are commonly used to achieve Perfect Forward Secrecy (note the character "E" appended to the traditional abbreviations):

  • DHE - An ephemeral version of the Diffie Hellman key-agreement protocol.
  • ECDHE - An ephemeral version of the Elliptic Curve Diffie Hellman key-agreement protocol.

Ephemeral methods may have some performance drawbacks, because key generation is expensive.

Class: CryptoStream#

Stability: 0 - Deprecated: Use tls.TLSSocket instead.

This is an encrypted stream.

cryptoStream.bytesWritten#

A proxy to the underlying socket's bytesWritten accessor, this will return the total bytes written to the socket, including the TLS overhead.

Class: SecurePair#

Returned by tls.createSecurePair.

Event: 'secure'#

The event is emitted from the SecurePair once the pair has successfully established a secure connection.

Similarly to the checking for the server 'secureConnection' event, pair.cleartext.authorized should be checked to confirm whether the certificate used properly authorized.

Class: tls.Server#

This class is a subclass of net.Server and has the same methods on it. Instead of accepting just raw TCP connections, this accepts encrypted connections using TLS or SSL.

Event: 'clientError'#

function (exception, tlsSocket) { }

When a client connection emits an 'error' event before secure connection is established - it will be forwarded here.

tlsSocket is the tls.TLSSocket that the error originated from.

Event: 'newSession'#

function (sessionId, sessionData, callback) { }

Emitted on creation of TLS session. May be used to store sessions in external storage. callback must be invoked eventually, otherwise no data will be sent or received from secure connection.

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

Event: 'OCSPRequest'#

function (certificate, issuer, callback) { }

Emitted when the client sends a certificate status request. You could parse server's current certificate to obtain OCSP url and certificate id, and after obtaining OCSP response invoke callback(null, resp), where resp is a Buffer instance. Both certificate and issuer are a Buffer DER-representations of the primary and issuer's certificates. They could be used to obtain OCSP certificate id and OCSP endpoint url.

Alternatively, callback(null, null) could be called, meaning that there is no OCSP response.

Calling callback(err) will result in a socket.destroy(err) call.

Typical flow:

  1. Client connects to server and sends 'OCSPRequest' to it (via status info extension in ClientHello.)
  2. Server receives request and invokes 'OCSPRequest' event listener if present
  3. Server grabs OCSP url from either certificate or issuer and performs an OCSP request to the CA
  4. Server receives OCSPResponse from CA and sends it back to client via callback argument
  5. Client validates the response and either destroys socket or performs a handshake.

NOTE: issuer could be null, if the certificate is self-signed or if the issuer is not in the root certificates list. (You could provide an issuer via ca option.)

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

NOTE: you may want to use some npm module like asn1.js to parse the certificates.

Event: 'resumeSession'#

function (sessionId, callback) { }

Emitted when client wants to resume previous TLS session. Event listener may perform lookup in external storage using given sessionId, and invoke callback(null, sessionData) once finished. If session can't be resumed (i.e. doesn't exist in storage) one may call callback(null, null). Calling callback(err) will terminate incoming connection and destroy socket.

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

Here's an example for using TLS session resumption:

var tlsSessionStore = {};
server.on('newSession', (id, data, cb) => {
  tlsSessionStore[id.toString('hex')] = data;
  cb();
});
server.on('resumeSession', (id, cb) => {
  cb(null, tlsSessionStore[id.toString('hex')] || null);
});

Event: 'secureConnection'#

function (tlsSocket) {}

This event is emitted after a new connection has been successfully handshaked. The argument is an instance of tls.TLSSocket. It has all the common stream methods and events.

socket.authorized is a boolean value which indicates if the client has verified by one of the supplied certificate authorities for the server. If socket.authorized is false, then socket.authorizationError is set to describe how authorization failed. Implied but worth mentioning: depending on the settings of the TLS server, you unauthorized connections may be accepted. socket.npnProtocol is a string containing selected NPN protocol. socket.servername is a string containing servername requested with SNI.

server.addContext(hostname, context)#

Add secure context that will be used if client request's SNI hostname is matching passed hostname (wildcards can be used). context can contain key, cert, ca and/or any other properties from tls.createSecureContext options argument.

server.address()#

Returns the bound address, the address family name and port of the server as reported by the operating system. See net.Server.address() for more information.

server.close([callback])#

Stops the server from accepting new connections. This function is asynchronous, the server is finally closed when the server emits a 'close' event. Optionally, you can pass a callback to listen for the 'close' event.

server.connections#

The number of concurrent connections on the server.

server.getTicketKeys()#

Returns Buffer instance holding the keys currently used for encryption/decryption of the TLS Session Tickets

server.listen(port[, hostname][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

This function is asynchronous. The last parameter callback will be called when the server has been bound.

See net.Server for more information.

server.maxConnections#

Set this property to reject connections when the server's connection count gets high.

server.setTicketKeys(keys)#

Updates the keys for encryption/decryption of the TLS Session Tickets.

NOTE: the buffer should be 48 bytes long. See server ticketKeys option for more information oh how it is going to be used.

NOTE: the change is effective only for the future server connections. Existing or currently pending server connections will use previous keys.

Class: tls.TLSSocket#

This is a wrapped version of net.Socket that does transparent encryption of written data and all required TLS negotiation.

This instance implements a duplex Stream interfaces. It has all the common stream methods and events.

Methods that return TLS connection meta data (e.g. getPeerCertificate will only return data while the connection is open.

new tls.TLSSocket(socket[, options])#

Construct a new TLSSocket object from existing TCP socket.

socket is an instance of net.Socket

options is an optional object that might contain following properties:

  • secureContext: An optional TLS context object from tls.createSecureContext( ... )

  • isServer: If true - TLS socket will be instantiated in server-mode. Default: false

  • server: An optional net.Server instance

  • requestCert: Optional, see tls.createSecurePair

  • rejectUnauthorized: Optional, see tls.createSecurePair

  • NPNProtocols: Optional, see tls.createServer

  • SNICallback: Optional, see tls.createServer

  • session: Optional, a Buffer instance, containing TLS session

  • requestOCSP: Optional, if true - OCSP status request extension would be added to client hello, and 'OCSPResponse' event will be emitted on socket before establishing secure communication

Event: 'OCSPResponse'#

function (response) { }

This event will be emitted if requestOCSP option was set. response is a buffer object, containing server's OCSP response.

Traditionally, the response is a signed object from the server's CA that contains information about server's certificate revocation status.

Event: 'secureConnect'#

This event is emitted after a new connection has been successfully handshaked. The listener will be called no matter if the server's certificate was authorized or not. It is up to the user to test tlsSocket.authorized to see if the server certificate was signed by one of the specified CAs. If tlsSocket.authorized === false then the error can be found in tlsSocket.authorizationError. Also if NPN was used - you can check tlsSocket.npnProtocol for negotiated protocol.

tlsSocket.address()#

Returns the bound address, the address family name and port of the underlying socket as reported by the operating system. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.authorized#

A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false

tlsSocket.authorizationError#

The reason why the peer's certificate has not been verified. This property becomes available only when tlsSocket.authorized === false.

tlsSocket.encrypted#

Static boolean value, always true. May be used to distinguish TLS sockets from regular ones.

tlsSocket.getCipher()#

Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection.

Example: { name: 'AES256-SHA', version: 'TLSv1/SSLv3' }

See SSL_CIPHER_get_name() and SSL_CIPHER_get_version() in https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS for more information.

tlsSocket.getPeerCertificate([ detailed ])#

Returns an object representing the peer's certificate. The returned object has some properties corresponding to the field of the certificate. If detailed argument is true - the full chain with issuer property will be returned, if false - only the top certificate without issuer property.

Example:

{ subject:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuerInfo:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuer:
   { ... another certificate ... },
  raw: < RAW DER buffer >,
  valid_from: 'Nov 11 09:52:22 2009 GMT',
  valid_to: 'Nov  6 09:52:22 2029 GMT',
  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
  serialNumber: 'B9B0D332A1AA5635' }

If the peer does not provide a certificate, it returns null or an empty object.

tlsSocket.getSession()#

Return ASN.1 encoded TLS session or undefined if none was negotiated. Could be used to speed up handshake establishment when reconnecting to the server.

tlsSocket.getTLSTicket()#

NOTE: Works only with client TLS sockets. Useful only for debugging, for session reuse provide session option to tls.connect.

Return TLS session ticket or undefined if none was negotiated.

tlsSocket.localPort#

The numeric representation of the local port.

tlsSocket.localAddress#

The string representation of the local IP address.

tlsSocket.remoteAddress#

The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'.

tlsSocket.remoteFamily#

The string representation of the remote IP family. 'IPv4' or 'IPv6'.

tlsSocket.remotePort#

The numeric representation of the remote port. For example, 443.

tlsSocket.renegotiate(options, callback)#

Initiate TLS renegotiation process. The options may contain the following fields: rejectUnauthorized, requestCert (See tls.createServer for details). callback(err) will be executed with null as err, once the renegotiation is successfully completed.

NOTE: Can be used to request peer's certificate after the secure connection has been established.

ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout.

tlsSocket.setMaxSendFragment(size)#

Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). Returns true on success, false otherwise.

Smaller fragment size decreases buffering latency on the client: large fragments are buffered by the TLS layer until the entire fragment is received and its integrity is verified; large fragments can span multiple roundtrips, and their processing can be delayed due to packet loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, which may decrease overall server throughput.

tls.connect(options[, callback])#

tls.connect(port[, host][, options][, callback])#

Creates a new client connection to the given port and host (old API) or options.port and options.host. (If host is omitted, it defaults to localhost.) options should be an object which specifies:

  • host: Host the client should connect to

  • port: Port the client should connect to

  • socket: Establish secure connection on a given socket rather than creating a new socket. If this option is specified, host and port are ignored.

  • path: Creates unix socket connection to path. If this option is specified, host and port are ignored.

  • pfx: A string or Buffer containing the private key, certificate and CA certs of the client in PFX or PKCS12 format.

  • key: A string or Buffer containing the private key of the client in PEM format. (Could be an array of keys).

  • passphrase: A string of passphrase for the private key or pfx.

  • cert: A string or Buffer containing the certificate key of the client in PEM format. (Could be an array of certs).

  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

  • ciphers: A string describing the ciphers to use or exclude, separated by :. Uses the same default cipher suite as tls.createServer.

  • rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails; err.code contains the OpenSSL error code. Default: true.

  • NPNProtocols: An array of strings or Buffers containing supported NPN protocols. Buffers should have following format: 0x05hello0x05world, where first byte is next protocol name's length. (Passing array should usually be much simpler: ['hello', 'world'].)

  • servername: Servername for SNI (Server Name Indication) TLS extension.

  • checkServerIdentity(servername, cert): Provide an override for checking server's hostname against the certificate. Should return an error if verification fails. Return undefined if passing.

  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

  • session: A Buffer instance, containing TLS session.

The callback parameter will be added as a listener for the 'secureConnect' event.

tls.connect() returns a tls.TLSSocket object.

Here is an example of a client of echo server as described previously:

const tls = require('tls');
const fs = require('fs');

const options = {
  // These are necessary only if using the client certificate authentication
  key: fs.readFileSync('client-key.pem'),
  cert: fs.readFileSync('client-cert.pem'),

  // This is necessary only if the server uses the self-signed certificate
  ca: [ fs.readFileSync('server-cert.pem') ]
};

var socket = tls.connect(8000, options, () => {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
  console.log(data);
});
socket.on('end', () => {
  server.close();
});

Or

const tls = require('tls');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('client.pfx')
};

var socket = tls.connect(8000, options, () => {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
  console.log(data);
});
socket.on('end', () => {
  server.close();
});

tls.createSecureContext(details)#

Creates a credentials object, with the optional details being a dictionary with keys:

  • pfx : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
  • key: A string or Buffer containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format {pem: key, passphrase: passphrase}. (Required)
  • passphrase : A string of passphrase for the private key or pfx
  • cert : A string holding the PEM encoded certificate
  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.
  • honorCipherOrder : When choosing a cipher, use the server's preferences instead of the client preferences. For further details see tls module documentation.

If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.

tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])#

Creates a new secure pair object with two streams, one of which reads/writes encrypted data, and one reads/writes cleartext data. Generally the encrypted one is piped to/from an incoming encrypted data stream, and the cleartext one is used as a replacement for the initial encrypted stream.

  • credentials: A secure context object from tls.createSecureContext( ... )

  • isServer: A boolean indicating whether this tls connection should be opened as a server or a client.

  • requestCert: A boolean indicating whether a server should request a certificate from a connecting client. Only applies to server connections.

  • rejectUnauthorized: A boolean indicating whether a server should automatically reject clients with invalid certificates. Only applies to servers with requestCert enabled.

tls.createSecurePair() returns a SecurePair object with cleartext and encrypted stream properties.

NOTE: cleartext has the same APIs as tls.TLSSocket

tls.createServer(options[, secureConnectionListener])#

Creates a new tls.Server. The connectionListener argument is automatically set as a listener for the 'secureConnection' event. The options object has these possibilities:

  • pfx: A string or Buffer containing the private key, certificate and CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with the key, cert and ca options.)

  • key: A string or Buffer containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format {pem: key, passphrase: passphrase}. (Required)

  • passphrase: A string of passphrase for the private key or pfx.

  • cert: A string or Buffer containing the certificate key of the server in PEM format. (Could be an array of certs). (Required)

  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)

  • ciphers: A string describing the ciphers to use or exclude, separated by :. The default cipher suite is:

    ECDHE-RSA-AES128-GCM-SHA256:
    ECDHE-ECDSA-AES128-GCM-SHA256:
    ECDHE-RSA-AES256-GCM-SHA384:
    ECDHE-ECDSA-AES256-GCM-SHA384:
    DHE-RSA-AES128-GCM-SHA256:
    ECDHE-RSA-AES128-SHA256:
    DHE-RSA-AES128-SHA256:
    ECDHE-RSA-AES256-SHA384:
    DHE-RSA-AES256-SHA384:
    ECDHE-RSA-AES256-SHA256:
    DHE-RSA-AES256-SHA256:
    HIGH:
    !aNULL:
    !eNULL:
    !EXPORT:
    !DES:
    !RC4:
    !MD5:
    !PSK:
    !SRP:
    !CAMELLIA

    The default cipher suite prefers GCM ciphers for Chrome's 'modern cryptography' setting and also prefers ECDHE and DHE ciphers for Perfect Forward secrecy, while offering some backward compatibiltity.

    128 bit AES is preferred over 192 and 256 bit AES in light of specific attacks affecting larger AES key sizes.

    Old clients that rely on insecure and deprecated RC4 or DES-based ciphers (like Internet Explorer 6) aren't able to complete the handshake with the default configuration. If you absolutely must support these clients, the TLS recommendations may offer a compatible cipher suite. For more details on the format, see the OpenSSL cipher list format documentation.

  • ecdhCurve: A string describing a named curve to use for ECDH key agreement or false to disable ECDH.

    Defaults to prime256v1 (NIST P-256). Use crypto.getCurves() to obtain a list of available curve names. On recent releases, openssl ecparam -list_curves will also display the name and description of each available elliptic curve.

  • dhparam: A string or Buffer containing Diffie Hellman parameters, required for Perfect Forward Secrecy. Use openssl dhparam to create it. Its key length should be greater than or equal to 1024 bits, otherwise it throws an error. It is strongly recommended to use 2048 bits or more for stronger security. If omitted or invalid, it is silently discarded and DHE ciphers won't be available.

  • handshakeTimeout: Abort the connection if the SSL/TLS handshake does not finish in this many milliseconds. The default is 120 seconds.

    A 'clientError' is emitted on the tls.Server object whenever a handshake times out.

  • honorCipherOrder : When choosing a cipher, use the server's preferences instead of the client preferences. Default: true.

  • requestCert: If true the server will request a certificate from clients that connect and attempt to verify that certificate. Default: false.

  • rejectUnauthorized: If true the server will reject any connection which is not authorized with the list of supplied CAs. This option only has an effect if requestCert is true. Default: false.

  • NPNProtocols: An array or Buffer of possible NPN protocols. (Protocols should be ordered by their priority).

  • SNICallback(servername, cb): A function that will be called if client supports SNI TLS extension. Two argument will be passed to it: servername, and cb. SNICallback should invoke cb(null, ctx), where ctx is a SecureContext instance. (You can use tls.createSecureContext(...) to get proper SecureContext). If SNICallback wasn't provided - default callback with high-level API will be used (see below).

  • sessionTimeout: An integer specifying the seconds after which TLS session identifiers and TLS session tickets created by the server are timed out. See SSL_CTX_set_timeout for more details.

  • ticketKeys: A 48-byte Buffer instance consisting of 16-byte prefix, 16-byte hmac key, 16-byte AES key. You could use it to accept tls session tickets on multiple instances of tls server.

    NOTE: Automatically shared between cluster module workers.

  • sessionIdContext: A string containing an opaque identifier for session resumption. If requestCert is true, the default is MD5 hash value generated from command-line. (In FIPS mode a truncated SHA1 hash is used instead.) Otherwise, the default is not provided.

  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

Here is a simple example echo server:

const tls = require('tls');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

  // This is necessary only if the client uses the self-signed certificate.
  ca: [ fs.readFileSync('client-cert.pem') ]
};

var server = tls.createServer(options, (socket) => {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write('welcome!\n');
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, () => {
  console.log('server bound');
});

Or

const tls = require('tls');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('server.pfx'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

};

var server = tls.createServer(options, (socket) => {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write('welcome!\n');
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, () => {
  console.log('server bound');
});

You can test this server by connecting to it with openssl s_client:

openssl s_client -connect 127.0.0.1:8000

tls.getCiphers()#

Returns an array with the names of the supported SSL ciphers.

Example:

var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]

TTY#

Stability: 2 - Stable

The tty module houses the tty.ReadStream and tty.WriteStream classes. In most cases, you will not need to use this module directly.

When Node.js detects that it is being run inside a TTY context, then process.stdin will be a tty.ReadStream instance and process.stdout will be a tty.WriteStream instance. The preferred way to check if Node.js is being run in a TTY context is to check process.stdout.isTTY:

$ node -p -e "Boolean(process.stdout.isTTY)"
true
$ node -p -e "Boolean(process.stdout.isTTY)" | cat
false

Class: ReadStream#

A net.Socket subclass that represents the readable portion of a tty. In normal circumstances, process.stdin will be the only tty.ReadStream instance in any Node.js program (only when isatty(0) is true).

rs.isRaw#

A Boolean that is initialized to false. It represents the current "raw" state of the tty.ReadStream instance.

rs.setRawMode(mode)#

mode should be true or false. This sets the properties of the tty.ReadStream to act either as a raw device or default. isRaw will be set to the resulting mode.

Class: WriteStream#

A net.Socket subclass that represents the writable portion of a tty. In normal circumstances, process.stdout will be the only tty.WriteStream instance ever created (and only when isatty(1) is true).

Event: 'resize'#

function () {}

Emitted by refreshSize() when either of the columns or rows properties has changed.

process.stdout.on('resize', () => {
  console.log('screen size has changed!');
  console.log(`${process.stdout.columns}x${process.stdout.rows}`);
});

ws.columns#

A Number that gives the number of columns the TTY currently has. This property gets updated on 'resize' events.

ws.rows#

A Number that gives the number of rows the TTY currently has. This property gets updated on 'resize' events.

tty.isatty(fd)#

Returns true or false depending on if the fd is associated with a terminal.

tty.setRawMode(mode)#

Stability: 0 - Deprecated: Use tty.ReadStream#setRawMode (i.e. process.stdin.setRawMode) instead.

URL#

Stability: 2 - Stable

This module has utilities for URL resolution and parsing. Call require('url') to use it.

URL Parsing#

Parsed URL objects have some or all of the following fields, depending on whether or not they exist in the URL string. Any parts that are not in the URL string will not be in the parsed object. Examples are shown for the URL

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • href: The full URL that was originally parsed. Both the protocol and host are lowercased.

    Example: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • protocol: The request protocol, lowercased.

    Example: 'http:'

  • slashes: The protocol requires slashes after the colon.

    Example: true or false

  • host: The full lowercased host portion of the URL, including port information.

    Example: 'host.com:8080'

  • auth: The authentication information portion of a URL.

    Example: 'user:pass'

  • hostname: Just the lowercased hostname portion of the host.

    Example: 'host.com'

  • port: The port number portion of the host.

    Example: '8080'

  • pathname: The path section of the URL, that comes after the host and before the query, including the initial slash if present. No decoding is performed.

    Example: '/p/a/t/h'

  • search: The 'query string' portion of the URL, including the leading question mark.

    Example: '?query=string'

  • path: Concatenation of pathname and search. No decoding is performed.

    Example: '/p/a/t/h?query=string'

  • query: Either the 'params' portion of the query string, or a querystring-parsed object.

    Example: 'query=string' or {'query':'string'}

  • hash: The 'fragment' portion of the URL including the pound-sign.

    Example: '#hash'

Escaped Characters#

Spaces (' ') and the following characters will be automatically escaped in the properties of URL objects:

< > " ` \r \n \t { } | \ ^ '

The following methods are provided by the URL module:

url.format(urlObj)#

Take a parsed URL object, and return a formatted URL string.

Here's how the formatting process works:

  • href will be ignored.
  • path will be ignored.
  • protocol is treated the same with or without the trailing : (colon).
    • The protocols http, https, ftp, gopher, file will be postfixed with :// (colon-slash-slash) as long as host/hostname are present.
    • All other protocols mailto, xmpp, aim, sftp, foo, etc will be postfixed with : (colon).
  • slashes set to true if the protocol requires :// (colon-slash-slash)
    • Only needs to be set for protocols not previously listed as requiring slashes, such as mongodb://localhost:8000/, or if host/hostname are absent.
  • auth will be used if present.
  • hostname will only be used if host is absent.
  • port will only be used if host is absent.
  • host will be used in place of hostname and port.
  • pathname is treated the same with or without the leading / (slash).
  • query (object; see querystring) will only be used if search is absent.
  • search will be used in place of query.
    • It is treated the same with or without the leading ? (question mark).
  • hash is treated the same with or without the leading # (pound sign, anchor).

url.parse(urlStr[, parseQueryString][, slashesDenoteHost])#

Take a URL string, and return an object.

Pass true as the second argument to also parse the query string using the querystring module. If true then the query property will always be assigned an object, and the search property will always be a (possibly empty) string. If false then the query property will not be parsed or decoded. Defaults to false.

Pass true as the third argument to treat //foo/bar as { host: 'foo', pathname: '/bar' } rather than { pathname: '//foo/bar' }. Defaults to false.

url.resolve(from, to)#

Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. Examples:

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

util#

Stability: 2 - Stable

These functions are in the module 'util'. Use require('util') to access them.

The util module is primarily designed to support the needs of Node.js's internal APIs. Many of these utilities are useful for your own programs. If you find that these functions are lacking for your purposes, however, you are encouraged to write your own utilities. We are not interested in any future additions to the util module that are unnecessary for Node.js's internal functionality.

util.debug(string)#

Stability: 0 - Deprecated: use console.error() instead.

Deprecated predecessor of console.error.

util.debuglog(section)#

  • section String The section of the program to be debugged
  • Returns: Function The logging function

This is used to create a function which conditionally writes to stderr based on the existence of a NODE_DEBUG environment variable. If the section name appears in that environment variable, then the returned function will be similar to console.error(). If not, then the returned function is a no-op.

For example:

var debuglog = util.debuglog('foo');

var bar = 123;
debuglog('hello from foo [%d]', bar);

If this program is run with NODE_DEBUG=foo in the environment, then it will output something like:

FOO 3245: hello from foo [123]

where 3245 is the process id. If it is not run with that environment variable set, then it will not print anything.

You may separate multiple NODE_DEBUG environment variables with a comma. For example, NODE_DEBUG=fs,net,tls.

util.deprecate(function, string)#

Marks that a method should not be used any more.

const util = require('util');

exports.puts = util.deprecate(function() {
  for (var i = 0, len = arguments.length; i < len; ++i) {
    process.stdout.write(arguments[i] + '\n');
  }
}, 'util.puts: Use console.log instead');

It returns a modified function which warns once by default.

If --no-deprecation is set then this function is a NO-OP. Configurable at run-time through the process.noDeprecation boolean (only effective when set before a module is loaded.)

If --trace-deprecation is set, a warning and a stack trace are logged to the console the first time the deprecated API is used. Configurable at run-time through the process.traceDeprecation boolean.

If --throw-deprecation is set then the application throws an exception when the deprecated API is used. Configurable at run-time through the process.throwDeprecation boolean.

process.throwDeprecation takes precedence over process.traceDeprecation.

util.error([...])#

Stability: 0 - Deprecated: Use console.error() instead.

Deprecated predecessor of console.error.

util.format(format[, ...])#

Returns a formatted string using the first argument as a printf-like format.

The first argument is a string that contains zero or more placeholders. Each placeholder is replaced with the converted value from its corresponding argument. Supported placeholders are:

  • %s - String.
  • %d - Number (both integer and float).
  • %j - JSON. Replaced with the string '[Circular]' if the argument contains circular references.
  • %% - single percent sign ('%'). This does not consume an argument.

If the placeholder does not have a corresponding argument, the placeholder is not replaced.

util.format('%s:%s', 'foo'); // 'foo:%s'

If there are more arguments than placeholders, the extra arguments are coerced to strings (for objects and symbols, util.inspect() is used) and then concatenated, delimited by a space.

util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'

If the first argument is not a format string then util.format() returns a string that is the concatenation of all its arguments separated by spaces. Each argument is converted to a string with util.inspect().

util.format(1, 2, 3); // '1 2 3'

util.inherits(constructor, superConstructor)#

Inherit the prototype methods from one constructor into another. The prototype of constructor will be set to a new object created from superConstructor.

As an additional convenience, superConstructor will be accessible through the constructor.super_ property.

const util = require('util');
const EventEmitter = require('events');

function MyStream() {
    EventEmitter.call(this);
}

util.inherits(MyStream, EventEmitter);

MyStream.prototype.write = function(data) {
    this.emit('data', data);
}

var stream = new MyStream();

console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
})
stream.write('It works!'); // Received data: "It works!"

util.inspect(object[, options])#

Return a string representation of object, which is useful for debugging.

An optional options object may be passed that alters certain aspects of the formatted string:

  • showHidden - if true then the object's non-enumerable and symbol properties will be shown too. Defaults to false.

  • depth - tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely pass null.

  • colors - if true, then the output will be styled with ANSI color codes. Defaults to false. Colors are customizable, see below.

  • customInspect - if false, then custom inspect(depth, opts) functions defined on the objects being inspected won't be called. Defaults to true.

Example of inspecting all properties of the util object:

const util = require('util');

console.log(util.inspect(util, { showHidden: true, depth: null }));

Values may supply their own custom inspect(depth, opts) functions, when called they receive the current depth in the recursive inspection, as well as the options object passed to util.inspect().

Customizing util.inspect colors#

Color output (if enabled) of util.inspect is customizable globally via util.inspect.styles and util.inspect.colors objects.

util.inspect.styles is a map assigning each style a color from util.inspect.colors. Highlighted styles and their default values are: number (yellow) boolean (yellow) string (green) date (magenta) regexp (red) null (bold) undefined (grey) special - only function at this time (cyan) * name (intentionally no styling)

Predefined color codes are: white, grey, black, blue, cyan, green, magenta, red and yellow. There are also bold, italic, underline and inverse codes.

Custom inspect() function on Objects#

Objects also may define their own inspect(depth) function which util.inspect() will invoke and use the result of when inspecting the object:

const util = require('util');

var obj = { name: 'nate' };
obj.inspect = function(depth) {
  return `{${this.name}}`;
};

util.inspect(obj);
  // "{nate}"

You may also return another Object entirely, and the returned String will be formatted according to the returned Object. This is similar to how JSON.stringify() works:

var obj = { foo: 'this will not show up in the inspect() output' };
obj.inspect = function(depth) {
  return { bar: 'baz' };
};

util.inspect(obj);
  // "{ bar: 'baz' }"

util.isArray(object)#

Stability: 0 - Deprecated

Internal alias for Array.isArray.

Returns true if the given "object" is an Array. false otherwise.

const util = require('util');

util.isArray([])
  // true
util.isArray(new Array)
  // true
util.isArray({})
  // false

util.isBoolean(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Boolean. false otherwise.

const util = require('util');

util.isBoolean(1)
  // false
util.isBoolean(0)
  // false
util.isBoolean(false)
  // true

util.isBuffer(object)#

Stability: 0 - Deprecated

Use Buffer.isBuffer() instead.

Returns true if the given "object" is a Buffer. false otherwise.

const util = require('util');

util.isBuffer({ length: 0 })
  // false
util.isBuffer([])
  // false
util.isBuffer(new Buffer('hello world'))
  // true

util.isDate(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Date. false otherwise.

const util = require('util');

util.isDate(new Date())
  // true
util.isDate(Date())
  // false (without 'new' returns a String)
util.isDate({})
  // false

util.isError(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is an Error. false otherwise.

const util = require('util');

util.isError(new Error())
  // true
util.isError(new TypeError())
  // true
util.isError({ name: 'Error', message: 'an error occurred' })
  // false

util.isFunction(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Function. false otherwise.

const util = require('util');

function Foo() {}
var Bar = function() {};

util.isFunction({})
  // false
util.isFunction(Foo)
  // true
util.isFunction(Bar)
  // true

util.isNull(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is strictly null. false otherwise.

const util = require('util');

util.isNull(0)
  // false
util.isNull(undefined)
  // false
util.isNull(null)
  // true

util.isNullOrUndefined(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is null or undefined. false otherwise.

const util = require('util');

util.isNullOrUndefined(0)
  // false
util.isNullOrUndefined(undefined)
  // true
util.isNullOrUndefined(null)
  // true

util.isNumber(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Number. false otherwise.

const util = require('util');

util.isNumber(false)
  // false
util.isNumber(Infinity)
  // true
util.isNumber(0)
  // true
util.isNumber(NaN)
  // true

util.isObject(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is strictly an Object and not a Function. false otherwise.

const util = require('util');

util.isObject(5)
  // false
util.isObject(null)
  // false
util.isObject({})
  // true
util.isObject(function(){})
  // false

util.isPrimitive(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a primitive type. false otherwise.

const util = require('util');

util.isPrimitive(5)
  // true
util.isPrimitive('foo')
  // true
util.isPrimitive(false)
  // true
util.isPrimitive(null)
  // true
util.isPrimitive(undefined)
  // true
util.isPrimitive({})
  // false
util.isPrimitive(function() {})
  // false
util.isPrimitive(/^$/)
  // false
util.isPrimitive(new Date())
  // false

util.isRegExp(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a RegExp. false otherwise.

const util = require('util');

util.isRegExp(/some regexp/)
  // true
util.isRegExp(new RegExp('another regexp'))
  // true
util.isRegExp({})
  // false

util.isString(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a String. false otherwise.

const util = require('util');

util.isString('')
  // true
util.isString('foo')
  // true
util.isString(String('foo'))
  // true
util.isString(5)
  // false

util.isSymbol(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Symbol. false otherwise.

const util = require('util');

util.isSymbol(5)
  // false
util.isSymbol('foo')
  // false
util.isSymbol(Symbol('foo'))
  // true

util.isUndefined(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is undefined. false otherwise.

const util = require('util');

var foo;
util.isUndefined(5)
  // false
util.isUndefined(foo)
  // true
util.isUndefined(null)
  // false

util.log(string)#

Output with timestamp on stdout.

require('util').log('Timestamped message.');

util.print([...])#

Stability: 0 - Deprecated: Use console.log instead.

Deprecated predecessor of console.log.

util.pump(readableStream, writableStream[, callback])#

Stability: 0 - Deprecated: Use readableStream.pipe(writableStream)

Deprecated predecessor of stream.pipe().

util.puts([...])#

Stability: 0 - Deprecated: Use console.log() instead.

Deprecated predecessor of console.log.

V8#

Stability: 2 - Stable

This module exposes events and interfaces specific to the version of V8 built with Node.js. These interfaces are subject to change by upstream and are therefore not covered under the stability index.

getHeapStatistics()#

Returns an object with the following properties

{
  total_heap_size: 7326976,
  total_heap_size_executable: 4194304,
  total_physical_size: 7326976,
  total_available_size: 1152656,
  used_heap_size: 3476208,
  heap_size_limit: 1535115264
}

setFlagsFromString(string)#

Set additional V8 command line flags. Use with care; changing settings after the VM has started may result in unpredictable behavior, including crashes and data loss. Or it may simply do nothing.

The V8 options available for a version of Node.js may be determined by running node --v8-options. An unofficial, community-maintained list of options and their effects is available here.

Usage:

// Print GC events to stdout for one minute.
const v8 = require('v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);

Executing JavaScript#

Stability: 2 - Stable

You can access this module with:

const vm = require('vm');

JavaScript code can be compiled and run immediately or compiled, saved, and run later.

Class: Script#

A class for holding precompiled scripts, and running them in specific sandboxes.

new vm.Script(code, options)#

Creating a new Script compiles code but does not run it. Instead, the created vm.Script object represents this compiled code. This script can be run later many times using methods below. The returned script is not bound to any global object. It is bound before each run, just for that run.

The options when creating a script are:

  • filename: allows you to control the filename that shows up in any stack traces produced from this script.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to syntax errors compiling the code; errors while running the code are controlled by the options to the script's methods.
  • timeout: a number of milliseconds to execute code before terminating execution. If execution is terminated, an Error will be thrown.

script.runInContext(contextifiedSandbox[, options])#

Similar to vm.runInContext but a method of a precompiled Script object. script.runInContext runs script's compiled code in contextifiedSandbox and returns the result. Running code does not have access to local scope.

script.runInContext takes the same options as script.runInThisContext.

Example: compile code that increments a global variable and sets one, then execute the code multiple times. These globals are contained in the sandbox.

const util = require('util');
const vm = require('vm');

var sandbox = {
  animal: 'cat',
  count: 2
};

var context = new vm.createContext(sandbox);
var script = new vm.Script('count += 1; name = "kitty"');

for (var i = 0; i < 10; ++i) {
  script.runInContext(context);
}

console.log(util.inspect(sandbox));

// { animal: 'cat', count: 12, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. script.runInContext is quite useful, but safely running untrusted code requires a separate process.

script.runInNewContext([sandbox][, options])#

Similar to vm.runInNewContext but a method of a precompiled Script object. script.runInNewContext contextifies sandbox if passed or creates a new contextified sandbox if it's omitted, and then runs script's compiled code with the sandbox as the global object and returns the result. Running code does not have access to local scope.

script.runInNewContext takes the same options as script.runInThisContext.

Example: compile code that sets a global variable, then execute the code multiple times in different contexts. These globals are set on and contained in the sandboxes.

const util = require('util');
const vm = require('vm');

const sandboxes = [{}, {}, {}];

const script = new vm.Script('globalVar = "set"');

sandboxes.forEach((sandbox) => {
  script.runInNewContext(sandbox);
});

console.log(util.inspect(sandboxes));

// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]

Note that running untrusted code is a tricky business requiring great care. script.runInNewContext is quite useful, but safely running untrusted code requires a separate process.

script.runInThisContext(options)#

Similar to vm.runInThisContext but a method of a precompiled Script object. script.runInThisContext runs script's compiled code and returns the result. Running code does not have access to local scope, but does have access to the current global object.

Example of using script.runInThisContext to compile code once and run it multiple times:

const vm = require('vm');

global.globalVar = 0;

const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });

for (var i = 0; i < 1000; ++i) {
  script.runInThisContext();
}

console.log(globalVar);

// 1000

The options for running a script are:

  • filename: allows you to control the filename that shows up in any stack traces produced.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to runtime errors executing the code; it is impossible to create a Script instance with syntax errors, as the constructor will throw.
  • timeout: a number of milliseconds to execute the script before terminating execution. If execution is terminated, an Error will be thrown.

vm.createContext([sandbox])#

If given a sandbox object, will "contextify" that sandbox so that it can be used in calls to vm.runInContext or script.runInContext. Inside scripts run as such, sandbox will be the global object, retaining all its existing properties but also having the built-in objects and functions any standard global object has. Outside of scripts run by the vm module, sandbox will be unchanged.

If not given a sandbox object, returns a new, empty contextified sandbox object you can use.

This function is useful for creating a sandbox that can be used to run multiple scripts, e.g. if you were emulating a web browser it could be used to create a single sandbox representing a window's global object, then run all <script> tags together inside that sandbox.

vm.isContext(sandbox)#

Returns whether or not a sandbox object has been contextified by calling vm.createContext on it.

vm.runInContext(code, contextifiedSandbox[, options])#

vm.runInContext compiles code, then runs it in contextifiedSandbox and returns the result. Running code does not have access to local scope. The contextifiedSandbox object must have been previously contextified via vm.createContext; it will be used as the global object for code.

vm.runInContext takes the same options as vm.runInThisContext.

Example: compile and execute different scripts in a single existing context.

const util = require('util');
const vm = require('vm');

const sandbox = { globalVar: 1 };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));

// { globalVar: 1024 }

Note that running untrusted code is a tricky business requiring great care. vm.runInContext is quite useful, but safely running untrusted code requires a separate process.

vm.runInDebugContext(code)#

vm.runInDebugContext compiles and executes code inside the V8 debug context. The primary use case is to get access to the V8 debug object:

const Debug = vm.runInDebugContext('Debug');
Debug.scripts().forEach(function(script) { console.log(script.name); });

Note that the debug context and object are intrinsically tied to V8's debugger implementation and may change (or even get removed) without prior warning.

The debug object can also be exposed with the --expose_debug_as= switch.

vm.runInNewContext(code[, sandbox][, options])#

vm.runInNewContext compiles code, contextifies sandbox if passed or creates a new contextified sandbox if it's omitted, and then runs the code with the sandbox as the global object and returns the result.

vm.runInNewContext takes the same options as vm.runInThisContext.

Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox.

const util = require('util');
const vm = require('vm');

const sandbox = {
  animal: 'cat',
  count: 2
};

vm.runInNewContext('count += 1; name = "kitty"', sandbox);
console.log(util.inspect(sandbox));

// { animal: 'cat', count: 3, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. vm.runInNewContext is quite useful, but safely running untrusted code requires a separate process.

vm.runInThisContext(code[, options])#

vm.runInThisContext() compiles code, runs it and returns the result. Running code does not have access to local scope, but does have access to the current global object.

Example of using vm.runInThisContext and eval to run the same code:

const vm = require('vm');
var localVar = 'initial value';

const vmResult = vm.runInThisContext('localVar = "vm";');
console.log('vmResult: ', vmResult);
console.log('localVar: ', localVar);

const evalResult = eval('localVar = "eval";');
console.log('evalResult: ', evalResult);
console.log('localVar: ', localVar);

// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'

vm.runInThisContext does not have access to the local scope, so localVar is unchanged. eval does have access to the local scope, so localVar is changed.

In this way vm.runInThisContext is much like an indirect eval call, e.g. (0,eval)('code'). However, it also has the following additional options:

  • filename: allows you to control the filename that shows up in any stack traces produced.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Will capture both syntax errors from compiling code and runtime errors thrown by executing the compiled code. Defaults to true.
  • timeout: a number of milliseconds to execute code before terminating execution. If execution is terminated, an Error will be thrown.

Zlib#

Stability: 2 - Stable

You can access this module with:

const zlib = require('zlib');

This provides bindings to Gzip/Gunzip, Deflate/Inflate, and DeflateRaw/InflateRaw classes. Each class takes the same options, and is a readable/writable Stream.

Examples#

Compressing or decompressing a file can be done by piping an fs.ReadStream into a zlib stream, then into an fs.WriteStream.

const gzip = zlib.createGzip();
const fs = require('fs');
const inp = fs.createReadStream('input.txt');
const out = fs.createWriteStream('input.txt.gz');

inp.pipe(gzip).pipe(out);

Compressing or decompressing data in one step can be done by using the convenience methods.

const input = '.................................';
zlib.deflate(input, function(err, buffer) {
  if (!err) {
    console.log(buffer.toString('base64'));
  }
});

const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');
zlib.unzip(buffer, function(err, buffer) {
  if (!err) {
    console.log(buffer.toString());
  }
});

To use this module in an HTTP client or server, use the accept-encoding on requests, and the content-encoding header on responses.

Note: these examples are drastically simplified to show the basic concept. Zlib encoding can be expensive, and the results ought to be cached. See Memory Usage Tuning below for more information on the speed/memory/compression tradeoffs involved in zlib usage.

// client request example
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
const request = http.get({ host: 'izs.me',
                         path: '/',
                         port: 80,
                         headers: { 'accept-encoding': 'gzip,deflate' } });
request.on('response', (response) => {
  var output = fs.createWriteStream('izs.me_index.html');

  switch (response.headers['content-encoding']) {
    // or, just use zlib.createUnzip() to handle both cases
    case 'gzip':
      response.pipe(zlib.createGunzip()).pipe(output);
      break;
    case 'deflate':
      response.pipe(zlib.createInflate()).pipe(output);
      break;
    default:
      response.pipe(output);
      break;
  }
});

// server example
// Running a gzip operation on every request is quite expensive.
// It would be much more efficient to cache the compressed buffer.
const zlib = require('zlib');
const http = require('http');
const fs = require('fs');
http.createServer((request, response) => {
  var raw = fs.createReadStream('index.html');
  var acceptEncoding = request.headers['accept-encoding'];
  if (!acceptEncoding) {
    acceptEncoding = '';
  }

  // Note: this is not a conformant accept-encoding parser.
  // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
  if (acceptEncoding.match(/\bdeflate\b/)) {
    response.writeHead(200, { 'content-encoding': 'deflate' });
    raw.pipe(zlib.createDeflate()).pipe(response);
  } else if (acceptEncoding.match(/\bgzip\b/)) {
    response.writeHead(200, { 'content-encoding': 'gzip' });
    raw.pipe(zlib.createGzip()).pipe(response);
  } else {
    response.writeHead(200, {});
    raw.pipe(response);
  }
}).listen(1337);

Memory Usage Tuning#

From zlib/zconf.h, modified to node.js's usage:

The memory requirements for deflate are (in bytes):

(1 << (windowBits+2)) +  (1 << (memLevel+9))

that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects.

For example, if you want to reduce the default memory requirements from 256K to 128K, set the options to:

{ windowBits: 14, memLevel: 7 }

Of course this will generally degrade compression (there's no free lunch).

The memory requirements for inflate are (in bytes)

1 << windowBits

that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects.

This is in addition to a single internal output slab buffer of size chunkSize, which defaults to 16K.

The speed of zlib compression is affected most dramatically by the level setting. A higher level will result in better compression, but will take longer to complete. A lower level will result in less compression, but will be much faster.

In general, greater memory usage options will mean that node.js has to make fewer calls to zlib, since it'll be able to process more data in a single write operation. So, this is another factor that affects the speed, at the cost of memory usage.

Constants#

All of the constants defined in zlib.h are also defined on require('zlib'). In the normal course of operations, you will not need to ever set any of these. They are documented here so that their presence is not surprising. This section is taken almost directly from the zlib documentation. See http://zlib.net/manual.html#Constants for more details.

Allowed flush values.

  • zlib.Z_NO_FLUSH
  • zlib.Z_PARTIAL_FLUSH
  • zlib.Z_SYNC_FLUSH
  • zlib.Z_FULL_FLUSH
  • zlib.Z_FINISH
  • zlib.Z_BLOCK
  • zlib.Z_TREES

Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events.

  • zlib.Z_OK
  • zlib.Z_STREAM_END
  • zlib.Z_NEED_DICT
  • zlib.Z_ERRNO
  • zlib.Z_STREAM_ERROR
  • zlib.Z_DATA_ERROR
  • zlib.Z_MEM_ERROR
  • zlib.Z_BUF_ERROR
  • zlib.Z_VERSION_ERROR

Compression levels.

  • zlib.Z_NO_COMPRESSION
  • zlib.Z_BEST_SPEED
  • zlib.Z_BEST_COMPRESSION
  • zlib.Z_DEFAULT_COMPRESSION

Compression strategy.

  • zlib.Z_FILTERED
  • zlib.Z_HUFFMAN_ONLY
  • zlib.Z_RLE
  • zlib.Z_FIXED
  • zlib.Z_DEFAULT_STRATEGY

Possible values of the data_type field.

  • zlib.Z_BINARY
  • zlib.Z_TEXT
  • zlib.Z_ASCII
  • zlib.Z_UNKNOWN

The deflate compression method (the only one supported in this version).

  • zlib.Z_DEFLATED

For initializing zalloc, zfree, opaque.

  • zlib.Z_NULL

Class Options#

Each class takes an options object. All options are optional.

Note that some options are only relevant when compressing, and are ignored by the decompression classes.

  • flush (default: zlib.Z_NO_FLUSH)
  • chunkSize (default: 16*1024)
  • windowBits
  • level (compression only)
  • memLevel (compression only)
  • strategy (compression only)
  • dictionary (deflate/inflate only, empty dictionary by default)

See the description of deflateInit2 and inflateInit2 at

http://zlib.net/manual.html#Advanced for more information on these.

Class: zlib.Deflate#

Compress data using deflate.

Class: zlib.DeflateRaw#

Compress data using deflate, and do not append a zlib header.

Class: zlib.Gunzip#

Decompress a gzip stream.

Class: zlib.Gzip#

Compress data using gzip.

Class: zlib.Inflate#

Decompress a deflate stream.

Class: zlib.InflateRaw#

Decompress a raw deflate stream.

Class: zlib.Unzip#

Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header.

Class: zlib.Zlib#

Not exported by the zlib module. It is documented here because it is the base class of the compressor/decompressor classes.

zlib.flush([kind], callback)#

kind defaults to zlib.Z_FULL_FLUSH.

Flush pending data. Don't call this frivolously, premature flushes negatively impact the effectiveness of the compression algorithm.

zlib.params(level, strategy, callback)#

Dynamically update the compression level and compression strategy. Only applicable to deflate algorithm.

zlib.reset()#

Reset the compressor/decompressor to factory defaults. Only applicable to the inflate and deflate algorithms.

zlib.createDeflate(options)#

Returns a new Deflate object with an options.

zlib.createDeflateRaw(options)#

Returns a new DeflateRaw object with an options.

zlib.createGunzip(options)#

Returns a new Gunzip object with an options.

zlib.createGzip(options)#

Returns a new Gzip object with an options.

zlib.createInflate(options)#

Returns a new Inflate object with an options.

zlib.createInflateRaw(options)#

Returns a new InflateRaw object with an options.

zlib.createUnzip(options)#

Returns a new Unzip object with an options.

Convenience Methods#

All of these take a string or buffer as the first argument, an optional second argument to supply options to the zlib classes and will call the supplied callback with callback(error, result).

Every method has a *Sync counterpart, which accept the same arguments, but without a callback.

zlib.deflate(buf[, options], callback)#

Compress a string with Deflate.

zlib.deflateRaw(buf[, options], callback)#

zlib.deflateRawSync(buf[, options])#

Compress a string with DeflateRaw.

zlib.deflateSync(buf[, options])#

Compress a string with Deflate.

zlib.gunzip(buf[, options], callback)#

zlib.gunzipSync(buf[, options])#

Decompress a raw Buffer with Gunzip.

zlib.gzip(buf[, options], callback)#

zlib.gzipSync(buf[, options])#

Compress a string with Gzip.

zlib.inflate(buf[, options], callback)#

Decompress a raw Buffer with Inflate.

zlib.inflateRaw(buf[, options], callback)#

zlib.inflateRawSync(buf[, options])#

Decompress a raw Buffer with InflateRaw.

zlib.inflateSync(buf[, options])#

Decompress a raw Buffer with Inflate.

zlib.unzip(buf[, options], callback)#

zlib.unzipSync(buf[, options])#

Decompress a raw Buffer with Unzip.

node-v4.2.6/doc/api/all.json000644 000766 000024 00004366567 12650222331 015756 0ustar00iojsstaff000000 000000 { "source": "doc/api/all.markdown", "miscs": [ { "textRaw": "About this Documentation", "name": "About this Documentation", "type": "misc", "desc": "

The goal of this documentation is to comprehensively explain the Node.js\nAPI, both from a reference as well as a conceptual point of view. Each\nsection describes a built-in module or high-level concept.\n\n

\n

Where appropriate, property types, method arguments, and the arguments\nprovided to event handlers are detailed in a list underneath the topic\nheading.\n\n

\n

Every .html document has a corresponding .json document presenting\nthe same information in a structured manner. This feature is\nexperimental, and added for the benefit of IDEs and other utilities that\nwish to do programmatic things with the documentation.\n\n

\n

Every .html and .json file is generated based on the corresponding\n.markdown file in the doc/api/ folder in Node.js's source tree. The\ndocumentation is generated using the tools/doc/generate.js program.\nThe HTML template is located at doc/template.html.\n\n

\n", "miscs": [ { "textRaw": "Stability Index", "name": "Stability Index", "type": "misc", "desc": "

Throughout the documentation, you will see indications of a section's\nstability. The Node.js API is still somewhat changing, and as it\nmatures, certain parts are more reliable than others. Some are so\nproven, and so relied upon, that they are unlikely to ever change at\nall. Others are brand new and experimental, or known to be hazardous\nand in the process of being redesigned.\n\n

\n

The stability indices are as follows:\n\n

\n
Stability: 0 - Deprecated\nThis feature is known to be problematic, and changes are\nplanned.  Do not rely on it.  Use of the feature may cause warnings.  Backwards\ncompatibility should not be expected.
\n
Stability: 1 - Experimental\nThis feature is subject to change, and is gated by a command line flag.\nIt may change or be removed in future versions.
\n
Stability: 2 - Stable\nThe API has proven satisfactory. Compatibility with the npm ecosystem\nis a high priority, and will not be broken unless absolutely necessary.
\n
Stability: 3 - Locked\nOnly fixes related to security, performance, or bug fixes will be accepted.\nPlease do not suggest API changes in this area; they will be refused.
\n" }, { "textRaw": "JSON Output", "name": "json_output", "stability": 1, "stabilityText": "Experimental", "desc": "

Every HTML file in the markdown has a corresponding JSON file with the\nsame data.\n\n

\n

This feature was added in Node.js v0.6.12. It is experimental.\n\n

\n", "type": "misc", "displayName": "JSON Output" } ] }, { "textRaw": "Synopsis", "name": "Synopsis", "type": "misc", "desc": "

An example of a [web server][] written with Node.js which responds with\n'Hello World':\n\n

\n
const http = require('http');\n\nhttp.createServer( (request, response) => {\n  response.writeHead(200, {'Content-Type': 'text/plain'});\n  response.end('Hello World\\n');\n}).listen(8124);\n\nconsole.log('Server running at http://127.0.0.1:8124/');
\n

To run the server, put the code into a file called example.js and execute\nit with the node program\n\n

\n
> node example.js\nServer running at http://127.0.0.1:8124/
\n

All of the examples in the documentation can be run similarly.\n\n

\n" }, { "textRaw": "Debugger", "name": "Debugger", "stability": 2, "stabilityText": "Stable", "type": "misc", "desc": "

Node.js includes a full-featured out-of-process debugging utility accessible\nvia a simple [TCP-based protocol][] and built-in debugging client. To use it,\nstart Node.js with the debug argument followed by the path to the script to\ndebug; a prompt will be displayed indicating successful launch of the debugger:\n\n

\n
% node debug myscript.js\n< debugger listening on port 5858\nconnecting... ok\nbreak in /home/indutny/Code/git/indutny/myscript.js:1\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\ndebug>
\n

Node.js's debugger client does not yet support the full range of commands, but\nsimple step and inspection are possible.\n\n

\n

Inserting the statement debugger; into the source code of a script will\nenable a breakpoint at that position in the code.\n\n

\n

For example, suppose myscript.js is written as:\n\n

\n
// myscript.js\nx = 5;\nsetTimeout(function () {\n  debugger;\n  console.log('world');\n}, 1000);\nconsole.log('hello');
\n

Once the debugger is run, a breakpoint will occur at line 4:\n\n

\n
% node debug myscript.js\n< debugger listening on port 5858\nconnecting... ok\nbreak in /home/indutny/Code/git/indutny/myscript.js:1\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\ndebug> cont\n< hello\nbreak in /home/indutny/Code/git/indutny/myscript.js:3\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\ndebug> next\nbreak in /home/indutny/Code/git/indutny/myscript.js:4\n  2 setTimeout(function () {\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\n  6 console.log('hello');\ndebug> repl\nPress Ctrl + C to leave debug repl\n> x\n5\n> 2+2\n4\ndebug> next\n< world\nbreak in /home/indutny/Code/git/indutny/myscript.js:5\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\n  6 console.log('hello');\n  7\ndebug> quit\n%
\n

The repl command allows code to be evaluated remotely. The next command\nsteps over to the next line. Type help to see what other commands are\navailable.\n\n

\n", "miscs": [ { "textRaw": "Watchers", "name": "watchers", "desc": "

It is possible to watch expression and variable values while debugging. On\nevery breakpoint, each expression from the watchers list will be evaluated\nin the current context and displayed immediately before the breakpoint's\nsource code listing.\n\n

\n

To begin watching an expression, type watch('my_expression'). The command\nwatchers will print the active watchers. To remove a watcher, type\nunwatch('my_expression').\n\n

\n", "type": "misc", "displayName": "Watchers" }, { "textRaw": "Commands reference", "name": "commands_reference", "modules": [ { "textRaw": "Stepping", "name": "Stepping", "desc": "

It is also possible to set a breakpoint in a file (module) that\nisn't loaded yet:\n\n

\n
% ./node debug test/fixtures/break-in-module/main.js\n< debugger listening on port 5858\nconnecting to port 5858... ok\nbreak in test/fixtures/break-in-module/main.js:1\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> setBreakpoint('mod.js', 23)\nWarning: script 'mod.js' was not loaded yet.\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> c\nbreak in test/fixtures/break-in-module/mod.js:23\n 21\n 22 exports.hello = function() {\n 23   return 'hello from module';\n 24 };\n 25\ndebug>
\n", "type": "module", "displayName": "Breakpoints" }, { "textRaw": "Breakpoints", "name": "breakpoints", "desc": "

It is also possible to set a breakpoint in a file (module) that\nisn't loaded yet:\n\n

\n
% ./node debug test/fixtures/break-in-module/main.js\n< debugger listening on port 5858\nconnecting to port 5858... ok\nbreak in test/fixtures/break-in-module/main.js:1\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> setBreakpoint('mod.js', 23)\nWarning: script 'mod.js' was not loaded yet.\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> c\nbreak in test/fixtures/break-in-module/mod.js:23\n 21\n 22 exports.hello = function() {\n 23   return 'hello from module';\n 24 };\n 25\ndebug>
\n", "type": "module", "displayName": "Breakpoints" }, { "textRaw": "Execution control", "name": "Execution control", "type": "module", "displayName": "Various" }, { "textRaw": "Various", "name": "various", "type": "module", "displayName": "Various" } ], "type": "misc", "displayName": "Commands reference" }, { "textRaw": "Advanced Usage", "name": "advanced_usage", "desc": "

An alternative way of enabling and accessing the debugger is to start\nNode.js with the --debug command-line flag or by signaling an existing\nNode.js process with SIGUSR1.\n\n

\n

Once a process has been set in debug mode this way, it can be connected to\nusing the Node.js debugger by either connecting to the pid of the running\nprocess or via URI reference to the listening debugger:\n\n

\n
    \n
  • node debug -p <pid> - Connects to the process via the pid
  • \n
  • node debug <URI> - Connects to the process via the URI such as\nlocalhost:5858
  • \n
\n", "type": "misc", "displayName": "Advanced Usage" } ] }, { "textRaw": "Errors", "name": "Errors", "type": "misc", "desc": "

Applications running in Node.js will generally experience four categories of\nerrors:\n\n

\n
    \n
  • Standard JavaScript errors such as:
      \n
    • [EvalError][]: thrown when a call to eval() fails.
    • \n
    • [SyntaxError][]: thrown in response to improper JavaScript language\nsyntax.
    • \n
    • [RangeError][]: thrown when a value is not within an expected range
    • \n
    • [ReferenceError][]: thrown when using undefined variables
    • \n
    • [TypeError][]: thrown when passing arguments of the wrong type
    • \n
    • [URIError][]: thrown when a global URI handling function is misused.
    • \n
    \n
  • \n
  • System errors triggered by underlying operating system constraints such\nas attempting to open a file that does not exist, attempting to send data\nover a closed socket, etc;
  • \n
  • And User-specified errors triggered by application code.
  • \n
  • Assertion Errors are a special class of error that can be triggered whenever\nNode.js detects an exceptional logic violation that should never occur. These\nare raised typically by the assert module.
  • \n
\n

All JavaScript and System errors raised by Node.js inherit from, or are\ninstances of, the standard JavaScript [Error][] class and are guaranteed\nto provide at least the properties available on that class.\n\n

\n", "miscs": [ { "textRaw": "Error Propagation and Interception", "name": "Error Propagation and Interception", "type": "misc", "desc": "

Node.js supports several mechanisms for propagating and handling errors that\noccur while an application is running. How these errors are reported and\nhandled depends entirely on the type of Error and the style of the API that is\ncalled.\n\n

\n

All JavaScript errors are handled as exceptions that immediately generate\nand throw an error using the standard JavaScript throw mechanism. These\nare handled using the [try / catch construct][] provided by the JavaScript\nlanguage.\n\n

\n
// Throws with a ReferenceError because z is undefined\ntry {\n  const m = 1;\n  const n = m + z;\n} catch (err) {\n  // Handle the error here.\n}
\n

Any use of the JavaScript throw mechanism will raise an exception that\nmust be handled using try / catch or the Node.js process will exit\nimmediately.\n\n

\n

With few exceptions, Synchronous APIs (any blocking method that does not\naccept a callback function, such as [fs.readFileSync][]), will use throw\nto report errors.\n\n

\n

Errors that occur within Asynchronous APIs may be reported in multiple ways:\n\n

\n
    \n
  • Most asynchronous methods that accept a callback function will accept an\nError object passed as the first argument to that function. If that first\nargument is not null and is an instance of Error, then an error occurred\nthat should be handled.

    \n
    const fs = require('fs');\nfs.readFile('a file that does not exist', (err, data) => {\n  if (err) {\n    console.error('There was an error reading the file!', err);\n    return;\n  }\n  // Otherwise handle the data\n});
    \n
  • \n
  • When an asynchronous method is called on an object that is an EventEmitter,\nerrors can be routed to that object's 'error' event.

    \n
    const net = require('net');\nconst connection = net.connect('localhost');\n\n// Adding an 'error' event handler to a stream:\nconnection.on('error', (err) => {\n  // If the connection is reset by the server, or if it can't\n  // connect at all, or on any sort of error encountered by\n  // the connection, the error will be sent here.\n  console.error(err);\n});\n\nconnection.pipe(process.stdout);
    \n
  • \n
  • A handful of typically asynchronous methods in the Node.js API may still\nuse the throw mechanism to raise exceptions that must be handled using\ntry / catch. There is no comprehensive list of such methods; please\nrefer to the documentation of each method to determine the appropriate\nerror handling mechanism required.

    \n
  • \n
\n

The use of the 'error' event mechanism is most common for [stream-based][]\nand [event emitter-based][] APIs, which themselves represent a series of\nasynchronous operations over time (as opposed to a single operation that may\npass or fail).\n\n

\n

For all EventEmitter objects, if an 'error' event handler is not\nprovided, the error will be thrown, causing the Node.js process to report an\nunhandled exception and crash unless either: The [domain][] module is used\nappropriately or a handler has been registered for the\n[process.on('uncaughtException')][] event.\n\n

\n
const EventEmitter = require('events');\nconst ee = new EventEmitter();\n\nsetImmediate(() => {\n  // This will crash the process because no 'error' event\n  // handler has been added.\n  ee.emit('error', new Error('This will crash'));\n});
\n

Errors generated in this way cannot be intercepted using try / catch as\nthey are thrown after the calling code has already exited.\n\n

\n

Developers must refer to the documentation for each method to determine\nexactly how errors raised by those methods are propagated.\n\n

\n", "miscs": [ { "textRaw": "Node.js style callbacks", "name": "Node.js style callbacks", "type": "misc", "desc": "

Most asynchronous methods exposed by the Node.js core API follow an idiomatic\npattern referred to as a "Node.js style callback". With this pattern, a\ncallback function is passed to the method as an argument. When the operation\neither completes or an error is raised, the callback function is called with\nthe Error object (if any) passed as the first argument. If no error was raised,\nthe first argument will be passed as null.\n\n

\n
const fs = require('fs');\n\nfunction nodeStyleCallback(err, data) {\n if (err) {\n   console.error('There was an error', err);\n   return;\n }\n console.log(data);\n}\n\nfs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);\nfs.readFile('/some/file/that/does-exist', nodeStyleCallback)
\n

The JavaScript try / catch mechanism cannot be used to intercept errors\ngenerated by asynchronous APIs. A common mistake for beginners is to try to\nuse throw inside a Node.js style callback:\n\n

\n
// THIS WILL NOT WORK:\nconst fs = require('fs');\n\ntry {\n  fs.readFile('/some/file/that/does-not-exist', (err, data) => {\n    // mistaken assumption: throwing here...\n    if (err) {\n      throw err;\n    }\n  });\n} catch(err) {\n  // This will not catch the throw!\n  console.log(err);\n}
\n

This will not work because the callback function passed to fs.readFile() is\ncalled asynchronously. By the time the callback has been called, the\nsurrounding code (including the try { } catch(err) { } block will have\nalready exited. Throwing an error inside the callback can crash the Node.js\nprocess in most cases. If [domains][] are enabled, or a handler has been\nregistered with process.on('uncaughtException'), such errors can be\nintercepted.\n\n

\n" } ] }, { "textRaw": "Exceptions vs. Errors", "name": "Exceptions vs. Errors", "type": "misc", "desc": "

A JavaScript exception is a value that is thrown as a result of an invalid\noperation or as the target of a throw statement. While it is not required\nthat these values are instances of Error or classes which inherit from\nError, all exceptions thrown by Node.js or the JavaScript runtime will be\ninstances of Error.\n\n

\n

Some exceptions are unrecoverable at the JavaScript layer. Such exceptions\nwill always cause the Node.js process to crash. Examples include assert()\nchecks or abort() calls in the C++ layer.\n\n

\n" }, { "textRaw": "System Errors", "name": "system_errors", "desc": "

System errors are generated when exceptions occur within the program's\nruntime environment. Typically, these are operational errors that occur\nwhen an application violates an operating system constraint such as attempting\nto read a file that does not exist or when the user does not have sufficient\npermissions.\n\n

\n

System errors are typically generated at the syscall level: an exhaustive list\nof error codes and their meanings is available by running man 2 intro or\nman 3 errno on most Unices; or [online][].\n\n

\n

In Node.js, system errors are represented as augmented Error objects with\nadded properties.\n\n

\n", "classes": [ { "textRaw": "Class: System Error", "type": "class", "name": "System", "properties": [ { "textRaw": "error.code", "name": "code", "desc": "

Returns a string representing the error code, which is always E followed by\na sequence of capital letters, and may be referenced in man 2 intro.\n\n

\n

The properties error.code and error.errno are aliases of one another and\nreturn the same value.\n\n

\n" }, { "textRaw": "error.errno", "name": "errno", "desc": "

Returns a string representing the error code, which is always E followed by\na sequence of capital letters, and may be referenced in man 2 intro.\n\n

\n

The properties error.code and error.errno are aliases of one another and\nreturn the same value.\n\n

\n" }, { "textRaw": "error.syscall", "name": "syscall", "desc": "

Returns a string describing the [syscall][] that failed.\n\n

\n" } ] } ], "modules": [ { "textRaw": "Common System Errors", "name": "common_system_errors", "desc": "

This list is not exhaustive, but enumerates many of the common system\nerrors encountered when writing a Node.js program. An exhaustive list may be\nfound [here][online].\n\n

\n
    \n
  • EACCES (Permission denied): An attempt was made to access a file in a way\nforbidden by its file access permissions.

    \n
  • \n
  • EADDRINUSE (Address already in use): An attempt to bind a server\n([net][], [http][], or [https][]) to a local address failed due to\nanother server on the local system already occupying that address.

    \n
  • \n
  • ECONNREFUSED (Connection refused): No connection could be made because the\ntarget machine actively refused it. This usually results from trying to\nconnect to a service that is inactive on the foreign host.

    \n
  • \n
  • ECONNRESET (Connection reset by peer): A connection was forcibly closed by\na peer. This normally results from a loss of the connection on the remote\nsocket due to a timeout or reboot. Commonly encountered via the [http][]\nand [net][] modules.

    \n
  • \n
  • EEXIST (File exists): An existing file was the target of an operation that\nrequired that the target not exist.

    \n
  • \n
  • EISDIR (Is a directory): An operation expected a file, but the given\npathname was a directory.

    \n
  • \n
  • EMFILE (Too many open files in system): Maximum number of\n[file descriptors][] allowable on the system has been reached, and\nrequests for another descriptor cannot be fulfilled until at least one\nhas been closed. This is encountered when opening many files at once in\nparallel, especially on systems (in particular, OS X) where there is a low\nfile descriptor limit for processes. To remedy a low limit, run\nulimit -n 2048 in the same shell that will run the Node.js process.

    \n
  • \n
  • ENOENT (No such file or directory): Commonly raised by [fs][] operations\nto indicate that a component of the specified pathname does not exist -- no\nentity (file or directory) could be found by the given path.

    \n
  • \n
  • ENOTDIR (Not a directory): A component of the given pathname existed, but\nwas not a directory as expected. Commonly raised by [fs.readdir][].

    \n
  • \n
  • ENOTEMPTY (Directory not empty): A directory with entries was the target\nof an operation that requires an empty directory -- usually [fs.unlink][].

    \n
  • \n
  • EPERM (Operation not permitted): An attempt was made to perform an\noperation that requires elevated privileges.

    \n
  • \n
  • EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is\nno process to read the data. Commonly encountered at the [net][] and\n[http][] layers, indicative that the remote side of the stream being\nwritten to has been closed.

    \n
  • \n
  • ETIMEDOUT (Operation timed out): A connect or send request failed because\nthe connected party did not properly respond after a period of time. Usually\nencountered by [http][] or [net][] -- often a sign that a socket.end()\nwas not properly called.

    \n
  • \n
\n", "type": "module", "displayName": "Common System Errors" } ], "type": "misc", "displayName": "System Errors" } ], "classes": [ { "textRaw": "Class: Error", "type": "class", "name": "Error", "desc": "

A generic JavaScript Error object that does not denote any specific\ncircumstance of why the error occurred. Error objects capture a "stack trace"\ndetailing the point in the code at which the Error was instantiated, and may\nprovide a text description of the error.\n\n

\n

All errors generated by Node.js, including all System and JavaScript errors,\nwill either be instances of, or inherit from, the Error class.\n\n

\n", "methods": [ { "textRaw": "Error.captureStackTrace(targetObject[, constructorOpt])", "type": "method", "name": "captureStackTrace", "desc": "

Creates a .stack property on targetObject, which when accessed returns\na string representing the location in the code at which\nError.captureStackTrace() was called.\n\n

\n
const myObject = {};\nError.captureStackTrace(myObject);\nmyObject.stack  // similar to `new Error().stack`
\n

The first line of the trace, instead of being prefixed with ErrorType:\nmessage, will be the result of calling targetObject.toString().\n\n

\n

The optional constructorOpt argument accepts a function. If given, all frames\nabove constructorOpt, including constructorOpt, will be omitted from the\ngenerated stack trace.\n\n

\n

The constructorOpt argument is useful for hiding implementation\ndetails of error generation from an end user. For instance:\n\n

\n
function MyError() {\n  Error.captureStackTrace(this, MyError);\n}\n\n// Without passing MyError to captureStackTrace, the MyError\n// frame would should up in the .stack property. by passing\n// the constructor, we omit that frame and all frames above it.\nnew MyError().stack
\n", "signatures": [ { "params": [ { "name": "targetObject" }, { "name": "constructorOpt", "optional": true } ] } ] } ], "properties": [ { "textRaw": "Error.stackTraceLimit", "name": "stackTraceLimit", "desc": "

The Error.stackTraceLimit property specifies the number of stack frames\ncollected by a stack trace (whether generated by new Error().stack or\nError.captureStackTrace(obj)).\n\n

\n

The default value is 10 but may be set to any valid JavaScript number. Changes\nwill affect any stack trace captured after the value has been changed.\n\n

\n

If set to a non-number value, or set to a negative number, stack traces will\nnot capture any frames.\n\n

\n", "properties": [ { "textRaw": "error.message", "name": "message", "desc": "

Returns the string description of error as set by calling new Error(message).\nThe message passed to the constructor will also appear in the first line of\nthe stack trace of the Error, however changing this property after the\nError object is created may not change the first line of the stack trace.\n\n

\n
const err = new Error('The message');\nconsole.log(err.message);\n  // Prints: The message
\n" }, { "textRaw": "error.stack", "name": "stack", "desc": "

Returns a string describing the point in the code at which the Error was\ninstantiated.\n\n

\n

For example:\n\n

\n
Error: Things keep happening!\n   at /home/gbusey/file.js:525:2\n   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)\n   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)\n   at increaseSynergy (/home/gbusey/actors.js:701:6)
\n

The first line is formatted as <error class name>: <error message>, and\nis followed by a series of stack frames (each line beginning with "at ").\nEach frame describes a call site within the code that lead to the error being\ngenerated. V8 attempts to display a name for each function (by variable name,\nfunction name, or object method name), but occasionally it will not be able to\nfind a suitable name. If V8 cannot determine a name for the function, only\nlocation information will be displayed for that frame. Otherwise, the\ndetermined function name will be displayed with location information appended\nin parentheses.\n\n

\n

It is important to note that frames are only generated for JavaScript\nfunctions. If, for example, execution synchronously passes through a C++ addon\nfunction called cheetahify, which itself calls a JavaScript function, the\nframe representing the cheetahify call will not be present in the stack\ntraces:\n\n

\n
const cheetahify = require('./native-binding.node');\n\nfunction makeFaster() {\n  // cheetahify *synchronously* calls speedy.\n  cheetahify(function speedy() {\n    throw new Error('oh no!');\n  });\n}\n\nmakeFaster(); // will throw:\n  // /home/gbusey/file.js:6\n  //     throw new Error('oh no!');\n  //           ^\n  // Error: oh no!\n  //     at speedy (/home/gbusey/file.js:6:11)\n  //     at makeFaster (/home/gbusey/file.js:5:3)\n  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)\n  //     at Module._compile (module.js:456:26)\n  //     at Object.Module._extensions..js (module.js:474:10)\n  //     at Module.load (module.js:356:32)\n  //     at Function.Module._load (module.js:312:12)\n  //     at Function.Module.runMain (module.js:497:10)\n  //     at startup (node.js:119:16)\n  //     at node.js:906:3
\n

The location information will be one of:\n\n

\n
    \n
  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • \n
  • plain-filename.js:line:column, if the frame represents a call internal\n to Node.js.
  • \n
  • /absolute/path/to/file.js:line:column, if the frame represents a call in\na user program, or its dependencies.
  • \n
\n

The string representing the stack trace is lazily generated when the\nerror.stack property is accessed.\n\n

\n

The number of frames captured by the stack trace is bounded by the smaller of\nError.stackTraceLimit or the number of available frames on the current event\nloop tick.\n\n

\n

System-level errors are generated as augmented Error instances, which are\ndetailed below.\n\n

\n" } ] } ], "signatures": [ { "params": [ { "name": "message" } ], "desc": "

Creates a new Error object and sets the error.message property to the\nprovided text message. If an object is passed as message, the text message\nis generated by calling message.toString(). The error.stack property will\nrepresent the point in the code at which new Error() was called. Stack traces\nare dependent on [V8's stack trace API][]. Stack traces extend only to either\n(a) the beginning of synchronous code execution, or (b) the number of frames\ngiven by the property Error.stackTraceLimit, whichever is smaller.\n\n

\n" } ] }, { "textRaw": "Class: RangeError", "type": "class", "name": "RangeError", "desc": "

A subclass of Error that indicates that a provided argument was not within the\nset or range of acceptable values for a function; whether that is a numeric\nrange, or outside the set of options for a given function parameter.\n\n

\n

For example:\n\n

\n
require('net').connect(-1);\n  // throws RangeError, port should be > 0 && < 65536
\n

Node.js will generate and throw RangeError instances immediately as a form\nof argument validation.\n\n

\n" }, { "textRaw": "Class: ReferenceError", "type": "class", "name": "ReferenceError", "desc": "

A subclass of Error that indicates that an attempt is being made to access a\nvariable that is not defined. Such errors commonly indicate typos in code, or\nan otherwise broken program.\n\n

\n

While client code may generate and propagate these errors, in practice, only V8\nwill do so.\n\n

\n
doesNotExist;\n  // throws ReferenceError, doesNotExist is not a variable in this program.
\n

ReferenceError instances will have an error.arguments property whose value\nis an array containing a single element: a string representing the variable\nthat was not defined.\n\n

\n
const assert = require('assert');\ntry {\n  doesNotExist;\n} catch(err) {\n  assert(err.arguments[0], 'doesNotExist');\n}
\n

Unless an application is dynamically generating and running code,\nReferenceError instances should always be considered a bug in the code\nor its dependencies.\n\n

\n" }, { "textRaw": "Class: SyntaxError", "type": "class", "name": "SyntaxError", "desc": "

A subclass of Error that indicates that a program is not valid JavaScript.\nThese errors may only be generated and propagated as a result of code\nevaluation. Code evaluation may happen as a result of eval, Function,\nrequire, or [vm][]. These errors are almost always indicative of a broken\nprogram.\n\n

\n
try {\n  require('vm').runInThisContext('binary ! isNotOk');\n} catch(err) {\n  // err will be a SyntaxError\n}
\n

SyntaxError instances are unrecoverable in the context that created them –\nthey may only be caught by other contexts.\n\n

\n" }, { "textRaw": "Class: TypeError", "type": "class", "name": "TypeError", "desc": "

A subclass of Error that indicates that a provided argument is not an\nallowable type. For example, passing a function to a parameter which expects a\nstring would be considered a TypeError.\n\n

\n
require('url').parse(function() { });\n  // throws TypeError, since it expected a string
\n

Node.js will generate and throw TypeError instances immediately as a form\nof argument validation.\n\n

\n" } ] }, { "textRaw": "Global Objects", "name": "Global Objects", "type": "misc", "desc": "

These objects are available in all modules. Some of these objects aren't\nactually in the global scope but in the module scope - this will be noted.\n\n

\n", "globals": [ { "textRaw": "Class: Buffer", "type": "global", "name": "Buffer", "desc": "

Used to handle binary data. See the [buffer section][].\n\n

\n" }, { "textRaw": "clearInterval(t)", "type": "global", "name": "clearInterval", "desc": "

Stop a timer that was previously created with [setInterval()][]. The callback\nwill not execute.\n\n

\n

The timer functions are global variables. See the [timers][] section.\n\n

\n" }, { "textRaw": "console", "name": "console", "type": "global", "desc": "

Used to print to stdout and stderr. See the [console][] section.\n\n

\n" }, { "textRaw": "global", "name": "global", "type": "global", "desc": "

In browsers, the top-level scope is the global scope. That means that in\nbrowsers if you're in the global scope var something will define a global\nvariable. In Node.js this is different. The top-level scope is not the global\nscope; var something inside an Node.js module will be local to that module.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object. See the [process object][] section.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object is a global object and can be accessed from anywhere.\nIt is an instance of [EventEmitter][].\n\n

\n", "events": [ { "textRaw": "Event: 'beforeExit'", "type": "event", "name": "beforeExit", "desc": "

This event is emitted when Node.js empties its event loop and has nothing else to\nschedule. Normally, Node.js exits when there is no work scheduled, but a listener\nfor 'beforeExit' can make asynchronous calls, and cause Node.js to continue.\n\n

\n

'beforeExit' is not emitted for conditions causing explicit termination, such as\n[process.exit()][] or uncaught exceptions, and should not be used as an\nalternative to the 'exit' event unless the intention is to schedule more work.\n\n

\n", "params": [] }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "desc": "

Emitted when the process is about to exit. There is no way to prevent the\nexiting of the event loop at this point, and once all 'exit' listeners have\nfinished running the process will exit. Therefore you must only perform\nsynchronous operations in this handler. This is a good hook to perform\nchecks on the module's state (like for unit tests). The callback takes one\nargument, the code the process is exiting with.\n\n

\n

This event is only emitted when Node.js exits explicitly by process.exit() or\nimplicitly by the event loop draining.\n\n

\n

Example of listening for 'exit':\n\n

\n
process.on('exit', (code) => {\n  // do *NOT* do this\n  setTimeout(() => {\n    console.log('This will not run');\n  }, 0);\n  console.log('About to exit with code:', code);\n});
\n", "params": [] }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Messages sent by [ChildProcess.send()][] are obtained using the 'message'\nevent on the child's process object.\n\n

\n" }, { "textRaw": "Event: 'rejectionHandled'", "type": "event", "name": "rejectionHandled", "desc": "

Emitted whenever a Promise was rejected and an error handler was attached to it\n(for example with .catch()) later than after an event loop turn. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • p the promise that was previously emitted in an 'unhandledRejection'\nevent, but which has now gained a rejection handler.
  • \n
\n

There is no notion of a top level for a promise chain at which rejections can\nalways be handled. Being inherently asynchronous in nature, a promise rejection\ncan be be handled at a future point in time — possibly much later than the\nevent loop turn it takes for the 'unhandledRejection' event to be emitted.\n\n

\n

Another way of stating this is that, unlike in synchronous code where there is\nan ever-growing list of unhandled exceptions, with promises there is a\ngrowing-and-shrinking list of unhandled rejections. In synchronous code, the\n'uncaughtException' event tells you when the list of unhandled exceptions\ngrows. And in asynchronous code, the 'unhandledRejection' event tells you\nwhen the list of unhandled rejections grows, while the 'rejectionHandled'\nevent tells you when the list of unhandled rejections shrinks.\n\n

\n

For example using the rejection detection hooks in order to keep a map of all\nthe rejected promise reasons at a given time:\n\n

\n
const unhandledRejections = new Map();\nprocess.on('unhandledRejection', (reason, p) => {\n  unhandledRejections.set(p, reason);\n});\nprocess.on('rejectionHandled', (p) => {\n  unhandledRejections.delete(p);\n});
\n

This map will grow and shrink over time, reflecting rejections that start\nunhandled and then become handled. You could record the errors in some error\nlog, either periodically (probably best for long-running programs, allowing\nyou to clear the map, which in the case of a very buggy program could grow\nindefinitely) or upon process exit (more convenient for scripts).\n\n

\n", "params": [] }, { "textRaw": "Event: 'uncaughtException'", "type": "event", "name": "uncaughtException", "desc": "

Emitted when an exception bubbles all the way back to the event loop. If a\nlistener is added for this exception, the default action (which is to print\na stack trace and exit) will not occur.\n\n

\n

Example of listening for 'uncaughtException':\n\n

\n
process.on('uncaughtException', (err) => {\n  console.log(`Caught exception: ${err}`);\n});\n\nsetTimeout(() => {\n  console.log('This will still run.');\n}, 500);\n\n// Intentionally cause an exception, but don't catch it.\nnonexistentFunc();\nconsole.log('This will not run.');
\n

Note that 'uncaughtException' is a very crude mechanism for exception\nhandling.\n\n

\n

Do not use it as the Node.js equivalent of On Error Resume Next. An\nunhandled exception means your application - and by extension Node.js itself -\nis in an undefined state. Blindly resuming means anything could happen.\n\n

\n

Think of resuming as pulling the power cord when you are upgrading your system.\nNine out of ten times nothing happens - but the 10th time, your system is bust.\n\n

\n

'uncaughtException' should be used to perform synchronous cleanup before\nshutting down the process. It is not safe to resume normal operation after\n'uncaughtException'. If you do use it, restart your application after every\nunhandled exception!\n\n

\n

You have been warned.\n\n

\n", "params": [] }, { "textRaw": "Event: 'unhandledRejection'", "type": "event", "name": "unhandledRejection", "desc": "

Emitted whenever a Promise is rejected and no error handler is attached to\nthe promise within a turn of the event loop. When programming with promises\nexceptions are encapsulated as rejected promises. Such promises can be caught\nand handled using [promise.catch(...)][] and rejections are propagated through\na promise chain. This event is useful for detecting and keeping track of\npromises that were rejected whose rejections were not handled yet. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • reason the object with which the promise was rejected (usually an [Error][]\ninstance).
  • \n
  • p the promise that was rejected.
  • \n
\n

Here is an example that logs every unhandled rejection to the console\n\n

\n
process.on('unhandledRejection', (reason, p) => {\n    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);\n    // application specific logging, throwing an error, or other logic here\n});
\n

For example, here is a rejection that will trigger the 'unhandledRejection'\nevent:\n\n

\n
somePromise.then((res) => {\n  return reportToUser(JSON.parse(res)); // note the typo\n}); // no `.catch` or `.then`
\n

Here is an example of a coding pattern that will also trigger\n'unhandledRejection':\n\n

\n
function SomeResource() {\n  // Initially set the loaded status to a rejected promise\n  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));\n}\n\nvar resource = new SomeResource();\n// no .catch or .then on resource.loaded for at least a turn
\n

In cases like this, you may not want to track the rejection as a developer\nerror like you would for other 'unhandledRejection' events. To address\nthis, you can either attach a dummy .catch(function() { }) handler to\nresource.loaded, preventing the 'unhandledRejection' event from being\nemitted, or you can use the 'rejectionHandled' event. Below is an\nexplanation of how to do that.\n\n

\n", "params": [] }, { "textRaw": "Signal Events", "name": "SIGINT, SIGHUP, etc.", "type": "event", "desc": "

Emitted when the processes receives a signal. See sigaction(2) for a list of\nstandard POSIX signal names such as SIGINT, SIGHUP, etc.\n\n

\n

Example of listening for SIGINT:\n\n

\n
// Start reading from stdin so we don't exit.\nprocess.stdin.resume();\n\nprocess.on('SIGINT', () => {\n  console.log('Got SIGINT.  Press Control-D to exit.');\n});
\n

An easy way to send the SIGINT signal is with Control-C in most terminal\nprograms.\n\n

\n

Note:\n\n

\n
    \n
  • SIGUSR1 is reserved by Node.js to start the debugger. It's possible to\ninstall a listener but that won't stop the debugger from starting.
  • \n
  • SIGTERM and SIGINT have default handlers on non-Windows platforms that resets\nthe terminal mode before exiting with code 128 + signal number. If one of\nthese signals has a listener installed, its default behavior will be removed\n(Node.js will no longer exit).
  • \n
  • SIGPIPE is ignored by default. It can have a listener installed.
  • \n
  • SIGHUP is generated on Windows when the console window is closed, and on other\nplatforms under various similar conditions, see signal(7). It can have a\nlistener installed, however Node.js will be unconditionally terminated by\nWindows about 10 seconds later. On non-Windows platforms, the default\nbehavior of SIGHUP is to terminate Node.js, but once a listener has been\ninstalled its default behavior will be removed.
  • \n
  • SIGTERM is not supported on Windows, it can be listened on.
  • \n
  • SIGINT from the terminal is supported on all platforms, and can usually be\ngenerated with CTRL+C (though this may be configurable). It is not generated\nwhen terminal raw mode is enabled.
  • \n
  • SIGBREAK is delivered on Windows when CTRL+BREAK is pressed, on non-Windows\nplatforms it can be listened on, but there is no way to send or generate it.
  • \n
  • SIGWINCH is delivered when the console has been resized. On Windows, this will\nonly happen on write to the console when the cursor is being moved, or when a\nreadable tty is used in raw mode.
  • \n
  • SIGKILL cannot have a listener installed, it will unconditionally terminate\nNode.js on all platforms.
  • \n
  • SIGSTOP cannot have a listener installed.
  • \n
\n

Note that Windows does not support sending Signals, but Node.js offers some\nemulation with process.kill(), and child_process.kill(). Sending signal 0\ncan be used to test for the existence of a process. Sending SIGINT,\nSIGTERM, and SIGKILL cause the unconditional termination of the target\nprocess.\n\n

\n", "params": [] } ], "modules": [ { "textRaw": "Exit Codes", "name": "exit_codes", "desc": "

Node.js will normally exit with a 0 status code when no more async\noperations are pending. The following status codes are used in other\ncases:\n\n

\n
    \n
  • 1 Uncaught Fatal Exception - There was an uncaught exception,\nand it was not handled by a domain or an 'uncaughtException' event\nhandler.
  • \n
  • 2 - Unused (reserved by Bash for builtin misuse)
  • \n
  • 3 Internal JavaScript Parse Error - The JavaScript source code\ninternal in Node.js's bootstrapping process caused a parse error. This\nis extremely rare, and generally can only happen during development\nof Node.js itself.
  • \n
  • 4 Internal JavaScript Evaluation Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process failed to\nreturn a function value when evaluated. This is extremely rare, and\ngenerally can only happen during development of Node.js itself.
  • \n
  • 5 Fatal Error - There was a fatal unrecoverable error in V8.\nTypically a message will be printed to stderr with the prefix FATAL\nERROR.
  • \n
  • 6 Non-function Internal Exception Handler - There was an\nuncaught exception, but the internal fatal exception handler\nfunction was somehow set to a non-function, and could not be called.
  • \n
  • 7 Internal Exception Handler Run-Time Failure - There was an\nuncaught exception, and the internal fatal exception handler\nfunction itself threw an error while attempting to handle it. This\ncan happen, for example, if a process.on('uncaughtException') or\ndomain.on('error') handler throws an error.
  • \n
  • 8 - Unused. In previous versions of Node.js, exit code 8 sometimes\nindicated an uncaught exception.
  • \n
  • 9 - Invalid Argument - Either an unknown option was specified,\nor an option requiring a value was provided without a value.
  • \n
  • 10 Internal JavaScript Run-Time Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process threw an error\nwhen the bootstrapping function was called. This is extremely rare,\nand generally can only happen during development of Node.js itself.
  • \n
  • 12 Invalid Debug Argument - The --debug and/or --debug-brk\noptions were set, but an invalid port number was chosen.
  • \n
  • >128 Signal Exits - If Node.js receives a fatal signal such as\nSIGKILL or SIGHUP, then its exit code will be 128 plus the\nvalue of the signal code. This is a standard Unix practice, since\nexit codes are defined to be 7-bit integers, and signal exits set\nthe high-order bit, and then contain the value of the signal code.
  • \n
\n", "type": "module", "displayName": "Exit Codes" } ], "methods": [ { "textRaw": "process.abort()", "type": "method", "name": "abort", "desc": "

This causes Node.js to emit an abort. This will cause Node.js to exit and\ngenerate a core file.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.chdir(directory)", "type": "method", "name": "chdir", "desc": "

Changes the current working directory of the process or throws an exception if that fails.\n\n

\n
console.log(`Starting directory: ${process.cwd()}`);\ntry {\n  process.chdir('/tmp');\n  console.log(`New directory: ${process.cwd()}`);\n}\ncatch (err) {\n  console.log(`chdir: ${err}`);\n}
\n", "signatures": [ { "params": [ { "name": "directory" } ] } ] }, { "textRaw": "process.cwd()", "type": "method", "name": "cwd", "desc": "

Returns the current working directory of the process.\n\n

\n
console.log(`Current directory: ${process.cwd()}`);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.disconnect()", "type": "method", "name": "disconnect", "desc": "

Close the IPC channel to the parent process, allowing this child to exit\ngracefully once there are no other connections keeping it alive.\n\n

\n

Identical to the parent process's [ChildProcess.disconnect()][].\n\n

\n

If Node.js was not spawned with an IPC channel, process.disconnect() will be\nundefined.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.exit([code])", "type": "method", "name": "exit", "desc": "

Ends the process with the specified code. If omitted, exit uses the\n'success' code 0.\n\n

\n

To exit with a 'failure' code:\n\n

\n
process.exit(1);
\n

The shell that executed Node.js should see the exit code as 1.\n\n\n

\n", "signatures": [ { "params": [ { "name": "code", "optional": true } ] } ] }, { "textRaw": "process.getegid()", "type": "method", "name": "getegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective group identity of the process. (See getegid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.geteuid()", "type": "method", "name": "geteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective user identity of the process. (See geteuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.geteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgid()", "type": "method", "name": "getgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the group identity of the process. (See getgid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgroups()", "type": "method", "name": "getgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Returns an array with the supplementary group IDs. POSIX leaves it unspecified\nif the effective group ID is included but Node.js ensures it always is.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getuid()", "type": "method", "name": "getuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the user identity of the process. (See getuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.getuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.hrtime()", "type": "method", "name": "hrtime", "desc": "

Returns the current high-resolution real time in a [seconds, nanoseconds]\ntuple Array. It is relative to an arbitrary time in the past. It is not\nrelated to the time of day and therefore not subject to clock drift. The\nprimary use is for measuring performance between intervals.\n\n

\n

You may pass in the result of a previous call to process.hrtime() to get\na diff reading, useful for benchmarks and measuring intervals:\n\n

\n
var time = process.hrtime();\n// [ 1800216, 25 ]\n\nsetTimeout(() => {\n  var diff = process.hrtime(time);\n  // [ 1, 552 ]\n\n  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);\n  // benchmark took 1000000527 nanoseconds\n}, 1000);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.initgroups(user, extra_group)", "type": "method", "name": "initgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Reads /etc/group and initializes the group access list, using all groups of\nwhich the user is a member. This is a privileged operation, meaning you need\nto be root or have the CAP_SETGID capability.\n\n

\n

user is a user name or user ID. extra_group is a group name or group ID.\n\n

\n

Some care needs to be taken when dropping privileges. Example:\n\n

\n
console.log(process.getgroups());         // [ 0 ]\nprocess.initgroups('bnoordhuis', 1000);   // switch user\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]\nprocess.setgid(1000);                     // drop root gid\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000 ]
\n", "signatures": [ { "params": [ { "name": "user" }, { "name": "extra_group" } ] } ] }, { "textRaw": "process.kill(pid[, signal])", "type": "method", "name": "kill", "desc": "

Send a signal to a process. pid is the process id and signal is the\nstring describing the signal to send. Signal names are strings like\nSIGINT or SIGHUP. If omitted, the signal will be SIGTERM.\nSee [Signal Events][] and kill(2) for more information.\n\n

\n

Will throw an error if target does not exist, and as a special case, a signal\nof 0 can be used to test for the existence of a process. Windows platforms\nwill throw an error if the pid is used to kill a process group.\n\n

\n

Note that even though the name of this function is process.kill, it is really\njust a signal sender, like the kill system call. The signal sent may do\nsomething other than kill the target process.\n\n

\n

Example of sending a signal to yourself:\n\n

\n
process.on('SIGHUP', () => {\n  console.log('Got SIGHUP signal.');\n});\n\nsetTimeout(() => {\n  console.log('Exiting.');\n  process.exit(0);\n}, 100);\n\nprocess.kill(process.pid, 'SIGHUP');
\n

Note: When SIGUSR1 is received by Node.js it starts the debugger, see\n[Signal Events][].\n\n

\n", "signatures": [ { "params": [ { "name": "pid" }, { "name": "signal", "optional": true } ] } ] }, { "textRaw": "process.memoryUsage()", "type": "method", "name": "memoryUsage", "desc": "

Returns an object describing the memory usage of the Node.js process\nmeasured in bytes.\n\n

\n
const util = require('util');\n\nconsole.log(util.inspect(process.memoryUsage()));
\n

This will generate:\n\n

\n
{ rss: 4935680,\n  heapTotal: 1826816,\n  heapUsed: 650472 }
\n

heapTotal and heapUsed refer to V8's memory usage.\n\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.nextTick(callback[, arg][, ...])", "type": "method", "name": "nextTick", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] }, { "params": [ { "name": "callback" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ], "desc": "

Once the current event loop turn runs to completion, call the callback\nfunction.\n\n

\n

This is not a simple alias to [setTimeout(fn, 0)][], it's much more\nefficient. It runs before any additional I/O events (including\ntimers) fire in subsequent ticks of the event loop.\n\n

\n
console.log('start');\nprocess.nextTick(() => {\n  console.log('nextTick callback');\n});\nconsole.log('scheduled');\n// Output:\n// start\n// scheduled\n// nextTick callback
\n

This is important in developing APIs where you want to give the user the\nchance to assign event handlers after an object has been constructed,\nbut before any I/O has occurred.\n\n

\n
function MyThing(options) {\n  this.setupOptions(options);\n\n  process.nextTick(() => {\n    this.startDoingStuff();\n  }.bind(this));\n}\n\nvar thing = new MyThing();\nthing.getReadyForStuff();\n\n// thing.startDoingStuff() gets called now, not before.
\n

It is very important for APIs to be either 100% synchronous or 100%\nasynchronous. Consider this example:\n\n

\n
// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!\nfunction maybeSync(arg, cb) {\n  if (arg) {\n    cb();\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

This API is hazardous. If you do this:\n\n

\n
maybeSync(true, function() {\n  foo();\n});\nbar();
\n

then it's not clear whether foo() or bar() will be called first.\n\n

\n

This approach is much better:\n\n

\n
function definitelyAsync(arg, cb) {\n  if (arg) {\n    process.nextTick(cb);\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

Note: the nextTick queue is completely drained on each pass of the\nevent loop before additional I/O is processed. As a result,\nrecursively setting nextTick callbacks will block any I/O from\nhappening, just like a while(true); loop.\n\n

\n" }, { "textRaw": "process.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

When Node.js is spawned with an IPC channel attached, it can send messages to its\nparent process using process.send(). Each will be received as a\n['message'][] event on the parent's ChildProcess object.\n\n

\n

If Node.js was not spawned with an IPC channel, process.send() will be undefined.\n\n

\n" }, { "textRaw": "process.setegid(id)", "type": "method", "name": "setegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective group identity of the process. (See setegid(2).)\nThis accepts either a numerical ID or a groupname string. If a groupname\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.getegid && process.setegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n  try {\n    process.setegid(501);\n    console.log(`New gid: ${process.getegid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.seteuid(id)", "type": "method", "name": "seteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective user identity of the process. (See seteuid(2).)\nThis accepts either a numerical ID or a username string. If a username\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.geteuid && process.seteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n  try {\n    process.seteuid(501);\n    console.log(`New uid: ${process.geteuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgid(id)", "type": "method", "name": "setgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the group identity of the process. (See setgid(2).) This accepts either\na numerical ID or a groupname string. If a groupname is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getgid && process.setgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n  try {\n    process.setgid(501);\n    console.log(`New gid: ${process.getgid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgroups(groups)", "type": "method", "name": "setgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the supplementary group IDs. This is a privileged operation, meaning you\nneed to be root or have the CAP_SETGID capability.\n\n

\n

The list can contain group IDs, group names or both.\n\n

\n", "signatures": [ { "params": [ { "name": "groups" } ] } ] }, { "textRaw": "process.setuid(id)", "type": "method", "name": "setuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the user identity of the process. (See setuid(2).) This accepts either\na numerical ID or a username string. If a username is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getuid && process.setuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n  try {\n    process.setuid(501);\n    console.log(`New uid: ${process.getuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.umask([mask])", "type": "method", "name": "umask", "desc": "

Sets or reads the process's file mode creation mask. Child processes inherit\nthe mask from the parent process. Returns the old mask if mask argument is\ngiven, otherwise returns the current mask.\n\n

\n
const newmask = 0o022;\nconst oldmask = process.umask(newmask);\nconsole.log(\n  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`\n);
\n", "signatures": [ { "params": [ { "name": "mask", "optional": true } ] } ] }, { "textRaw": "process.uptime()", "type": "method", "name": "uptime", "desc": "

Number of seconds Node.js has been running.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "process.arch", "name": "arch", "desc": "

What processor architecture you're running on: 'arm', 'ia32', or 'x64'.\n\n

\n
console.log('This processor architecture is ' + process.arch);
\n" }, { "textRaw": "process.argv", "name": "argv", "desc": "

An array containing the command line arguments. The first element will be\n'node', the second element will be the name of the JavaScript file. The\nnext elements will be any additional command line arguments.\n\n

\n
// print process.argv\nprocess.argv.forEach((val, index, array) => {\n  console.log(`${index}: ${val}`);\n});
\n

This will generate:\n\n

\n
$ node process-2.js one two=three four\n0: node\n1: /Users/mjr/work/node/process-2.js\n2: one\n3: two=three\n4: four
\n" }, { "textRaw": "process.config", "name": "config", "desc": "

An Object containing the JavaScript representation of the configure options\nthat were used to compile the current Node.js executable. This is the same as\nthe config.gypi file that was produced when running the ./configure script.\n\n

\n

An example of the possible output looks like:\n\n

\n
{ target_defaults:\n   { cflags: [],\n     default_configuration: 'Release',\n     defines: [],\n     include_dirs: [],\n     libraries: [] },\n  variables:\n   { host_arch: 'x64',\n     node_install_npm: 'true',\n     node_prefix: '',\n     node_shared_cares: 'false',\n     node_shared_http_parser: 'false',\n     node_shared_libuv: 'false',\n     node_shared_zlib: 'false',\n     node_use_dtrace: 'false',\n     node_use_openssl: 'true',\n     node_shared_openssl: 'false',\n     strict_aliasing: 'true',\n     target_arch: 'x64',\n     v8_use_snapshot: 'true' } }
\n", "properties": [ { "textRaw": "`connected` {Boolean} Set to false after `process.disconnect()` is called ", "name": "connected", "desc": "

If process.connected is false, it is no longer possible to send messages.\n\n

\n", "shortDesc": "Set to false after `process.disconnect()` is called" } ] }, { "textRaw": "process.env", "name": "env", "desc": "

An object containing the user environment. See environ(7).\n\n

\n

An example of this object looks like:\n\n

\n
{ TERM: 'xterm-256color',\n  SHELL: '/usr/local/bin/bash',\n  USER: 'maciej',\n  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',\n  PWD: '/Users/maciej',\n  EDITOR: 'vim',\n  SHLVL: '1',\n  HOME: '/Users/maciej',\n  LOGNAME: 'maciej',\n  _: '/usr/local/bin/node' }
\n

You can write to this object, but changes won't be reflected outside of your\nprocess. That means that the following won't work:\n\n

\n
$ node -e 'process.env.foo = "bar"' && echo $foo
\n

But this will:\n\n

\n
process.env.foo = 'bar';\nconsole.log(process.env.foo);
\n" }, { "textRaw": "process.execArgv", "name": "execArgv", "desc": "

This is the set of Node.js-specific command line options from the\nexecutable that started the process. These options do not show up in\nprocess.argv, and do not include the Node.js executable, the name of\nthe script, or any options following the script name. These options\nare useful in order to spawn child processes with the same execution\nenvironment as the parent.\n\n

\n

Example:\n\n

\n
$ node --harmony script.js --version
\n

results in process.execArgv:\n\n

\n
['--harmony']
\n

and process.argv:\n\n

\n
['/usr/local/bin/node', 'script.js', '--version']
\n" }, { "textRaw": "process.execPath", "name": "execPath", "desc": "

This is the absolute pathname of the executable that started the process.\n\n

\n

Example:\n\n

\n
/usr/local/bin/node
\n" }, { "textRaw": "process.exitCode", "name": "exitCode", "desc": "

A number which will be the process exit code, when the process either\nexits gracefully, or is exited via [process.exit()][] without specifying\na code.\n\n

\n

Specifying a code to process.exit(code) will override any previous\nsetting of process.exitCode.\n\n\n

\n" }, { "textRaw": "process.mainModule", "name": "mainModule", "desc": "

Alternate way to retrieve [require.main][]. The difference is that if the main\nmodule changes at runtime, require.main might still refer to the original main\nmodule in modules that were required before the change occurred. Generally it's\nsafe to assume that the two refer to the same module.\n\n

\n

As with require.main, it will be undefined if there was no entry script.\n\n

\n" }, { "textRaw": "process.pid", "name": "pid", "desc": "

The PID of the process.\n\n

\n
console.log(`This process is pid ${process.pid}`);
\n" }, { "textRaw": "process.platform", "name": "platform", "desc": "

What platform you're running on:\n'darwin', 'freebsd', 'linux', 'sunos' or 'win32'\n\n

\n
console.log(`This platform is ${process.platform}`);
\n" }, { "textRaw": "process.release", "name": "release", "desc": "

An Object containing metadata related to the current release, including URLs\nfor the source tarball and headers-only tarball.\n\n

\n

process.release contains the following properties:\n\n

\n
    \n
  • name: a string with a value that will always be 'node' for Node.js. For\nlegacy io.js releases, this will be 'io.js'.
  • \n
  • sourceUrl: a complete URL pointing to a .tar.gz file containing the\nsource of the current release.
  • \n
  • headersUrl: a complete URL pointing to a .tar.gz file containing only\nthe header files for the current release. This file is significantly smaller\nthan the full source file and can be used for compiling add-ons against\nNode.js.
  • \n
  • libUrl: a complete URL pointing to an node.lib file matching the\narchitecture and version of the current release. This file is used for\ncompiling add-ons against Node.js. This property is only present on Windows\nbuilds of Node.js and will be missing on all other platforms.
  • \n
\n

e.g.\n\n

\n
{ name: 'node',\n  sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz',\n  headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz',\n  libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' }
\n

In custom builds from non-release versions of the source tree, only the\nname property may be present. The additional properties should not be\nrelied upon to exist.\n\n

\n" }, { "textRaw": "process.stderr", "name": "stderr", "desc": "

A writable stream to stderr (on fd 2).\n\n

\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the finish\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n" }, { "textRaw": "process.stdin", "name": "stdin", "desc": "

A Readable Stream for stdin (on fd 0).\n\n

\n

Example of opening standard input and listening for both events:\n\n

\n
process.stdin.setEncoding('utf8');\n\nprocess.stdin.on('readable', () => {\n  var chunk = process.stdin.read();\n  if (chunk !== null) {\n    process.stdout.write(`data: ${chunk}`);\n  }\n});\n\nprocess.stdin.on('end', () => {\n  process.stdout.write('end');\n});
\n

As a Stream, process.stdin can also be used in "old" mode that is compatible\nwith scripts written for node.js prior to v0.10.\nFor more information see [Stream compatibility][].\n\n

\n

In "old" Streams mode the stdin stream is paused by default, so one\nmust call process.stdin.resume() to read from it. Note also that calling\nprocess.stdin.resume() itself would switch stream to "old" mode.\n\n

\n

If you are starting a new project you should prefer a more recent "new" Streams\nmode over "old" one.\n\n

\n" }, { "textRaw": "process.stdout", "name": "stdout", "desc": "

A Writable Stream to stdout (on fd 1).\n\n

\n

For example, a console.log equivalent could look like this:\n\n

\n
console.log = function(msg) {\n  process.stdout.write(`${msg}\\n`);\n};
\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the 'finish'\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n

To check if Node.js is being run in a TTY context, read the isTTY property\non process.stderr, process.stdout, or process.stdin:\n\n

\n
$ node -p "Boolean(process.stdin.isTTY)"\ntrue\n$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"\nfalse\n\n$ node -p "Boolean(process.stdout.isTTY)"\ntrue\n$ node -p "Boolean(process.stdout.isTTY)" | cat\nfalse
\n

See [the tty docs][] for more information.\n\n

\n" }, { "textRaw": "process.title", "name": "title", "desc": "

Getter/setter to set what is displayed in ps.\n\n

\n

When used as a setter, the maximum length is platform-specific and probably\nshort.\n\n

\n

On Linux and OS X, it's limited to the size of the binary name plus the\nlength of the command line arguments because it overwrites the argv memory.\n\n

\n

v0.8 allowed for longer process title strings by also overwriting the environ\nmemory but that was potentially insecure/confusing in some (rather obscure)\ncases.\n\n

\n" }, { "textRaw": "process.version", "name": "version", "desc": "

A compiled-in property that exposes NODE_VERSION.\n\n

\n
console.log(`Version: ${process.version}`);
\n" }, { "textRaw": "process.versions", "name": "versions", "desc": "

A property exposing version strings of Node.js and its dependencies.\n\n

\n
console.log(process.versions);
\n

Will print something like:\n\n

\n
{ http_parser: '2.3.0',\n  node: '1.1.1',\n  v8: '4.1.0.14',\n  uv: '1.3.0',\n  zlib: '1.2.8',\n  ares: '1.10.0-DEV',\n  modules: '43',\n  icu: '55.1',\n  openssl: '1.0.1k' }
\n" } ] } ], "vars": [ { "textRaw": "__dirname", "name": "__dirname", "type": "var", "desc": "

The name of the directory that the currently executing script resides in.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__dirname);\n// /Users/mjr
\n

__dirname isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "__filename", "name": "__filename", "type": "var", "desc": "

The filename of the code being executed. This is the resolved absolute path\nof this code file. For a main program this is not necessarily the same\nfilename used in the command line. The value inside a module is the path\nto that module file.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__filename);\n// /Users/mjr/example.js
\n

__filename isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "exports", "name": "exports", "type": "var", "desc": "

A reference to the module.exports that is shorter to type.\nSee [module system documentation][] for details on when to use exports and\nwhen to use module.exports.\n\n

\n

exports isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "module", "name": "module", "type": "var", "desc": "

A reference to the current module. In particular\nmodule.exports is used for defining what a module exports and makes\navailable through require().\n\n

\n

module isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "require()", "type": "var", "name": "require", "desc": "

To require modules. See the [Modules][] section. require isn't actually a\nglobal but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`cache` {Object} ", "name": "cache", "desc": "

Modules are cached in this object when they are required. By deleting a key\nvalue from this object, the next require will reload the module.\n\n

\n" }, { "textRaw": "`extensions` {Object} ", "name": "extensions", "stability": 0, "stabilityText": "Deprecated", "desc": "

Instruct require on how to handle certain file extensions.\n\n

\n

Process files with the extension .sjs as .js:\n\n

\n
require.extensions['.sjs'] = require.extensions['.js'];
\n

Deprecated In the past, this list has been used to load\nnon-JavaScript modules into Node.js by compiling them on-demand.\nHowever, in practice, there are much better ways to do this, such as\nloading modules via some other Node.js program, or compiling them to\nJavaScript ahead of time.\n\n

\n

Since the Module system is locked, this feature will probably never go\naway. However, it may have subtle bugs and complexities that are best\nleft untouched.\n\n

\n" } ], "methods": [ { "textRaw": "require.resolve()", "type": "method", "name": "resolve", "desc": "

Use the internal require() machinery to look up the location of a module,\nbut rather than loading the module, just return the resolved filename.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "clearTimeout(t)", "type": "method", "name": "clearTimeout", "desc": "

Stop a timer that was previously created with [setTimeout()][]. The callback will\nnot execute.\n\n

\n", "signatures": [ { "params": [ { "name": "t" } ] } ] }, { "textRaw": "setInterval(cb, ms)", "type": "method", "name": "setInterval", "desc": "

Run callback cb repeatedly every ms milliseconds. Note that the actual\ninterval may vary, depending on external factors like OS timer granularity and\nsystem load. It's never less than ms but it may be longer.\n\n

\n

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] }, { "textRaw": "setTimeout(cb, ms)", "type": "method", "name": "setTimeout", "desc": "

Run callback cb after at least ms milliseconds. The actual delay depends\non external factors like OS timer granularity and system load.\n\n

\n

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] } ] } ], "modules": [ { "textRaw": "Addons", "name": "addons", "desc": "

Addons are dynamically-linked shared objects. They can provide glue to C and\nC++ libraries. The API (at the moment) is rather complex, involving\nknowledge of several libraries:\n\n

\n
    \n
  • V8 JavaScript, a C++ library. Used for interfacing with JavaScript:\ncreating objects, calling functions, etc. Documented mostly in the\nv8.h header file (deps/v8/include/v8.h in the Node.js source\ntree), which is also available [online][].

    \n
  • \n
  • [libuv][], C event loop library. Anytime one needs to wait for a file\ndescriptor to become readable, wait for a timer, or wait for a signal\nto be received, one will need to interface with libuv. That is, if you\nperform any I/O, libuv will need to be used.

    \n
  • \n
  • Internal Node.js libraries. The most important class is node::ObjectWrap\nwhich you will likely want to derive from.

    \n
  • \n
  • Others. Look in deps/ for what else is available.

    \n
  • \n
\n

Node.js statically compiles all its dependencies into the executable.\nWhen compiling your module, you don't need to worry about linking to\nany of these libraries.\n\n

\n

All of the following examples are available for [download][] and may\nbe used as a starting-point for your own Addon.\n\n

\n", "modules": [ { "textRaw": "Hello world", "name": "hello_world", "desc": "

To get started, let's make a small Addon which is the C++ equivalent of\nthe following JavaScript code:\n\n

\n
module.exports.hello = function() { return 'world'; };
\n

First we create a file hello.cc:\n\n

\n
// hello.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Method(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));\n}\n\nvoid init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, "hello", Method);\n}\n\nNODE_MODULE(addon, init)\n\n}  // namespace demo
\n

Note that all Node.js addons must export an initialization function:\n\n

\n
void Initialize(Local<Object> exports);\nNODE_MODULE(module_name, Initialize)
\n

There is no semi-colon after NODE_MODULE as it's not a function (see\nnode.h).\n\n

\n

The module_name needs to match the filename of the final binary (excluding\nthe .node suffix).\n\n

\n

The source code needs to be built into addon.node, the binary Addon. To\ndo this, we create a file called binding.gyp which describes the configuration\nto build your module in a JSON-like format. This file gets compiled by\n[node-gyp][].\n\n

\n
{\n  "targets": [\n    {\n      "target_name": "addon",\n      "sources": [ "hello.cc" ]\n    }\n  ]\n}
\n

The next step is to generate the appropriate project build files for the\ncurrent platform. Use node-gyp configure for that.\n\n

\n

Now you will have either a Makefile (on Unix platforms) or a vcxproj file\n(on Windows) in the build/ directory. Next, invoke the node-gyp build\ncommand.\n\n

\n

Now you have your compiled .node bindings file! The compiled bindings end up\nin build/Release/.\n\n

\n

You can now use the binary addon in a Node.js project hello.js by pointing\nrequire to the recently built hello.node module:\n\n

\n
// hello.js\nconst addon = require('./build/Release/addon');\n\nconsole.log(addon.hello()); // 'world'
\n

Please see patterns below for further information or\n

\n

https://github.com/arturadib/node-qt for an example in production.\n\n\n

\n", "type": "module", "displayName": "Hello world" }, { "textRaw": "Addon patterns", "name": "addon_patterns", "desc": "

Below are some addon patterns to help you get started. Consult the online\n[v8 reference][] for help with the various v8 calls, and v8's\n[Embedder's Guide][] for an explanation of several concepts used such as\nhandles, scopes, function templates, etc.\n\n

\n

In order to use these examples, you need to compile them using node-gyp.\nCreate the following binding.gyp file:\n\n

\n
{\n  "targets": [\n    {\n      "target_name": "addon",\n      "sources": [ "addon.cc" ]\n    }\n  ]\n}
\n

In cases where there is more than one .cc file, simply add the file name to\nthe sources array. For example:\n\n

\n
"sources": ["addon.cc", "myexample.cc"]
\n

Now that you have your binding.gyp ready, you can configure and build the\naddon:\n\n

\n
$ node-gyp configure build
\n", "modules": [ { "textRaw": "Function arguments", "name": "function_arguments", "desc": "

The following pattern illustrates how to read arguments from JavaScript\nfunction calls and return a result. This is the main and only needed source\naddon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Exception;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.Length() < 2) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, "Wrong number of arguments")));\n    return;\n  }\n\n  if (!args[0]->IsNumber() || !args[1]->IsNumber()) {\n    isolate->ThrowException(Exception::TypeError(\n        String::NewFromUtf8(isolate, "Wrong arguments")));\n    return;\n  }\n\n  double value = args[0]->NumberValue() + args[1]->NumberValue();\n  Local<Number> num = Number::New(isolate, value);\n\n  args.GetReturnValue().Set(num);\n}\n\nvoid Init(Local<Object> exports) {\n  NODE_SET_METHOD(exports, "add", Add);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

You can test it with the following JavaScript snippet:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nconsole.log( 'This should be eight:', addon.add(3,5) );
\n", "type": "module", "displayName": "Function arguments" }, { "textRaw": "Callbacks", "name": "callbacks", "desc": "

You can pass JavaScript functions to a C++ function and execute them from\nthere. Here's addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Null;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid RunCallback(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  Local<Function> cb = Local<Function>::Cast(args[0]);\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { String::NewFromUtf8(isolate, "hello world") };\n  cb->Call(Null(isolate), argc, argv);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", RunCallback);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

Note that this example uses a two-argument form of Init() that receives\nthe full module object as the second argument. This allows the addon\nto completely overwrite exports with a single function instead of\nadding the function as a property of exports.\n\n

\n

To test it, run the following JavaScript snippet:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\naddon(function(msg){\n  console.log(msg); // 'hello world'\n});
\n", "type": "module", "displayName": "Callbacks" }, { "textRaw": "Object factory", "name": "object_factory", "desc": "

You can create and return new objects from within a C++ function with this\naddon.cc pattern, which returns an object with property msg that echoes\nthe string passed to createObject():\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<Object> obj = Object::New(isolate);\n  obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString());\n\n  args.GetReturnValue().Set(obj);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", CreateObject);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

To test it in JavaScript:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj1 = addon('hello');\nvar obj2 = addon('world');\nconsole.log(obj1.msg+' '+obj2.msg); // 'hello world'
\n", "type": "module", "displayName": "Object factory" }, { "textRaw": "Function factory", "name": "function_factory", "desc": "

This pattern illustrates how to create and return a JavaScript function that\nwraps a C++ function:\n\n

\n
// addon.cc\n#include <node.h>\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid MyFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));\n}\n\nvoid CreateFunction(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, MyFunction);\n  Local<Function> fn = tpl->GetFunction();\n\n  // omit this to make it anonymous\n  fn->SetName(String::NewFromUtf8(isolate, "theFunction"));\n\n  args.GetReturnValue().Set(fn);\n}\n\nvoid Init(Local<Object> exports, Local<Object> module) {\n  NODE_SET_METHOD(module, "exports", CreateFunction);\n}\n\nNODE_MODULE(addon, Init)\n\n}  // namespace demo
\n

To test:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar fn = addon();\nconsole.log(fn()); // 'hello world'
\n", "type": "module", "displayName": "Function factory" }, { "textRaw": "Wrapping C++ objects", "name": "wrapping_c++_objects", "desc": "

Here, we will create a wrapper for a C++ object/class MyObject that can be\ninstantiated in JavaScript through the new operator. First, prepare the main\nmodule addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Local;\nusing v8::Object;\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

Then, in myobject.h, make your wrapper inherit from node::ObjectWrap:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Local<v8::Object> exports);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

And in myobject.cc, implement the various methods that you want to expose.\nHere we expose the method plusOne by adding it to the constructor's\nprototype:\n\n

\n
// myobject.cc\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Local<Object> exports) {\n  Isolate* isolate = exports->GetIsolate();\n\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n  exports->Set(String::NewFromUtf8(isolate, "MyObject"),\n               tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj = new addon.MyObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13
\n", "type": "module", "displayName": "Wrapping C++ objects" }, { "textRaw": "Factory of wrapped objects", "name": "factory_of_wrapped_objects", "desc": "

This is useful when you want to be able to create native objects without\nexplicitly instantiating them with the new operator in JavaScript. For\nexample:\n\n

\n
var obj = addon.createObject();\n// instead of:\n// var obj = new addon.Object();
\n

Let's register our createObject method in addon.cc:\n\n

\n
// addon.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid InitAll(Local<Object> exports, Local<Object> module) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(module, "exports", CreateObject);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

In myobject.h, we now introduce the static method NewInstance that takes\ncare of instantiating the object. In other words, it does the job of new in\nJavaScript:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static void PlusOne(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

The implementation is similar to the above in myobject.cc:\n\n

\n
// myobject.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  // Prototype\n  NODE_SET_PROTOTYPE_METHOD(tpl, "plusOne", PlusOne);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Object> instance = cons->NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\nvoid MyObject::PlusOne(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.Holder());\n  obj->value_ += 1;\n\n  args.GetReturnValue().Set(Number::New(isolate, obj->value_));\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst createObject = require('./build/Release/addon');\n\nvar obj = createObject(10);\nconsole.log( obj.plusOne() ); // 11\nconsole.log( obj.plusOne() ); // 12\nconsole.log( obj.plusOne() ); // 13\n\nvar obj2 = createObject(20);\nconsole.log( obj2.plusOne() ); // 21\nconsole.log( obj2.plusOne() ); // 22\nconsole.log( obj2.plusOne() ); // 23
\n", "type": "module", "displayName": "Factory of wrapped objects" }, { "textRaw": "Passing wrapped objects around", "name": "passing_wrapped_objects_around", "desc": "

In addition to wrapping and returning C++ objects, you can pass them around\nby unwrapping them with the Node.js helper function node::ObjectWrap::Unwrap.\nIn the following addon.cc, we introduce a function add() that can take on\ntwo MyObject objects:\n\n

\n
// addon.cc\n#include <node.h>\n#include <node_object_wrap.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::FunctionCallbackInfo;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Number;\nusing v8::Object;\nusing v8::String;\nusing v8::Value;\n\nvoid CreateObject(const FunctionCallbackInfo<Value>& args) {\n  MyObject::NewInstance(args);\n}\n\nvoid Add(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(\n      args[0]->ToObject());\n  MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(\n      args[1]->ToObject());\n\n  double sum = obj1->value() + obj2->value();\n  args.GetReturnValue().Set(Number::New(isolate, sum));\n}\n\nvoid InitAll(Local<Object> exports) {\n  MyObject::Init(exports->GetIsolate());\n\n  NODE_SET_METHOD(exports, "createObject", CreateObject);\n  NODE_SET_METHOD(exports, "add", Add);\n}\n\nNODE_MODULE(addon, InitAll)\n\n}  // namespace demo
\n

To make things interesting, we introduce a public method in myobject.h so we\ncan probe private values after unwrapping the object:\n\n

\n
// myobject.h\n#ifndef MYOBJECT_H\n#define MYOBJECT_H\n\n#include <node.h>\n#include <node_object_wrap.h>\n\nnamespace demo {\n\nclass MyObject : public node::ObjectWrap {\n public:\n  static void Init(v8::Isolate* isolate);\n  static void NewInstance(const v8::FunctionCallbackInfo<v8::Value>& args);\n  inline double value() const { return value_; }\n\n private:\n  explicit MyObject(double value = 0);\n  ~MyObject();\n\n  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);\n  static v8::Persistent<v8::Function> constructor;\n  double value_;\n};\n\n}  // namespace demo\n\n#endif
\n

The implementation of myobject.cc is similar to before:\n\n

\n
// myobject.cc\n#include <node.h>\n#include "myobject.h"\n\nnamespace demo {\n\nusing v8::Function;\nusing v8::FunctionCallbackInfo;\nusing v8::FunctionTemplate;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\nusing v8::Persistent;\nusing v8::String;\nusing v8::Value;\n\nPersistent<Function> MyObject::constructor;\n\nMyObject::MyObject(double value) : value_(value) {\n}\n\nMyObject::~MyObject() {\n}\n\nvoid MyObject::Init(Isolate* isolate) {\n  // Prepare constructor template\n  Local<FunctionTemplate> tpl = FunctionTemplate::New(isolate, New);\n  tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject"));\n  tpl->InstanceTemplate()->SetInternalFieldCount(1);\n\n  constructor.Reset(isolate, tpl->GetFunction());\n}\n\nvoid MyObject::New(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  if (args.IsConstructCall()) {\n    // Invoked as constructor: `new MyObject(...)`\n    double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();\n    MyObject* obj = new MyObject(value);\n    obj->Wrap(args.This());\n    args.GetReturnValue().Set(args.This());\n  } else {\n    // Invoked as plain function `MyObject(...)`, turn into construct call.\n    const int argc = 1;\n    Local<Value> argv[argc] = { args[0] };\n    Local<Function> cons = Local<Function>::New(isolate, constructor);\n    args.GetReturnValue().Set(cons->NewInstance(argc, argv));\n  }\n}\n\nvoid MyObject::NewInstance(const FunctionCallbackInfo<Value>& args) {\n  Isolate* isolate = args.GetIsolate();\n\n  const unsigned argc = 1;\n  Local<Value> argv[argc] = { args[0] };\n  Local<Function> cons = Local<Function>::New(isolate, constructor);\n  Local<Object> instance = cons->NewInstance(argc, argv);\n\n  args.GetReturnValue().Set(instance);\n}\n\n}  // namespace demo
\n

Test it with:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');\n\nvar obj1 = addon.createObject(10);\nvar obj2 = addon.createObject(20);\nvar result = addon.add(obj1, obj2);\n\nconsole.log(result); // 30
\n", "type": "module", "displayName": "Passing wrapped objects around" }, { "textRaw": "AtExit hooks", "name": "atexit_hooks", "modules": [ { "textRaw": "void AtExit(callback, args)", "name": "void_atexit(callback,_args)", "desc": "

Registers exit hooks that run after the event loop has ended but before the VM\nis killed.\n\n

\n

Callbacks are run in last-in first-out order. AtExit takes two parameters:\na pointer to a callback function to run at exit, and a pointer to untyped\ncontext data to be passed to that callback.\n\n

\n

The file addon.cc implements AtExit below:\n\n

\n
// addon.cc\n#undef NDEBUG\n#include <assert.h>\n#include <stdlib.h>\n#include <node.h>\n\nnamespace demo {\n\nusing node::AtExit;\nusing v8::HandleScope;\nusing v8::Isolate;\nusing v8::Local;\nusing v8::Object;\n\nstatic char cookie[] = "yum yum";\nstatic int at_exit_cb1_called = 0;\nstatic int at_exit_cb2_called = 0;\n\nstatic void at_exit_cb1(void* arg) {\n  Isolate* isolate = static_cast<Isolate*>(arg);\n  HandleScope scope(isolate);\n  Local<Object> obj = Object::New(isolate);\n  assert(!obj.IsEmpty()); // assert VM is still alive\n  assert(obj->IsObject());\n  at_exit_cb1_called++;\n}\n\nstatic void at_exit_cb2(void* arg) {\n  assert(arg == static_cast<void*>(cookie));\n  at_exit_cb2_called++;\n}\n\nstatic void sanity_check(void*) {\n  assert(at_exit_cb1_called == 1);\n  assert(at_exit_cb2_called == 2);\n}\n\nvoid init(Local<Object> exports) {\n  AtExit(sanity_check);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb2, cookie);\n  AtExit(at_exit_cb1, exports->GetIsolate());\n}\n\nNODE_MODULE(addon, init);\n\n}  // namespace demo
\n

Test in JavaScript by running:\n\n

\n
// test.js\nconst addon = require('./build/Release/addon');
\n", "type": "module", "displayName": "void AtExit(callback, args)" } ], "type": "module", "displayName": "AtExit hooks" } ], "type": "module", "displayName": "Addon patterns" } ], "type": "module", "displayName": "Addons" }, { "textRaw": "Assert", "name": "assert", "stability": 3, "stabilityText": "Locked", "desc": "

The assert module provides a simple set of assertion tests that can be used to\ntest invariants. The module is intended for internal use by Node.js, but can be\nused in application code via require('assert'). However, assert is not a\ntesting framework, and is not intended to be used as a general purpose assertion\nlibrary.\n\n

\n

The API for the assert module is [Locked][]. This means that there will be no\nadditions or changes to any of the methods implemented and exposed by\nthe module.\n\n

\n", "methods": [ { "textRaw": "assert(value[, message]), assert.ok(value[, message])", "type": "method", "name": "ok", "desc": "

Tests if value is truthy. It is equivalent to\nassert.equal(!!value, true, message).\n\n

\n

If value is not truthy, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n
const assert = require('assert');\n\nassert(true);  // OK\nassert(1);     // OK\nassert(false);\n  // throws "AssertionError: false == true"\nassert(0);\n  // throws "AssertionError: 0 == true"\nassert(false, 'it\\'s false');\n  // throws "AssertionError: it's false"\n\nassert.ok(true);  // OK\nassert.ok(1);     // OK\nassert.ok(false);\n  // throws "AssertionError: false == true"\nassert.ok(0);\n  // throws "AssertionError: 0 == true"\nassert.ok(false, 'it\\'s false');\n  // throws "AssertionError: it's false"
\n", "signatures": [ { "params": [ { "name": "value" }, { "name": "message])" }, { "name": "assert.ok(value" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.deepEqual(actual, expected[, message])", "type": "method", "name": "deepEqual", "desc": "

Tests for deep equality between the actual and expected parameters.\nPrimitive values are compared with the equal comparison operator ( == ).\n\n

\n

Only enumerable "own" properties are considered. The deepEqual()\nimplementation does not test object prototypes, attached symbols, or\nnon-enumerable properties. This can lead to some potentially surprising\nresults. For example, the following example does not throw an AssertionError\nbecause the properties on the [Error][] object are non-enumerable:\n\n

\n
// WARNING: This does not throw an AssertionError!\nassert.deepEqual(Error('a'), Error('b'));
\n

"Deep" equality means that the enumerable "own" properties of child objects\nare evaluated also:\n\n

\n
const assert = require('assert');\n\nconst obj1 = {\n  a : {\n    b : 1\n  }\n};\nconst obj2 = {\n  a : {\n    b : 2\n  }\n};\nconst obj3 = {\n  a : {\n    b : 1\n  }\n}\nconst obj4 = Object.create(obj1);\n\nassert.deepEqual(obj1, obj1);\n  // OK, object is equal to itself\n\nassert.deepEqual(obj1, obj2);\n  // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }\n  // values of b are different\n\nassert.deepEqual(obj1, obj3);\n  // OK, objects are equal\n\nassert.deepEqual(obj1, obj4);\n  // AssertionError: { a: { b: 1 } } deepEqual {}\n  // Prototypes are ignored
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.deepStrictEqual(actual, expected[, message])", "type": "method", "name": "deepStrictEqual", "desc": "

Generally identical to assert.deepEqual with the exception that primitive\nvalues are compared using the strict equality operator ( === ).\n\n

\n
const assert = require('assert');\n\nassert.deepEqual({a:1}, {a:'1'});\n  // OK, because 1 == '1'\n\nassert.deepStrictEqual({a:1}, {a:'1'});\n  // AssertionError: { a: 1 } deepStrictEqual { a: '1' }\n  // because 1 !== '1' using strict equality
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.doesNotThrow(block[, error][, message])", "type": "method", "name": "doesNotThrow", "desc": "

Asserts that the function block does not throw an error. See\n[assert.throws()][] for more details.\n\n

\n

When assert.doesNotThrow() is called, it will immediately call the block\nfunction.\n\n

\n

If an error is thrown and it is the same type as that specified by the error\nparameter, then an AssertionError is thrown. If the error is of a different\ntype, or if the error parameter is undefined, the error is propagated back\nto the caller.\n\n

\n

The following, for instance, will throw the [TypeError][] because there is no\nmatching error type in the assertion:\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  SyntaxError\n);
\n

However, the following will result in an AssertionError with the message\n'Got unwanted exception (TypeError)..':\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  TypeError\n);
\n

If an AssertionError is thrown and a value is provided for the message\nparameter, the value of message will be appended to the AssertionError\nmessage:\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  TypeError,\n  'Whoops'\n);\n// Throws: AssertionError: Got unwanted exception (TypeError). Whoops
\n", "signatures": [ { "params": [ { "name": "block" }, { "name": "error", "optional": true }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.equal(actual, expected[, message])", "type": "method", "name": "equal", "desc": "

Tests shallow, coercive equality between the actual and expected parameters\nusing the equal comparison operator ( == ).\n\n

\n
const assert = require('assert');\n\nassert.equal(1, 1);\n  // OK, 1 == 1\nassert.equal(1, '1');\n  // OK, 1 == '1'\n\nassert.equal(1, 2);\n  // AssertionError: 1 == 2\nassert.equal({a: {b: 1}}, {a: {b: 1}});\n  //AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.fail(actual, expected, message, operator)", "type": "method", "name": "fail", "desc": "

Throws an AssertionError. If message is falsy, the error message is set as\nthe values of actual and expected separated by the provided operator.\nOtherwise, the error message is the value of message.\n\n

\n
const assert = require('assert');\n\nassert.fail(1, 2, undefined, '>');\n  // AssertionError: 1 > 2\n\nassert.fail(1, 2, 'whoops', '>');\n  // AssertionError: whoops
\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message" }, { "name": "operator" } ] } ] }, { "textRaw": "assert.ifError(value)", "type": "method", "name": "ifError", "desc": "

Throws value if value is truthy. This is useful when testing the error\nargument in callbacks.\n\n

\n
const assert = require('assert');\n\nassert.ifError(0); // OK\nassert.ifError(1); // Throws 1\nassert.ifError('error') // Throws 'error'\nassert.ifError(new Error()); // Throws Error
\n", "signatures": [ { "params": [ { "name": "value" } ] } ] }, { "textRaw": "assert.notDeepEqual(actual, expected[, message])", "type": "method", "name": "notDeepEqual", "desc": "

Tests for any deep inequality. Opposite of [assert.deepEqual][].\n\n

\n
const assert = require('assert');\n\nconst obj1 = {\n  a : {\n    b : 1\n  }\n};\nconst obj2 = {\n  a : {\n    b : 2\n  }\n};\nconst obj3 = {\n  a : {\n    b : 1\n  }\n}\nconst obj4 = Object.create(obj1);\n\nassert.deepEqual(obj1, obj1);\n  AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }\n\nassert.deepEqual(obj1, obj2);\n  // OK, obj1 and obj2 are not deeply equal\n\nassert.deepEqual(obj1, obj3);\n  // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }\n\nassert.deepEqual(obj1, obj4);\n  // OK, obj1 and obj2 are not deeply equal
\n

If the values are deeply equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notDeepStrictEqual(actual, expected[, message])", "type": "method", "name": "notDeepStrictEqual", "desc": "

Tests for deep strict inequality. Opposite of [assert.deepStrictEqual][].\n\n

\n
const assert = require('assert');\n\nassert.notDeepEqual({a:1}, {a:'1'});\n  // AssertionError: { a: 1 } notDeepEqual { a: '1' }\n\nassert.notDeepStrictEqual({a:1}, {a:'1'});\n  // OK
\n

If the values are deeply and strictly equal, an AssertionError is thrown\nwith a message property set equal to the value of the message parameter. If\nthe message parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notEqual(actual, expected[, message])", "type": "method", "name": "notEqual", "desc": "

Tests shallow, coercive inequality with the not equal comparison operator\n( != ).\n\n

\n
const assert = require('assert');\n\nassert.notEqual(1, 2);\n  // OK\n\nassert.notEqual(1, 1);\n  // AssertionError: 1 != 1\n\nassert.notEqual(1, '1');\n  // AssertionError: 1 != '1'
\n

If the values are equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notStrictEqual(actual, expected[, message])", "type": "method", "name": "notStrictEqual", "desc": "

Tests strict inequality as determined by the strict not equal operator\n( !== ).\n\n

\n
const assert = require('assert');\n\nassert.notStrictEqual(1, 2);\n  // OK\n\nassert.notStrictEqual(1, 1);\n  // AssertionError: 1 != 1\n\nassert.notStrictEqual(1, '1');\n  // OK
\n

If the values are strictly equal, an AssertionError is thrown with a\nmessage property set equal to the value of the message parameter. If the\nmessage parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.strictEqual(actual, expected[, message])", "type": "method", "name": "strictEqual", "desc": "

Tests strict equality as determined by the strict equality operator ( === ).\n\n

\n
const assert = require('assert');\n\nassert.strictEqual(1, 2);\n  // AssertionError: 1 === 2\n\nassert.strictEqual(1, 1);\n  // OK\n\nassert.strictEqual(1, '1');\n  // AssertionError: 1 === '1'
\n

If the values are not strictly equal, an AssertionError is thrown with a\nmessage property set equal to the value of the message parameter. If the\nmessage parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.throws(block[, error][, message])", "type": "method", "name": "throws", "desc": "

Expects the function block to throw an error. If specified, error can be a\nconstructor, [RegExp][], or validation function.\n\n

\n

Validate instanceof using constructor:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  Error\n);
\n

Validate error message using [RegExp][]:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  /value/\n);
\n

Custom error validation:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  function(err) {\n    if ( (err instanceof Error) && /value/.test(err) ) {\n      return true;\n    }\n  },\n  'unexpected error'\n);
\n", "signatures": [ { "params": [ { "name": "block" }, { "name": "error", "optional": true }, { "name": "message", "optional": true } ] } ] } ], "type": "module", "displayName": "Assert" }, { "textRaw": "Buffer", "name": "buffer", "stability": 2, "stabilityText": "Stable", "desc": "

Pure JavaScript is Unicode-friendly but not nice to binary data. When\ndealing with TCP streams or the file system, it's necessary to handle octet\nstreams. Node.js has several strategies for manipulating, creating, and\nconsuming octet streams.\n\n

\n

Raw data is stored in instances of the Buffer class. A Buffer is similar\nto an array of integers but corresponds to a raw memory allocation outside\nthe V8 heap. A Buffer cannot be resized.\n\n

\n

The Buffer class is a global, making it very rare that one would need\nto ever require('buffer').\n\n

\n

Converting between Buffers and JavaScript string objects requires an explicit\nencoding method. The different string encodings are:\n\n

\n
    \n
  • 'ascii' - for 7-bit ASCII data only. This encoding method is very fast and\nwill strip the high bit if set.

    \n
  • \n
  • 'utf8' - Multibyte encoded Unicode characters. Many web pages and other\ndocument formats use UTF-8.

    \n
  • \n
  • 'utf16le' - 2 or 4 bytes, little-endian encoded Unicode characters.\nSurrogate pairs (U+10000 to U+10FFFF) are supported.

    \n
  • \n
  • 'ucs2' - Alias of 'utf16le'.

    \n
  • \n
  • 'base64' - Base64 string encoding.

    \n
  • \n
  • 'binary' - A way of encoding the buffer into a one-byte (latin-1)\nencoded string. The string 'latin-1' is not supported. Instead, pass\n'binary' to use 'latin-1' encoding.

    \n
  • \n
  • 'hex' - Encode each byte as two hexadecimal characters.

    \n
  • \n
\n

Creating a typed array from a Buffer works with the following caveats:\n\n

\n
    \n
  1. The buffer's memory is copied, not shared.

    \n
  2. \n
  3. The buffer's memory is interpreted as an array, not a byte array. That is,\nnew Uint32Array(new Buffer([1,2,3,4])) creates a 4-element Uint32Array\nwith elements [1,2,3,4], not a Uint32Array with a single element\n[0x1020304] or [0x4030201].

    \n
  4. \n
\n

NOTE: Node.js v0.8 retained a reference to the buffer in array.buffer instead\nof cloning it.\n\n

\n

While more efficient, it introduces subtle incompatibilities with the typed\narrays specification. ArrayBuffer#slice() makes a copy of the slice while\n[Buffer#slice()][] creates a view.\n\n

\n", "classes": [ { "textRaw": "Class: Buffer", "type": "class", "name": "Buffer", "desc": "

The Buffer class is a global type for dealing with binary data directly.\nIt can be constructed in a variety of ways.\n\n

\n", "classMethods": [ { "textRaw": "Class Method: Buffer.byteLength(string[, encoding])", "type": "classMethod", "name": "byteLength", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`string` String ", "name": "string", "desc": "String" }, { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true } ] }, { "params": [ { "name": "string" }, { "name": "encoding", "optional": true } ] } ], "desc": "

Gives the actual byte length of a string. encoding defaults to 'utf8'.\nThis is not the same as [String.prototype.length][] since that returns the\nnumber of characters in a string.\n\n

\n

Example:\n\n

\n
str = '\\u00bd + \\u00bc = \\u00be';\n\nconsole.log(`${str}: ${str.length} characters, ` +\n            `${Buffer.byteLength(str, 'utf8')} bytes`);\n\n// ½ + ¼ = ¾: 9 characters, 12 bytes
\n" }, { "textRaw": "Class Method: Buffer.compare(buf1, buf2)", "type": "classMethod", "name": "compare", "signatures": [ { "params": [ { "textRaw": "`buf1` {Buffer} ", "name": "buf1", "type": "Buffer" }, { "textRaw": "`buf2` {Buffer} ", "name": "buf2", "type": "Buffer" } ] }, { "params": [ { "name": "buf1" }, { "name": "buf2" } ] } ], "desc": "

The same as [buf1.compare(buf2)][]. Useful for sorting an Array of Buffers:\n\n

\n
var arr = [Buffer('1234'), Buffer('0123')];\narr.sort(Buffer.compare);
\n" }, { "textRaw": "Class Method: Buffer.concat(list[, totalLength])", "type": "classMethod", "name": "concat", "signatures": [ { "params": [ { "textRaw": "`list` {Array} List of Buffer objects to concat ", "name": "list", "type": "Array", "desc": "List of Buffer objects to concat" }, { "textRaw": "`totalLength` {Number} Total length of the buffers in the list when concatenated ", "name": "totalLength", "type": "Number", "desc": "Total length of the buffers in the list when concatenated", "optional": true } ] }, { "params": [ { "name": "list" }, { "name": "totalLength", "optional": true } ] } ], "desc": "

Returns a buffer which is the result of concatenating all the buffers in\nthe list together.\n\n

\n

If the list has no items, or if the totalLength is 0, then it returns a\nzero-length buffer.\n\n

\n

If totalLength is not provided, it is read from the buffers in the list.\nHowever, this adds an additional loop to the function, so it is faster\nto provide the length explicitly.\n\n

\n

Example: build a single buffer from a list of three buffers:\n\n

\n
var buf1 = new Buffer(10);\nvar buf2 = new Buffer(14);\nvar buf3 = new Buffer(18);\n\nbuf1.fill(0);\nbuf2.fill(0);\nbuf3.fill(0);\n\nvar buffers = [buf1, buf2, buf3];\n\nvar totalLength = 0;\nfor (var i = 0; i < buffers.length; i++) {\n  totalLength += buffers[i].length;\n}\n\nconsole.log(totalLength);\nvar bufA = Buffer.concat(buffers, totalLength);\nconsole.log(bufA);\nconsole.log(bufA.length);\n\n// 42\n// <Buffer 00 00 00 00 ...>\n// 42
\n" }, { "textRaw": "Class Method: Buffer.isBuffer(obj)", "type": "classMethod", "name": "isBuffer", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`obj` Object ", "name": "obj", "desc": "Object" } ] }, { "params": [ { "name": "obj" } ] } ], "desc": "

Tests if obj is a Buffer.\n\n

\n" }, { "textRaw": "Class Method: Buffer.isEncoding(encoding)", "type": "classMethod", "name": "isEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The encoding string to test ", "name": "encoding", "type": "String", "desc": "The encoding string to test" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Returns true if the encoding is a valid encoding argument, or false\notherwise.\n\n

\n" } ], "methods": [ { "textRaw": "buffer.entries()", "type": "method", "name": "entries", "desc": "

Creates iterator for [index, byte] arrays.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buffer.keys()", "type": "method", "name": "keys", "desc": "

Creates iterator for buffer keys (indices).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buffer.values()", "type": "method", "name": "values", "desc": "

Creates iterator for buffer values (bytes). This function is called automatically\nwhen buffer is used in a for..of statement.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buf.compare(otherBuffer)", "type": "method", "name": "compare", "signatures": [ { "params": [ { "textRaw": "`otherBuffer` {Buffer} ", "name": "otherBuffer", "type": "Buffer" } ] }, { "params": [ { "name": "otherBuffer" } ] } ], "desc": "

Returns a number indicating whether this comes before, after, or is\nthe same as the otherBuffer in sort order.\n\n\n

\n" }, { "textRaw": "buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])", "type": "method", "name": "copy", "signatures": [ { "params": [ { "textRaw": "`targetBuffer` Buffer object - Buffer to copy into ", "name": "targetBuffer", "desc": "Buffer object - Buffer to copy into" }, { "textRaw": "`targetStart` Number, Optional, Default: 0 ", "name": "targetStart", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`sourceStart` Number, Optional, Default: 0 ", "name": "sourceStart", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`sourceEnd` Number, Optional, Default: `buffer.length` ", "name": "sourceEnd", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "targetBuffer" }, { "name": "targetStart", "optional": true }, { "name": "sourceStart", "optional": true }, { "name": "sourceEnd", "optional": true } ] } ], "desc": "

Copies data from a region of this buffer to a region in the target buffer even\nif the target memory region overlaps with the source. If undefined, the\ntargetStart and sourceStart parameters default to 0 while sourceEnd\ndefaults to buffer.length.\n\n

\n

Returns the number of bytes copied.\n\n

\n

Example: build two Buffers, then copy buf1 from byte 16 through byte 19\ninto buf2, starting at the 8th byte in buf2.\n\n

\n
buf1 = new Buffer(26);\nbuf2 = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf1[i] = i + 97; // 97 is ASCII a\n  buf2[i] = 33; // ASCII !\n}\n\nbuf1.copy(buf2, 8, 16, 20);\nconsole.log(buf2.toString('ascii', 0, 25));\n\n// !!!!!!!!qrst!!!!!!!!!!!!!
\n

Example: Build a single buffer, then copy data from one region to an overlapping\nregion in the same buffer\n\n

\n
buf = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf[i] = i + 97; // 97 is ASCII a\n}\n\nbuf.copy(buf, 0, 4, 10);\nconsole.log(buf.toString());\n\n// efghijghijklmnopqrstuvwxyz
\n" }, { "textRaw": "buf.equals(otherBuffer)", "type": "method", "name": "equals", "signatures": [ { "params": [ { "textRaw": "`otherBuffer` {Buffer} ", "name": "otherBuffer", "type": "Buffer" } ] }, { "params": [ { "name": "otherBuffer" } ] } ], "desc": "

Returns a boolean indicating whether this and otherBuffer have the same bytes.\n\n

\n" }, { "textRaw": "buf.fill(value[, offset][, end])", "type": "method", "name": "fill", "signatures": [ { "params": [ { "textRaw": "`value` ", "name": "value" }, { "textRaw": "`offset` Number, Optional ", "name": "offset", "optional": true, "desc": "Number" }, { "textRaw": "`end` Number, Optional ", "name": "end", "optional": true, "desc": "Number" } ] }, { "params": [ { "name": "value" }, { "name": "offset", "optional": true }, { "name": "end", "optional": true } ] } ], "desc": "

Fills the buffer with the specified value. If the offset (defaults to 0)\nand end (defaults to buffer.length) are not given it will fill the entire\nbuffer.\n\n

\n
var b = new Buffer(50);\nb.fill('h');
\n" }, { "textRaw": "buf.indexOf(value[, byteOffset])", "type": "method", "name": "indexOf", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`value` String, Buffer or Number ", "name": "value", "desc": "String, Buffer or Number" }, { "textRaw": "`byteOffset` Number, Optional, Default: 0 ", "name": "byteOffset", "desc": "Number, Optional, Default: 0", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "byteOffset", "optional": true } ] } ], "desc": "

Operates similar to [Array#indexOf()][]. Accepts a String, Buffer or Number.\nStrings are interpreted as UTF8. Buffers will use the entire buffer. So in order\nto compare a partial Buffer use [Buffer#slice()][]. Numbers can range from 0 to\n255.\n\n

\n" }, { "textRaw": "buf.readDoubleBE(offset[, noAssert])", "type": "method", "name": "readDoubleBE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 64-bit double from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\n\nbuf[0] = 0x55;\nbuf[1] = 0x55;\nbuf[2] = 0x55;\nbuf[3] = 0x55;\nbuf[4] = 0x55;\nbuf[5] = 0x55;\nbuf[6] = 0xd5;\nbuf[7] = 0x3f;\n\nconsole.log(buf.readDoubleLE(0));\n\n// 0.3333333333333333
\n" }, { "textRaw": "buf.readDoubleLE(offset[, noAssert])", "type": "method", "name": "readDoubleLE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 64-bit double from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\n\nbuf[0] = 0x55;\nbuf[1] = 0x55;\nbuf[2] = 0x55;\nbuf[3] = 0x55;\nbuf[4] = 0x55;\nbuf[5] = 0x55;\nbuf[6] = 0xd5;\nbuf[7] = 0x3f;\n\nconsole.log(buf.readDoubleLE(0));\n\n// 0.3333333333333333
\n" }, { "textRaw": "buf.readFloatBE(offset[, noAssert])", "type": "method", "name": "readFloatBE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 32-bit float from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x00;\nbuf[1] = 0x00;\nbuf[2] = 0x80;\nbuf[3] = 0x3f;\n\nconsole.log(buf.readFloatLE(0));\n\n// 0x01
\n" }, { "textRaw": "buf.readFloatLE(offset[, noAssert])", "type": "method", "name": "readFloatLE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 32-bit float from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x00;\nbuf[1] = 0x00;\nbuf[2] = 0x80;\nbuf[3] = 0x3f;\n\nconsole.log(buf.readFloatLE(0));\n\n// 0x01
\n" }, { "textRaw": "buf.readInt8(offset[, noAssert])", "type": "method", "name": "readInt8", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 8-bit integer from the buffer at the specified offset.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt8, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt16BE(offset[, noAssert])", "type": "method", "name": "readInt16BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt16*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt16LE(offset[, noAssert])", "type": "method", "name": "readInt16LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt16*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt32BE(offset[, noAssert])", "type": "method", "name": "readInt32BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt32*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt32LE(offset[, noAssert])", "type": "method", "name": "readInt32LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt32*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readIntBE(offset, byteLength[, noAssert])", "type": "method", "name": "readIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n" }, { "textRaw": "buf.readIntLE(offset, byteLength[, noAssert])", "type": "method", "name": "readIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n" }, { "textRaw": "buf.readUInt8(offset[, noAssert])", "type": "method", "name": "readUInt8", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 8-bit integer from the buffer at the specified offset.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nfor (ii = 0; ii < buf.length; ii++) {\n  console.log(buf.readUInt8(ii));\n}\n\n// 0x3\n// 0x4\n// 0x23\n// 0x42
\n" }, { "textRaw": "buf.readUInt16BE(offset[, noAssert])", "type": "method", "name": "readUInt16BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt16BE(0));\nconsole.log(buf.readUInt16LE(0));\nconsole.log(buf.readUInt16BE(1));\nconsole.log(buf.readUInt16LE(1));\nconsole.log(buf.readUInt16BE(2));\nconsole.log(buf.readUInt16LE(2));\n\n// 0x0304\n// 0x0403\n// 0x0423\n// 0x2304\n// 0x2342\n// 0x4223
\n" }, { "textRaw": "buf.readUInt16LE(offset[, noAssert])", "type": "method", "name": "readUInt16LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt16BE(0));\nconsole.log(buf.readUInt16LE(0));\nconsole.log(buf.readUInt16BE(1));\nconsole.log(buf.readUInt16LE(1));\nconsole.log(buf.readUInt16BE(2));\nconsole.log(buf.readUInt16LE(2));\n\n// 0x0304\n// 0x0403\n// 0x0423\n// 0x2304\n// 0x2342\n// 0x4223
\n" }, { "textRaw": "buf.readUInt32BE(offset[, noAssert])", "type": "method", "name": "readUInt32BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt32BE(0));\nconsole.log(buf.readUInt32LE(0));\n\n// 0x03042342\n// 0x42230403
\n" }, { "textRaw": "buf.readUInt32LE(offset[, noAssert])", "type": "method", "name": "readUInt32LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt32BE(0));\nconsole.log(buf.readUInt32LE(0));\n\n// 0x03042342\n// 0x42230403
\n" }, { "textRaw": "buf.readUIntBE(offset, byteLength[, noAssert])", "type": "method", "name": "readUIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n" }, { "textRaw": "buf.readUIntLE(offset, byteLength[, noAssert])", "type": "method", "name": "readUIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n" }, { "textRaw": "buf.slice([start[, end]])", "type": "method", "name": "slice", "signatures": [ { "params": [ { "textRaw": "`start` Number, Optional, Default: 0 ", "name": "start", "desc": "Number, Optional, Default: 0" }, { "textRaw": "`end` Number, Optional, Default: `buffer.length` ", "name": "end", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "start" }, { "name": "end]", "optional": true } ] } ], "desc": "

Returns a new buffer which references the same memory as the old, but offset\nand cropped by the start (defaults to 0) and end (defaults to\nbuffer.length) indexes. Negative indexes start from the end of the buffer.\n\n

\n

Modifying the new buffer slice will modify memory in the original buffer!\n\n

\n

Example: build a Buffer with the ASCII alphabet, take a slice, then modify one\nbyte from the original Buffer.\n\n

\n
var buf1 = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf1[i] = i + 97; // 97 is ASCII a\n}\n\nvar buf2 = buf1.slice(0, 3);\nconsole.log(buf2.toString('ascii', 0, buf2.length));\nbuf1[0] = 33;\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n\n// abc\n// !bc
\n" }, { "textRaw": "buf.toString([encoding][, start][, end])", "type": "method", "name": "toString", "signatures": [ { "params": [ { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true }, { "textRaw": "`start` Number, Optional, Default: 0 ", "name": "start", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`end` Number, Optional, Default: `buffer.length` ", "name": "end", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "encoding", "optional": true }, { "name": "start", "optional": true }, { "name": "end", "optional": true } ] } ], "desc": "

Decodes and returns a string from buffer data encoded using the specified\ncharacter set encoding. If encoding is undefined or null, then encoding\ndefaults to 'utf8'. The start and end parameters default to 0 and\nbuffer.length when undefined.\n\n

\n
buf = new Buffer(26);\nfor (var i = 0 ; i < 26 ; i++) {\n  buf[i] = i + 97; // 97 is ASCII a\n}\nbuf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz\nbuf.toString('ascii',0,5); // outputs: abcde\nbuf.toString('utf8',0,5); // outputs: abcde\nbuf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde
\n

See buf.write() example, below.\n\n\n

\n" }, { "textRaw": "buf.toJSON()", "type": "method", "name": "toJSON", "desc": "

Returns a JSON representation of the Buffer instance. JSON.stringify\nimplicitly calls this function when stringifying a Buffer instance.\n\n

\n

Example:\n\n

\n
var buf = new Buffer('test');\nvar json = JSON.stringify(buf);\n\nconsole.log(json);\n// '{"type":"Buffer","data":[116,101,115,116]}'\n\nvar copy = JSON.parse(json, function(key, value) {\n    return value && value.type === 'Buffer'\n      ? new Buffer(value.data)\n      : value;\n  });\n\nconsole.log(copy);\n// <Buffer 74 65 73 74>
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buf.write(string[, offset][, length][, encoding])", "type": "method", "name": "write", "signatures": [ { "params": [ { "textRaw": "`string` String - data to be written to buffer ", "name": "string", "desc": "String - data to be written to buffer" }, { "textRaw": "`offset` Number, Optional, Default: 0 ", "name": "offset", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`length` Number, Optional, Default: `buffer.length - offset` ", "name": "length", "desc": "Number, Optional, Default: `buffer.length - offset`", "optional": true }, { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true } ] }, { "params": [ { "name": "string" }, { "name": "offset", "optional": true }, { "name": "length", "optional": true }, { "name": "encoding", "optional": true } ] } ], "desc": "

Writes string to the buffer at offset using the given encoding.\noffset defaults to 0, encoding defaults to 'utf8'. length is\nthe number of bytes to write. Returns number of octets written. If buffer did\nnot contain enough space to fit the entire string, it will write a partial\namount of the string. length defaults to buffer.length - offset.\nThe method will not write partial characters.\n\n

\n
buf = new Buffer(256);\nlen = buf.write('\\u00bd + \\u00bc = \\u00be', 0);\nconsole.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
\n" }, { "textRaw": "buf.writeDoubleBE(value, offset[, noAssert])", "type": "method", "name": "writeDoubleBE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid 64-bit double.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\nbuf.writeDoubleBE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeDoubleLE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 43 eb d5 b7 dd f9 5f d7>\n// <Buffer d7 5f f9 dd b7 d5 eb 43>
\n" }, { "textRaw": "buf.writeDoubleLE(value, offset[, noAssert])", "type": "method", "name": "writeDoubleLE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid 64-bit double.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\nbuf.writeDoubleBE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeDoubleLE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 43 eb d5 b7 dd f9 5f d7>\n// <Buffer d7 5f f9 dd b7 d5 eb 43>
\n" }, { "textRaw": "buf.writeFloatBE(value, offset[, noAssert])", "type": "method", "name": "writeFloatBE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. Behavior is unspecified if value is not a 32-bit float.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeFloatLE(0xcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 4f 4a fe bb>\n// <Buffer bb fe 4a 4f>
\n" }, { "textRaw": "buf.writeFloatLE(value, offset[, noAssert])", "type": "method", "name": "writeFloatLE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. Behavior is unspecified if value is not a 32-bit float.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeFloatLE(0xcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 4f 4a fe bb>\n// <Buffer bb fe 4a 4f>
\n" }, { "textRaw": "buf.writeInt8(value, offset[, noAssert])", "type": "method", "name": "writeInt8", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset. value must be a\nvalid signed 8-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt8, except value is written out as a two's complement\nsigned integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt16BE(value, offset[, noAssert])", "type": "method", "name": "writeInt16BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt16*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt16LE(value, offset[, noAssert])", "type": "method", "name": "writeInt16LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt16*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt32BE(value, offset[, noAssert])", "type": "method", "name": "writeInt32BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt32*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt32LE(value, offset[, noAssert])", "type": "method", "name": "writeInt32LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt32*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeIntBE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeIntLE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeUInt8(value, offset[, noAssert])", "type": "method", "name": "writeUInt8", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset. value must be a\nvalid unsigned 8-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt8(0x3, 0);\nbuf.writeUInt8(0x4, 1);\nbuf.writeUInt8(0x23, 2);\nbuf.writeUInt8(0x42, 3);\n\nconsole.log(buf);\n\n// <Buffer 03 04 23 42>
\n" }, { "textRaw": "buf.writeUInt16BE(value, offset[, noAssert])", "type": "method", "name": "writeUInt16BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n\n// <Buffer de ad be ef>\n// <Buffer ad de ef be>
\n" }, { "textRaw": "buf.writeUInt16LE(value, offset[, noAssert])", "type": "method", "name": "writeUInt16LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n\n// <Buffer de ad be ef>\n// <Buffer ad de ef be>
\n" }, { "textRaw": "buf.writeUInt32BE(value, offset[, noAssert])", "type": "method", "name": "writeUInt32BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n\n// <Buffer fe ed fa ce>\n// <Buffer ce fa ed fe>
\n" }, { "textRaw": "buf.writeUInt32LE(value, offset[, noAssert])", "type": "method", "name": "writeUInt32LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n\n// <Buffer fe ed fa ce>\n// <Buffer ce fa ed fe>
\n" }, { "textRaw": "buf.writeUIntBE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeUIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeUIntLE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeUIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" } ], "properties": [ { "textRaw": "buf[index]", "name": "[index]", "desc": "

Get and set the octet at index. The values refer to individual bytes,\nso the legal range is between 0x00 and 0xFF hex or 0 and 255.\n\n

\n

Example: copy an ASCII string into a buffer, one byte at a time:\n\n

\n
str = "Node.js";\nbuf = new Buffer(str.length);\n\nfor (var i = 0; i < str.length ; i++) {\n  buf[i] = str.charCodeAt(i);\n}\n\nconsole.log(buf);\n\n// Node.js
\n" }, { "textRaw": "`length` Number ", "name": "length", "desc": "

The size of the buffer in bytes. Note that this is not necessarily the size\nof the contents. length refers to the amount of memory allocated for the\nbuffer object. It does not change when the contents of the buffer are changed.\n\n

\n
buf = new Buffer(1234);\n\nconsole.log(buf.length);\nbuf.write('some string', 0, 'ascii');\nconsole.log(buf.length);\n\n// 1234\n// 1234
\n

While the length property is not immutable, changing the value of length\ncan result in undefined and inconsistent behavior. Applications that wish to\nmodify the length of a buffer should therefore treat length as read-only and\nuse [buf.slice][] to create a new buffer.\n\n

\n
buf = new Buffer(10);\nbuf.write('abcdefghj', 0, 'ascii');\nconsole.log(buf.length); // 10\nbuf = buf.slice(0,5);\nconsole.log(buf.length); // 5
\n", "shortDesc": "Number" } ], "signatures": [ { "params": [ { "textRaw": "`array` Array ", "name": "array", "desc": "Array" } ], "desc": "

Allocates a new buffer using an array of octets.\n\n

\n" }, { "params": [ { "name": "array" } ], "desc": "

Allocates a new buffer using an array of octets.\n\n

\n" }, { "params": [ { "textRaw": "`buffer` {Buffer} ", "name": "buffer", "type": "Buffer" } ], "desc": "

Copies the passed buffer data onto a new Buffer instance.\n\n

\n" }, { "params": [ { "name": "buffer" } ], "desc": "

Copies the passed buffer data onto a new Buffer instance.\n\n

\n" }, { "params": [ { "textRaw": "`size` Number ", "name": "size", "desc": "Number" } ], "desc": "

Allocates a new buffer of size bytes. size must be less than\n1,073,741,824 bytes (1 GB) on 32-bit architectures or\n2,147,483,648 bytes (2 GB) on 64-bit architectures.\nOtherwise, a [RangeError][] is thrown.\n\n

\n

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So\nthe contents of a newly created Buffer are unknown and could contain\nsensitive data. Use [buf.fill(0)][] to initialize a buffer to zeroes.\n\n

\n" }, { "params": [ { "name": "size" } ], "desc": "

Allocates a new buffer of size bytes. size must be less than\n1,073,741,824 bytes (1 GB) on 32-bit architectures or\n2,147,483,648 bytes (2 GB) on 64-bit architectures.\nOtherwise, a [RangeError][] is thrown.\n\n

\n

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So\nthe contents of a newly created Buffer are unknown and could contain\nsensitive data. Use [buf.fill(0)][] to initialize a buffer to zeroes.\n\n

\n" }, { "params": [ { "textRaw": "`str` String - string to encode. ", "name": "str", "desc": "String - string to encode." }, { "textRaw": "`encoding` String - encoding to use, Optional. ", "name": "encoding", "desc": "String - encoding to use, Optional.", "optional": true } ], "desc": "

Allocates a new buffer containing the given str.\nencoding defaults to 'utf8'.\n\n

\n" }, { "params": [ { "name": "str" }, { "name": "encoding", "optional": true } ], "desc": "

Allocates a new buffer containing the given str.\nencoding defaults to 'utf8'.\n\n

\n" } ] }, { "textRaw": "Class: SlowBuffer", "type": "class", "name": "SlowBuffer", "desc": "

Returns an un-pooled Buffer.\n\n

\n

In order to avoid the garbage collection overhead of creating many individually\nallocated Buffers, by default allocations under 4KB are sliced from a single\nlarger allocated object. This approach improves both performance and memory\nusage since v8 does not need to track and cleanup as many Persistent objects.\n\n

\n

In the case where a developer may need to retain a small chunk of memory from a\npool for an indeterminate amount of time, it may be appropriate to create an\nun-pooled Buffer instance using SlowBuffer and copy out the relevant bits.\n\n

\n
// need to keep around a few small chunks of memory\nvar store = [];\n\nsocket.on('readable', function() {\n  var data = socket.read();\n  // allocate for retained data\n  var sb = new SlowBuffer(10);\n  // copy the data into the new allocation\n  data.copy(sb, 0, 0, 10);\n  store.push(sb);\n});
\n

This should be used only as a last resort after a developer has observed\nundue memory retention in their applications.\n\n

\n" } ], "properties": [ { "textRaw": "`INSPECT_MAX_BYTES` Number, Default: 50 ", "name": "INSPECT_MAX_BYTES", "desc": "

How many bytes will be returned when buffer.inspect() is called. This can\nbe overridden by user modules. See [util.inspect()][] for more details on\nbuffer.inspect() behavior.\n\n

\n

Note that this is a property on the buffer module returned by\nrequire('buffer'), not on the Buffer global or a buffer instance.\n\n

\n", "shortDesc": "Number, Default: 50" } ], "modules": [ { "textRaw": "ES6 iteration", "name": "es6_iteration", "desc": "

Buffers can be iterated over using for..of syntax:\n\n

\n
var buf = new Buffer([1, 2, 3]);\n\nfor (var b of buf)\n  console.log(b)\n\n// 1\n// 2\n// 3
\n

Additionally, the buffer.values(), buffer.keys(), and buffer.entries()\nmethods can be used to create iterators.\n\n

\n", "type": "module", "displayName": "ES6 iteration" } ], "type": "module", "displayName": "Buffer" }, { "textRaw": "Child Process", "name": "child_process", "stability": 2, "stabilityText": "Stable", "desc": "

Node.js provides a tri-directional popen(3) facility through the\nchild_process module.\n\n

\n

It is possible to stream data through a child's stdin, stdout, and\nstderr in a fully non-blocking way. (Note that some programs use\nline-buffered I/O internally. That doesn't affect Node.js but it means\ndata you send to the child process may not be immediately consumed.)\n\n

\n

To create a child process, use require('child_process').spawn() or\nrequire('child_process').fork(). The semantics of each are slightly\ndifferent as explained [below][].\n\n

\n

For scripting purposes you may find the [synchronous counterparts][] more\nconvenient.\n\n

\n", "classes": [ { "textRaw": "Class: ChildProcess", "type": "class", "name": "ChildProcess", "desc": "

ChildProcess is an [EventEmitter][].\n\n

\n

Child processes always have three streams associated with them. child.stdin,\nchild.stdout, and child.stderr. These may be shared with the stdio\nstreams of the parent process, or they may be separate stream objects\nwhich can be piped to and from.\n\n

\n

The ChildProcess class is not intended to be used directly. Use the\n[spawn()][], [exec()][], [execFile()][], or [fork()][] methods to create\nan instance of ChildProcess.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "params": [], "desc": "

This event is emitted when the stdio streams of a child process have all\nterminated. This is distinct from 'exit', since multiple processes\nmight share the same stdio streams.\n\n

\n" }, { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "desc": "

This event is emitted after calling the .disconnect() method in the parent\nor in the child. After disconnecting it is no longer possible to send messages,\nand the .connected property is false.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when:\n\n

\n
    \n
  1. The process could not be spawned, or
  2. \n
  3. The process could not be killed, or
  4. \n
  5. Sending a message to the child process failed.
  6. \n
\n

Note that the 'exit' event may or may not fire after an error has occurred.\nIf you are listening on both events to fire a function, remember to guard\nagainst calling your function twice.\n\n

\n

See also [ChildProcess#kill()][] and [ChildProcess#send()][].\n\n

\n" }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

This event is emitted after the child process ends. If the process terminated\nnormally, code is the final exit code of the process, otherwise null. If\nthe process terminated due to receipt of a signal, signal is the string name\nof the signal, otherwise null.\n\n

\n

Note that the child process stdio streams might still be open.\n\n

\n

Also, note that Node.js establishes signal handlers for SIGINT and\nSIGTERM. It will not terminate due to receipt of those signals. It will exit.\n\n

\n

See waitpid(2).\n\n

\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Messages sent by .send(message, [sendHandle]) are obtained using the\n'message' event.\n\n

\n" } ], "properties": [ { "textRaw": "`connected` {Boolean} Set to false after `.disconnect` is called ", "name": "connected", "desc": "

If .connected is false, it is no longer possible to send messages.\n\n

\n", "shortDesc": "Set to false after `.disconnect` is called" }, { "textRaw": "`pid` {Integer} ", "name": "pid", "desc": "

The process identifier (PID) of the child process.\n\n

\n

Example:\n\n

\n
const spawn = require('child_process').spawn;\nconst grep = spawn('grep', ['ssh']);\n\nconsole.log(`Spawned child pid: ${grep.pid}`);\ngrep.stdin.end();
\n" }, { "textRaw": "`stderr` {Stream object} ", "name": "stderr", "desc": "

A Readable Stream that represents the child process's stderr.\n\n

\n

If the child was not spawned with stdio[2] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stderr is shorthand for child.stdio[2]. Both properties will refer\nto the same object, or null.\n\n

\n" }, { "textRaw": "`stdin` {Stream object} ", "name": "stdin", "desc": "

A Writable Stream that represents the child process's stdin.\nIf the child is waiting to read all its input, it will not continue until this\nstream has been closed via end().\n\n

\n

If the child was not spawned with stdio[0] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stdin is shorthand for child.stdio[0]. Both properties will refer\nto the same object, or null.\n\n

\n" }, { "textRaw": "`stdio` {Array} ", "name": "stdio", "desc": "

A sparse array of pipes to the child process, corresponding with positions in\nthe [stdio][] option to [spawn()][] that have been set to 'pipe'.\nNote that streams 0-2 are also available as ChildProcess.stdin,\nChildProcess.stdout, and ChildProcess.stderr, respectively.\n\n

\n

In the following example, only the child's fd 1 is setup as a pipe, so only\nthe parent's child.stdio[1] is a stream, all other values in the array are\nnull.\n\n

\n
const assert = require('assert');\nconst fs = require('fs');\nconst child_process = require('child_process');\n\nconst child = child_process.spawn('ls', {\n    stdio: [\n      0, // use parents stdin for child\n      'pipe', // pipe child's stdout to parent\n      fs.openSync('err.out', 'w') // direct child's stderr to a file\n    ]\n});\n\nassert.equal(child.stdio[0], null);\nassert.equal(child.stdio[0], child.stdin);\n\nassert(child.stdout);\nassert.equal(child.stdio[1], child.stdout);\n\nassert.equal(child.stdio[2], null);\nassert.equal(child.stdio[2], child.stderr);
\n" }, { "textRaw": "`stdout` {Stream object} ", "name": "stdout", "desc": "

A Readable Stream that represents the child process's stdout.\n\n

\n

If the child was not spawned with stdio[1] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stdout is shorthand for child.stdio[1]. Both properties will refer\nto the same object, or null.\n\n

\n" } ], "methods": [ { "textRaw": "child.disconnect()", "type": "method", "name": "disconnect", "desc": "

Close the IPC channel between parent and child, allowing the child to exit\ngracefully once there are no other connections keeping it alive. After calling\nthis method the .connected flag will be set to false in both the parent and\nchild, and it is no longer possible to send messages.\n\n

\n

The 'disconnect' event will be emitted when there are no messages in the\nprocess of being received, most likely immediately.\n\n

\n

Note that you can also call process.disconnect() in the child process when the\nchild process has any open IPC channels with the parent (i.e [fork()][]).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "child.kill([signal])", "type": "method", "name": "kill", "signatures": [ { "params": [ { "textRaw": "`signal` {String} ", "name": "signal", "type": "String", "optional": true } ] }, { "params": [ { "name": "signal", "optional": true } ] } ], "desc": "

Send a signal to the child process. If no argument is given, the process will\nbe sent 'SIGTERM'. See signal(7) for a list of available signals.\n\n

\n
const spawn = require('child_process').spawn;\nconst grep = spawn('grep', ['ssh']);\n\ngrep.on('close', (code, signal) => {\n  console.log(\n    `child process terminated due to receipt of signal ${signal}`);\n});\n\n// send SIGHUP to process\ngrep.kill('SIGHUP');
\n

May emit an 'error' event when the signal cannot be delivered. Sending a\nsignal to a child process that has already exited is not an error but may\nhave unforeseen consequences. Specifically, if the process identifier (PID) has\nbeen reassigned to another process, the signal will be delivered to that\nprocess instead. What happens next is anyone's guess.\n\n

\n

Note that while the function is called kill, the signal delivered to the\nchild process may not actually kill it. kill really just sends a signal\nto a process.\n\n

\n

See kill(2)\n\n

\n" }, { "textRaw": "child.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

When using [child_process.fork()][] you can write to the child using\nchild.send(message[, sendHandle][, callback]) and messages are received by\na 'message' event on the child.\n\n

\n

For example:\n\n

\n
const cp = require('child_process');\nconst n = cp.fork(`${__dirname}/sub.js`);\n\nn.on('message', (m) => {\n  console.log('PARENT got message:', m);\n});\n\nn.send({ hello: 'world' });
\n

And then the child script, 'sub.js' might look like this:\n\n

\n
process.on('message', (m) => {\n  console.log('CHILD got message:', m);\n});\n\nprocess.send({ foo: 'bar' });
\n

In the child, the process object will have a send() method, and process\nwill emit objects each time it receives a message on its channel.\n\n

\n

There is a special case when sending a {cmd: 'NODE_foo'} message. All messages\ncontaining a NODE_ prefix in its cmd property will not be emitted in\nthe 'message' event, since they are internal messages used by Node.js core.\nMessages containing the prefix are emitted in the 'internalMessage' event.\nAvoid using this feature; it is subject to change without notice.\n\n

\n

The sendHandle option to child.send() is for sending a TCP server or\nsocket object to another process. The child will receive the object as its\nsecond argument to the 'message' event.\n\n

\n

The callback option is a function that is invoked after the message is\nsent but before the target may have received it. It is called with a single\nargument: null on success, or an [Error][] object on failure.\n\n

\n

child.send() emits an 'error' event if no callback was given and the message\ncannot be sent, for example because the child process has already exited.\n\n

\n

Returns true under normal circumstances or false when the backlog of\nunsent messages exceeds a threshold that makes it unwise to send more.\nUse the callback mechanism to implement flow control.\n\n

\n

Example: sending server object

\n

Here is an example of sending a server:\n\n

\n
const child = require('child_process').fork('child.js');\n\n// Open up the server object and send the handle.\nconst server = require('net').createServer();\nserver.on('connection', (socket) => {\n  socket.end('handled by parent');\n});\nserver.listen(1337, () => {\n  child.send('server', server);\n});
\n

And the child would then receive the server object as:\n\n

\n
process.on('message', (m, server) => {\n  if (m === 'server') {\n    server.on('connection', (socket) => {\n      socket.end('handled by child');\n    });\n  }\n});
\n

Note that the server is now shared between the parent and child, this means\nthat some connections will be handled by the parent and some by the child.\n\n

\n

For dgram servers the workflow is exactly the same. Here you listen on\na 'message' event instead of 'connection' and use server.bind instead of\nserver.listen. (Currently only supported on UNIX platforms.)\n\n

\n

Example: sending socket object

\n

Here is an example of sending a socket. It will spawn two children and handle\nconnections with the remote address 74.125.127.100 as VIP by sending the\nsocket to a "special" child process. Other sockets will go to a "normal"\nprocess.\n\n

\n
const normal = require('child_process').fork('child.js', ['normal']);\nconst special = require('child_process').fork('child.js', ['special']);\n\n// Open up the server and send sockets to child\nconst server = require('net').createServer();\nserver.on('connection', (socket) => {\n\n  // if this is a VIP\n  if (socket.remoteAddress === '74.125.127.100') {\n    special.send('socket', socket);\n    return;\n  }\n  // just the usual...\n  normal.send('socket', socket);\n});\nserver.listen(1337);
\n

The child.js could look like this:\n\n

\n
process.on('message', (m, socket) => {\n  if (m === 'socket') {\n    socket.end(`You were handled as a ${process.argv[2]} person`);\n  }\n});
\n

Note that once a single socket has been sent to a child the parent can no\nlonger keep track of when the socket is destroyed. To indicate this condition\nthe .connections property becomes null.\nIt is also recommended not to use .maxConnections in this condition.\n\n

\n" } ] } ], "modules": [ { "textRaw": "Asynchronous Process Creation", "name": "asynchronous_process_creation", "desc": "

These methods follow the common async programming patterns (accepting a\ncallback or returning an EventEmitter).\n\n

\n", "methods": [ { "textRaw": "child_process.exec(command[, options], callback)", "type": "method", "name": "exec", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`command` {String} The command to run, with space-separated arguments ", "name": "command", "type": "String", "desc": "The command to run, with space-separated arguments" }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`encoding` {String} (Default: 'utf8') ", "name": "encoding", "default": "utf8", "type": "String" }, { "textRaw": "`shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) ", "name": "shell", "type": "String", "desc": "Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.)" }, { "textRaw": "`timeout` {Number} (Default: 0) ", "name": "timeout", "default": "0", "type": "Number" }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: `200*1024`) ", "name": "maxBuffer", "default": "200*1024", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`killSignal` {String} (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true }, { "textRaw": "`callback` {Function} called with the output when process terminates ", "options": [ { "textRaw": "`error` {Error} ", "name": "error", "type": "Error" }, { "textRaw": "`stdout` {Buffer} ", "name": "stdout", "type": "Buffer" }, { "textRaw": "`stderr` {Buffer} ", "name": "stderr", "type": "Buffer" } ], "name": "callback", "type": "Function", "desc": "called with the output when process terminates" } ] }, { "params": [ { "name": "command" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Runs a command in a shell and buffers the output.\n\n

\n
const exec = require('child_process').exec;\nconst child = exec('cat *.js bad_file | wc -l',\n  (error, stdout, stderr) => {\n    console.log(`stdout: ${stdout}`);\n    console.log(`stderr: ${stderr}`);\n    if (error !== null) {\n      console.log(`exec error: ${error}`);\n    }\n});
\n

The callback gets the arguments (error, stdout, stderr). On success, error\nwill be null. On error, error will be an instance of [Error][] and error.code\nwill be the exit code of the child process, and error.signal will be set to the\nsignal that terminated the process.\n\n

\n

There is a second optional argument to specify several options. The\ndefault options are\n\n

\n
{ encoding: 'utf8',\n  timeout: 0,\n  maxBuffer: 200*1024,\n  killSignal: 'SIGTERM',\n  cwd: null,\n  env: null }
\n

If timeout is greater than 0, then it will kill the child process\nif it runs longer than timeout milliseconds. The child process is killed with\nkillSignal (default: 'SIGTERM'). maxBuffer specifies the largest\namount of data (in bytes) allowed on stdout or stderr - if this value is\nexceeded then the child process is killed.\n\n

\n

Note: Unlike the exec() POSIX system call, child_process.exec() does not replace\nthe existing process and uses a shell to execute the command.\n\n

\n" }, { "textRaw": "child_process.execFile(file[, args][, options][, callback])", "type": "method", "name": "execFile", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`file` {String} The filename of the program to run ", "name": "file", "type": "String", "desc": "The filename of the program to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`encoding` {String} (Default: 'utf8') ", "name": "encoding", "default": "utf8", "type": "String" }, { "textRaw": "`timeout` {Number} (Default: 0) ", "name": "timeout", "default": "0", "type": "Number" }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200\\*1024) ", "name": "maxBuffer", "default": "200\\*1024", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`killSignal` {String} (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true }, { "textRaw": "`callback` {Function} called with the output when process terminates ", "options": [ { "textRaw": "`error` {Error} ", "name": "error", "type": "Error" }, { "textRaw": "`stdout` {Buffer} ", "name": "stdout", "type": "Buffer" }, { "textRaw": "`stderr` {Buffer} ", "name": "stderr", "type": "Buffer" } ], "name": "callback", "type": "Function", "desc": "called with the output when process terminates", "optional": true } ] }, { "params": [ { "name": "file" }, { "name": "args", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This is similar to [child_process.exec()][] except it does not execute a\nsubshell but rather the specified file directly. This makes it slightly\nleaner than [child_process.exec()][]. It has the same options.\n\n\n

\n" }, { "textRaw": "child_process.fork(modulePath[, args][, options])", "type": "method", "name": "fork", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`modulePath` {String} The module to run in the child ", "name": "modulePath", "type": "String", "desc": "The module to run in the child" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`execPath` {String} Executable used to create the child process ", "name": "execPath", "type": "String", "desc": "Executable used to create the child process" }, { "textRaw": "`execArgv` {Array} List of string arguments passed to the executable (Default: `process.execArgv`) ", "name": "execArgv", "default": "process.execArgv", "type": "Array", "desc": "List of string arguments passed to the executable" }, { "textRaw": "`silent` {Boolean} If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`spawn()`][]'s [`stdio`][] for more details (default is false) ", "name": "silent", "type": "Boolean", "desc": "If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`spawn()`][]'s [`stdio`][] for more details (default is false)" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "modulePath" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

This is a special case of the [child_process.spawn()][] functionality for\nspawning Node.js processes. In addition to having all the methods in a normal\nChildProcess instance, the returned object has a communication channel built-in.\nSee [ChildProcess#send()][] for details.\n\n

\n

These child Node.js processes are still whole new instances of V8. Assume at\nleast 30ms startup and 10mb memory for each new Node.js. That is, you cannot\ncreate many thousands of them.\n\n

\n

The execPath property in the options object allows for a process to be\ncreated for the child rather than the current node executable. This should be\ndone with care and by default will talk over the fd represented an\nenvironmental variable NODE_CHANNEL_FD on the child process. The input and\noutput on this fd is expected to be line delimited JSON objects.\n\n

\n

Note: Unlike the fork() POSIX system call, [child_process.fork()][] does not clone the\ncurrent process.\n\n

\n" }, { "textRaw": "child_process.spawn(command[, args][, options])", "type": "method", "name": "spawn", "signatures": [ { "return": { "textRaw": "return: {ChildProcess object} ", "name": "return", "type": "ChildProcess object" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`stdio` {Array|String} Child's stdio configuration. (See [below](#child_process_options_stdio)) ", "name": "stdio", "type": "Array|String", "desc": "Child's stdio configuration. (See [below](#child_process_options_stdio))" }, { "textRaw": "`detached` {Boolean} Prepare child to run independently of its parent process. Specific behavior depends on the platform, see [below](#child_process_options_detached)) ", "name": "detached", "type": "Boolean", "desc": "Prepare child to run independently of its parent process. Specific behavior depends on the platform, see [below](#child_process_options_detached))" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

Launches a new process with the given command, with command line arguments in\nargs. If omitted, args defaults to an empty Array.\n\n

\n

The third argument is used to specify additional options, with these defaults:\n\n

\n
{ cwd: undefined,\n  env: process.env\n}
\n

Use cwd to specify the working directory from which the process is spawned.\nIf not given, the default is to inherit the current working directory.\n\n

\n

Use env to specify environment variables that will be visible to the new\nprocess, the default is process.env.\n\n

\n

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:\n\n

\n
const spawn = require('child_process').spawn;\nconst ls = spawn('ls', ['-lh', '/usr']);\n\nls.stdout.on('data', (data) => {\n  console.log(`stdout: ${data}`);\n});\n\nls.stderr.on('data', (data) => {\n  console.log(`stderr: ${data}`);\n});\n\nls.on('close', (code) => {\n  console.log(`child process exited with code ${code}`);\n});
\n

Example: A very elaborate way to run 'ps ax | grep ssh'\n\n

\n
const spawn = require('child_process').spawn;\nconst ps = spawn('ps', ['ax']);\nconst grep = spawn('grep', ['ssh']);\n\nps.stdout.on('data', (data) => {\n  grep.stdin.write(data);\n});\n\nps.stderr.on('data', (data) => {\n  console.log(`ps stderr: ${data}`);\n});\n\nps.on('close', (code) => {\n  if (code !== 0) {\n    console.log(`ps process exited with code ${code}`);\n  }\n  grep.stdin.end();\n});\n\ngrep.stdout.on('data', (data) => {\n  console.log(`${data}`);\n});\n\ngrep.stderr.on('data', (data) => {\n  console.log(`grep stderr: ${data}`);\n});\n\ngrep.on('close', (code) => {\n  if (code !== 0) {\n    console.log(`grep process exited with code ${code}`);\n  }\n});
\n

Example of checking for failed exec:\n\n

\n
const spawn = require('child_process').spawn;\nconst child = spawn('bad_command');\n\nchild.on('error', (err) => {\n  console.log('Failed to start child process.');\n});
\n", "properties": [ { "textRaw": "options.detached", "name": "detached", "desc": "

On Windows, this makes it possible for the child to continue running after the\nparent exits. The child will have a new console window (this cannot be\ndisabled).\n\n

\n

On non-Windows, if the detached option is set, the child process will be made\nthe leader of a new process group and session. Note that child processes may\ncontinue running after the parent exits whether they are detached or not. See\nsetsid(2) for more information.\n\n

\n

By default, the parent will wait for the detached child to exit. To prevent\nthe parent from waiting for a given child, use the child.unref() method,\nand the parent's event loop will not include the child in its reference count.\n\n

\n

Example of detaching a long-running process and redirecting its output to a\nfile:\n\n

\n
 const fs = require('fs');\n const spawn = require('child_process').spawn;\n const out = fs.openSync('./out.log', 'a');\n const err = fs.openSync('./out.log', 'a');\n\n const child = spawn('prg', [], {\n   detached: true,\n   stdio: [ 'ignore', out, err ]\n });\n\n child.unref();
\n

When using the detached option to start a long-running process, the process\nwill not stay running in the background after the parent exits unless it is\nprovided with a stdio configuration that is not connected to the parent.\nIf the parent's stdio is inherited, the child will remain attached to the\ncontrolling terminal.\n\n

\n" }, { "textRaw": "options.stdio", "name": "stdio", "desc": "

As a shorthand, the stdio argument may be one of the following strings:\n\n

\n
    \n
  • 'pipe' - ['pipe', 'pipe', 'pipe'], this is the default value
  • \n
  • 'ignore' - ['ignore', 'ignore', 'ignore']
  • \n
  • 'inherit' - [process.stdin, process.stdout, process.stderr] or [0,1,2]
  • \n
\n

Otherwise, the 'stdio' option to [child_process.spawn()][] is an array where each\nindex corresponds to a fd in the child. The value is one of the following:\n\n

\n
    \n
  1. 'pipe' - Create a pipe between the child process and the parent process.\nThe parent end of the pipe is exposed to the parent as a property on the\nchild_process object as ChildProcess.stdio[fd]. Pipes created for\nfds 0 - 2 are also available as ChildProcess.stdin, ChildProcess.stdout\nand ChildProcess.stderr, respectively.
  2. \n
  3. 'ipc' - Create an IPC channel for passing messages/file descriptors\nbetween parent and child. A ChildProcess may have at most one IPC stdio\nfile descriptor. Setting this option enables the ChildProcess.send() method.\nIf the child writes JSON messages to this file descriptor, then this will\ntrigger ChildProcess.on('message'). If the child is an Node.js program, then\nthe presence of an IPC channel will enable process.send() and\nprocess.on('message').
  4. \n
  5. 'ignore' - Do not set this file descriptor in the child. Note that Node.js\nwill always open fd 0 - 2 for the processes it spawns. When any of these is\nignored Node.js will open /dev/null and attach it to the child's fd.
  6. \n
  7. Stream object - Share a readable or writable stream that refers to a tty,\nfile, socket, or a pipe with the child process. The stream's underlying\nfile descriptor is duplicated in the child process to the fd that\ncorresponds to the index in the stdio array. Note that the stream must\nhave an underlying descriptor (file streams do not until the 'open'\nevent has occurred).
  8. \n
  9. Positive integer - The integer value is interpreted as a file descriptor\nthat is is currently open in the parent process. It is shared with the child\nprocess, similar to how Stream objects can be shared.
  10. \n
  11. null, undefined - Use default value. For stdio fds 0, 1 and 2 (in other\nwords, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the\ndefault is 'ignore'.
  12. \n
\n

Example:\n\n

\n
const spawn = require('child_process').spawn;\n\n// Child will use parent's stdios\nspawn('prg', [], { stdio: 'inherit' });\n\n// Spawn child sharing only stderr\nspawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });\n\n// Open an extra fd=4, to interact with programs present a\n// startd-style interface.\nspawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
\n

See also: [child_process.exec()][] and [child_process.fork()][]\n\n

\n" } ] } ], "type": "module", "displayName": "Asynchronous Process Creation" }, { "textRaw": "Synchronous Process Creation", "name": "synchronous_process_creation", "desc": "

These methods are synchronous, meaning they WILL block the event loop,\npausing execution of your code until the spawned process exits.\n\n

\n

Blocking calls like these are mostly useful for simplifying general purpose\nscripting tasks and for simplifying the loading/processing of application\nconfiguration at startup.\n\n

\n", "methods": [ { "textRaw": "child_process.execFileSync(file[, args][, options])", "type": "method", "name": "execFileSync", "signatures": [ { "return": { "textRaw": "return: {Buffer|String} The stdout from the command ", "name": "return", "type": "Buffer|String", "desc": "The stdout from the command" }, "params": [ { "textRaw": "`file` {String} The filename of the program to run ", "name": "file", "type": "String", "desc": "The filename of the program to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. (Default: 'pipe') ", "options": [ { "textRaw": "`stderr` by default will be output to the parent process' stderr unless `stdio` is specified ", "name": "stderr", "desc": "by default will be output to the parent process' stderr unless `stdio` is specified" } ], "name": "stdio", "default": "pipe", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "file" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

execFileSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n

If the process times out, or has a non-zero exit code, this method will\nthrow. The [Error][] object will contain the entire result from\n[child_process.spawnSync()][]\n\n

\n" }, { "textRaw": "child_process.execSync(command[, options])", "type": "method", "name": "execSync", "signatures": [ { "return": { "textRaw": "return: {Buffer|String} The stdout from the command ", "name": "return", "type": "Buffer|String", "desc": "The stdout from the command" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. (Default: 'pipe') ", "options": [ { "textRaw": "`stderr` by default will be output to the parent process' stderr unless `stdio` is specified ", "name": "stderr", "desc": "by default will be output to the parent process' stderr unless `stdio` is specified" } ], "name": "stdio", "default": "pipe", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) ", "name": "shell", "type": "String", "desc": "Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.)" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "options", "optional": true } ] } ], "desc": "

execSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n

If the process times out, or has a non-zero exit code, this method will\nthrow. The [Error][] object will contain the entire result from\n[child_process.spawnSync()][]\n\n

\n" }, { "textRaw": "child_process.spawnSync(command[, args][, options])", "type": "method", "name": "spawnSync", "signatures": [ { "return": { "textRaw": "return: {Object} ", "options": [ { "textRaw": "`pid` {Number} Pid of the child process ", "name": "pid", "type": "Number", "desc": "Pid of the child process" }, { "textRaw": "`output` {Array} Array of results from stdio output ", "name": "output", "type": "Array", "desc": "Array of results from stdio output" }, { "textRaw": "`stdout` {Buffer|String} The contents of `output[1]` ", "name": "stdout", "type": "Buffer|String", "desc": "The contents of `output[1]`" }, { "textRaw": "`stderr` {Buffer|String} The contents of `output[2]` ", "name": "stderr", "type": "Buffer|String", "desc": "The contents of `output[2]`" }, { "textRaw": "`status` {Number} The exit code of the child process ", "name": "status", "type": "Number", "desc": "The exit code of the child process" }, { "textRaw": "`signal` {String} The signal used to kill the child process ", "name": "signal", "type": "String", "desc": "The signal used to kill the child process" }, { "textRaw": "`error` {Error} The error object if the child process failed or timed out ", "name": "error", "type": "Error", "desc": "The error object if the child process failed or timed out" } ], "name": "return", "type": "Object" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. ", "name": "stdio", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

spawnSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n" } ], "type": "module", "displayName": "Synchronous Process Creation" } ], "type": "module", "displayName": "Child Process" }, { "textRaw": "Cluster", "name": "cluster", "stability": 2, "stabilityText": "Stable", "desc": "

A single instance of Node.js runs in a single thread. To take advantage of\nmulti-core systems the user will sometimes want to launch a cluster of Node.js\nprocesses to handle the load.\n\n

\n

The cluster module allows you to easily create child processes that\nall share server ports.\n\n

\n
const cluster = require('cluster');\nconst http = require('http');\nconst numCPUs = require('os').cpus().length;\n\nif (cluster.isMaster) {\n  // Fork workers.\n  for (var i = 0; i < numCPUs; i++) {\n    cluster.fork();\n  }\n\n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`worker ${worker.process.pid} died`);\n  });\n} else {\n  // Workers can share any TCP connection\n  // In this case it is an HTTP server\n  http.createServer((req, res) => {\n    res.writeHead(200);\n    res.end('hello world\\n');\n  }).listen(8000);\n}
\n

Running Node.js will now share port 8000 between the workers:\n\n

\n
% NODE_DEBUG=cluster node server.js\n23521,Master Worker 23524 online\n23521,Master Worker 23526 online\n23521,Master Worker 23523 online\n23521,Master Worker 23528 online
\n

Please note that, on Windows, it is not yet possible to set up a named pipe\nserver in a worker.\n\n

\n", "miscs": [ { "textRaw": "How It Works", "name": "How It Works", "type": "misc", "desc": "

The worker processes are spawned using the [child_process.fork][] method,\nso that they can communicate with the parent via IPC and pass server\nhandles back and forth.\n\n

\n

The cluster module supports two methods of distributing incoming\nconnections.\n\n

\n

The first one (and the default one on all platforms except Windows),\nis the round-robin approach, where the master process listens on a\nport, accepts new connections and distributes them across the workers\nin a round-robin fashion, with some built-in smarts to avoid\noverloading a worker process.\n\n

\n

The second approach is where the master process creates the listen\nsocket and sends it to interested workers. The workers then accept\nincoming connections directly.\n\n

\n

The second approach should, in theory, give the best performance.\nIn practice however, distribution tends to be very unbalanced due\nto operating system scheduler vagaries. Loads have been observed\nwhere over 70% of all connections ended up in just two processes,\nout of a total of eight.\n\n

\n

Because server.listen() hands off most of the work to the master\nprocess, there are three cases where the behavior between a normal\nNode.js process and a cluster worker differs:\n\n

\n
    \n
  1. server.listen({fd: 7}) Because the message is passed to the master,\nfile descriptor 7 in the parent will be listened on, and the\nhandle passed to the worker, rather than listening to the worker's\nidea of what the number 7 file descriptor references.
  2. \n
  3. server.listen(handle) Listening on handles explicitly will cause\nthe worker to use the supplied handle, rather than talk to the master\nprocess. If the worker already has the handle, then it's presumed\nthat you know what you are doing.
  4. \n
  5. server.listen(0) Normally, this will cause servers to listen on a\nrandom port. However, in a cluster, each worker will receive the\nsame "random" port each time they do listen(0). In essence, the\nport is random the first time, but predictable thereafter. If you\nwant to listen on a unique port, generate a port number based on the\ncluster worker ID.
  6. \n
\n

There is no routing logic in Node.js, or in your program, and no shared\nstate between the workers. Therefore, it is important to design your\nprogram such that it does not rely too heavily on in-memory data objects\nfor things like sessions and login.\n\n

\n

Because workers are all separate processes, they can be killed or\nre-spawned depending on your program's needs, without affecting other\nworkers. As long as there are some workers still alive, the server will\ncontinue to accept connections. If no workers are alive, existing connections\nwill be dropped and new connections will be refused. Node.js does not\nautomatically manage the number of workers for you, however. It is your\nresponsibility to manage the worker pool for your application's needs.\n\n\n\n

\n" } ], "classes": [ { "textRaw": "Class: Worker", "type": "class", "name": "Worker", "desc": "

A Worker object contains all public information and method about a worker.\nIn the master it can be obtained using cluster.workers. In a worker\nit can be obtained using cluster.worker.\n\n

\n", "events": [ { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "desc": "

Similar to the cluster.on('disconnect') event, but specific to this worker.\n\n

\n
cluster.fork().on('disconnect', () => {\n  // Worker has disconnected\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "desc": "

This event is the same as the one provided by [child_process.fork()][].\n\n

\n

In a worker you can also use process.on('error').\n\n

\n", "params": [] }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

Similar to the cluster.on('exit') event, but specific to this worker.\n\n

\n
const worker = cluster.fork();\nworker.on('exit', (code, signal) => {\n  if( signal ) {\n    console.log(`worker was killed by signal: ${signal}`);\n  } else if( code !== 0 ) {\n    console.log(`worker exited with error code: ${code}`);\n  } else {\n    console.log('worker success!');\n  }\n});
\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "params": [], "desc": "

Similar to the cluster.on('listening') event, but specific to this worker.\n\n

\n
cluster.fork().on('listening', (address) => {\n  // Worker is listening\n});
\n

It is not emitted in the worker.\n\n

\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Similar to the cluster.on('message') event, but specific to this worker.\n\n

\n

This event is the same as the one provided by [child_process.fork()][].\n\n

\n

In a worker you can also use process.on('message').\n\n

\n

As an example, here is a cluster that keeps count of the number of requests\nin the master process using the message system:\n\n

\n
const cluster = require('cluster');\nconst http = require('http');\n\nif (cluster.isMaster) {\n\n  // Keep track of http requests\n  var numReqs = 0;\n  setInterval(() => {\n    console.log('numReqs =', numReqs);\n  }, 1000);\n\n  // Count requests\n  function messageHandler(msg) {\n    if (msg.cmd && msg.cmd == 'notifyRequest') {\n      numReqs += 1;\n    }\n  }\n\n  // Start workers and listen for messages containing notifyRequest\n  const numCPUs = require('os').cpus().length;\n  for (var i = 0; i < numCPUs; i++) {\n    cluster.fork();\n  }\n\n  Object.keys(cluster.workers).forEach((id) => {\n    cluster.workers[id].on('message', messageHandler);\n  });\n\n} else {\n\n  // Worker processes have a http server.\n  http.Server((req, res) => {\n    res.writeHead(200);\n    res.end('hello world\\n');\n\n    // notify master about the request\n    process.send({ cmd: 'notifyRequest' });\n  }).listen(8000);\n}
\n" }, { "textRaw": "Event: 'online'", "type": "event", "name": "online", "desc": "

Similar to the cluster.on('online') event, but specific to this worker.\n\n

\n
cluster.fork().on('online', () => {\n  // Worker is online\n});
\n

It is not emitted in the worker.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "worker.disconnect()", "type": "method", "name": "disconnect", "desc": "

In a worker, this function will close all servers, wait for the 'close' event on\nthose servers, and then disconnect the IPC channel.\n\n

\n

In the master, an internal message is sent to the worker causing it to call\n.disconnect() on itself.\n\n

\n

Causes .suicide to be set.\n\n

\n

Note that after a server is closed, it will no longer accept new connections,\nbut connections may be accepted by any other listening worker. Existing\nconnections will be allowed to close as usual. When no more connections exist,\nsee [server.close()][], the IPC channel to the worker will close allowing it to\ndie gracefully.\n\n

\n

The above applies only to server connections, client connections are not\nautomatically closed by workers, and disconnect does not wait for them to close\nbefore exiting.\n\n

\n

Note that in a worker, process.disconnect exists, but it is not this function,\nit is [disconnect][].\n\n

\n

Because long living server connections may block workers from disconnecting, it\nmay be useful to send a message, so application specific actions may be taken to\nclose them. It also may be useful to implement a timeout, killing a worker if\nthe 'disconnect' event has not been emitted after some time.\n\n

\n
if (cluster.isMaster) {\n  var worker = cluster.fork();\n  var timeout;\n\n  worker.on('listening', (address) => {\n    worker.send('shutdown');\n    worker.disconnect();\n    timeout = setTimeout(() => {\n      worker.kill();\n    }, 2000);\n  });\n\n  worker.on('disconnect', () => {\n    clearTimeout(timeout);\n  });\n\n} else if (cluster.isWorker) {\n  const net = require('net');\n  var server = net.createServer((socket) => {\n    // connections never end\n  });\n\n  server.listen(8000);\n\n  process.on('message', (msg) => {\n    if(msg === 'shutdown') {\n      // initiate graceful close of any connections to server\n    }\n  });\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.isConnected()", "type": "method", "name": "isConnected", "desc": "

This function returns true if the worker is connected to its master via its IPC\nchannel, false otherwise. A worker is connected to its master after it's been\ncreated. It is disconnected after the 'disconnect' event is emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.isDead()", "type": "method", "name": "isDead", "desc": "

This function returns true if the worker's process has terminated (either\nbecause of exiting or being signaled). Otherwise, it returns false.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.kill([signal='SIGTERM'])", "type": "method", "name": "kill", "signatures": [ { "params": [ { "textRaw": "`signal` {String} Name of the kill signal to send to the worker process. ", "name": "signal", "type": "String", "desc": "Name of the kill signal to send to the worker process.", "optional": true, "default": "'SIGTERM'" } ] }, { "params": [ { "name": "signal", "optional": true, "default": "'SIGTERM'" } ] } ], "desc": "

This function will kill the worker. In the master, it does this by disconnecting\nthe worker.process, and once disconnected, killing with signal. In the\nworker, it does it by disconnecting the channel, and then exiting with code 0.\n\n

\n

Causes .suicide to be set.\n\n

\n

This method is aliased as worker.destroy() for backwards compatibility.\n\n

\n

Note that in a worker, process.kill() exists, but it is not this function,\nit is [kill][].\n\n

\n" }, { "textRaw": "worker.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Send a message to a worker or master, optionally with a handle.\n\n

\n

In the master this sends a message to a specific worker. It is identical to\n[ChildProcess.send()][].\n\n

\n

In a worker this sends a message to the master. It is identical to\nprocess.send().\n\n

\n

This example will echo back all messages from the master:\n\n

\n
if (cluster.isMaster) {\n  var worker = cluster.fork();\n  worker.send('hi there');\n\n} else if (cluster.isWorker) {\n  process.on('message', (msg) => {\n    process.send(msg);\n  });\n}
\n" } ], "properties": [ { "textRaw": "`id` {Number} ", "name": "id", "desc": "

Each new worker is given its own unique id, this id is stored in the\nid.\n\n

\n

While a worker is alive, this is the key that indexes it in\ncluster.workers\n\n

\n" }, { "textRaw": "`process` {ChildProcess object} ", "name": "process", "desc": "

All workers are created using [child_process.fork()][], the returned object\nfrom this function is stored as .process. In a worker, the global process\nis stored.\n\n

\n

See: [Child Process module][]\n\n

\n

Note that workers will call process.exit(0) if the 'disconnect' event occurs\non process and .suicide is not true. This protects against accidental\ndisconnection.\n\n

\n" }, { "textRaw": "`suicide` {Boolean} ", "name": "suicide", "desc": "

Set by calling .kill() or .disconnect(), until then it is undefined.\n\n

\n

The boolean worker.suicide lets you distinguish between voluntary and accidental\nexit, the master may choose not to respawn a worker based on this value.\n\n

\n
cluster.on('exit', (worker, code, signal) => {\n  if (worker.suicide === true) {\n    console.log('Oh, it was just suicide\\' – no need to worry').\n  }\n});\n\n// kill worker\nworker.kill();
\n" } ] } ], "events": [ { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "params": [], "desc": "

Emitted after the worker IPC channel has disconnected. This can occur when a\nworker exits gracefully, is killed, or is disconnected manually (such as with\nworker.disconnect()).\n\n

\n

There may be a delay between the 'disconnect' and 'exit' events. These events\ncan be used to detect if the process is stuck in a cleanup or if there are\nlong-living connections.\n\n

\n
cluster.on('disconnect', (worker) => {\n  console.log(`The worker #${worker.id} has disconnected`);\n});
\n" }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

When any of the workers die the cluster module will emit the 'exit' event.\n\n

\n

This can be used to restart the worker by calling .fork() again.\n\n

\n
cluster.on('exit', (worker, code, signal) => {\n  console.log('worker %d died (%s). restarting...',\n    worker.process.pid, signal || code);\n  cluster.fork();\n});
\n

See [child_process event: 'exit'][].\n\n

\n" }, { "textRaw": "Event: 'fork'", "type": "event", "name": "fork", "params": [], "desc": "

When a new worker is forked the cluster module will emit a 'fork' event.\nThis can be used to log worker activity, and create your own timeout.\n\n

\n
var timeouts = [];\nfunction errorMsg() {\n  console.error('Something must be wrong with the connection ...');\n}\n\ncluster.on('fork', (worker) => {\n  timeouts[worker.id] = setTimeout(errorMsg, 2000);\n});\ncluster.on('listening', (worker, address) => {\n  clearTimeout(timeouts[worker.id]);\n});\ncluster.on('exit', (worker, code, signal) => {\n  clearTimeout(timeouts[worker.id]);\n  errorMsg();\n});
\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "params": [], "desc": "

After calling listen() from a worker, when the 'listening' event is emitted on\nthe server, a 'listening' event will also be emitted on cluster in the master.\n\n

\n

The event handler is executed with two arguments, the worker contains the worker\nobject and the address object contains the following connection properties:\naddress, port and addressType. This is very useful if the worker is listening\non more than one address.\n\n

\n
cluster.on('listening', (worker, address) => {\n  console.log(\n    `A worker is now connected to ${address.address}:${address.port}`);\n});
\n

The addressType is one of:\n\n

\n
    \n
  • 4 (TCPv4)
  • \n
  • 6 (TCPv6)
  • \n
  • -1 (unix domain socket)
  • \n
  • "udp4" or "udp6" (UDP v4 or v6)
  • \n
\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Emitted when any worker receives a message.\n\n

\n

See [child_process event: 'message'][].\n\n

\n" }, { "textRaw": "Event: 'online'", "type": "event", "name": "online", "params": [], "desc": "

After forking a new worker, the worker should respond with an online message.\nWhen the master receives an online message it will emit this event.\nThe difference between 'fork' and 'online' is that fork is emitted when the\nmaster forks a worker, and 'online' is emitted when the worker is running.\n\n

\n
cluster.on('online', (worker) => {\n  console.log('Yay, the worker responded after it was forked');\n});
\n" }, { "textRaw": "Event: 'setup'", "type": "event", "name": "setup", "params": [], "desc": "

Emitted every time .setupMaster() is called.\n\n

\n

The settings object is the cluster.settings object at the time\n.setupMaster() was called and is advisory only, since multiple calls to\n.setupMaster() can be made in a single tick.\n\n

\n

If accuracy is important, use cluster.settings.\n\n

\n" } ], "methods": [ { "textRaw": "cluster.disconnect([callback])", "type": "method", "name": "disconnect", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} called when all workers are disconnected and handles are closed ", "name": "callback", "type": "Function", "desc": "called when all workers are disconnected and handles are closed", "optional": true } ] }, { "params": [ { "name": "callback", "optional": true } ] } ], "desc": "

Calls .disconnect() on each worker in cluster.workers.\n\n

\n

When they are disconnected all internal handles will be closed, allowing the\nmaster process to die gracefully if no other event is waiting.\n\n

\n

The method takes an optional callback argument which will be called when finished.\n\n

\n

This can only be called from the master process.\n\n

\n" }, { "textRaw": "cluster.fork([env])", "type": "method", "name": "fork", "signatures": [ { "return": { "textRaw": "return {Worker object} ", "name": "return", "type": "Worker object" }, "params": [ { "textRaw": "`env` {Object} Key/value pairs to add to worker process environment. ", "name": "env", "type": "Object", "desc": "Key/value pairs to add to worker process environment.", "optional": true } ] }, { "params": [ { "name": "env", "optional": true } ] } ], "desc": "

Spawn a new worker process.\n\n

\n

This can only be called from the master process.\n\n

\n" }, { "textRaw": "cluster.setupMaster([settings])", "type": "method", "name": "setupMaster", "signatures": [ { "params": [ { "textRaw": "`settings` {Object} ", "options": [ { "textRaw": "`exec` {String} file path to worker file. (Default=`process.argv[1]`) ", "name": "exec", "default": "process.argv[1]", "type": "String", "desc": "file path to worker file." }, { "textRaw": "`args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) ", "name": "args", "default": "process.argv.slice(2)", "type": "Array", "desc": "string arguments passed to worker." }, { "textRaw": "`silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) ", "name": "silent", "default": "false", "type": "Boolean", "desc": "whether or not to send output to parent's stdio." } ], "name": "settings", "type": "Object", "optional": true } ] }, { "params": [ { "name": "settings", "optional": true } ] } ], "desc": "

setupMaster is used to change the default 'fork' behavior. Once called,\nthe settings will be present in cluster.settings.\n\n

\n

Note that:\n\n

\n
    \n
  • any settings changes only affect future calls to .fork() and have no\neffect on workers that are already running
  • \n
  • The only attribute of a worker that cannot be set via .setupMaster() is\nthe env passed to .fork()
  • \n
  • the defaults above apply to the first call only, the defaults for later\ncalls is the current value at the time of cluster.setupMaster() is called
  • \n
\n

Example:\n\n

\n
const cluster = require('cluster');\ncluster.setupMaster({\n  exec: 'worker.js',\n  args: ['--use', 'https'],\n  silent: true\n});\ncluster.fork(); // https worker\ncluster.setupMaster({\n  args: ['--use', 'http']\n});\ncluster.fork(); // http worker
\n

This can only be called from the master process.\n\n

\n" } ], "properties": [ { "textRaw": "`isMaster` {Boolean} ", "name": "isMaster", "desc": "

True if the process is a master. This is determined\nby the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is\nundefined, then isMaster is true.\n\n

\n" }, { "textRaw": "`isWorker` {Boolean} ", "name": "isWorker", "desc": "

True if the process is not a master (it is the negation of cluster.isMaster).\n\n

\n" }, { "textRaw": "cluster.schedulingPolicy", "name": "schedulingPolicy", "desc": "

The scheduling policy, either cluster.SCHED_RR for round-robin or\ncluster.SCHED_NONE to leave it to the operating system. This is a\nglobal setting and effectively frozen once you spawn the first worker\nor call cluster.setupMaster(), whatever comes first.\n\n

\n

SCHED_RR is the default on all operating systems except Windows.\nWindows will change to SCHED_RR once libuv is able to effectively\ndistribute IOCP handles without incurring a large performance hit.\n\n

\n

cluster.schedulingPolicy can also be set through the\nNODE_CLUSTER_SCHED_POLICY environment variable. Valid\nvalues are "rr" and "none".\n\n

\n" }, { "textRaw": "`settings` {Object} ", "name": "settings", "options": [ { "textRaw": "`execArgv` {Array} list of string arguments passed to the Node.js executable. (Default=`process.execArgv`) ", "name": "execArgv", "default": "process.execArgv", "type": "Array", "desc": "list of string arguments passed to the Node.js executable." }, { "textRaw": "`exec` {String} file path to worker file. (Default=`process.argv[1]`) ", "name": "exec", "default": "process.argv[1]", "type": "String", "desc": "file path to worker file." }, { "textRaw": "`args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) ", "name": "args", "default": "process.argv.slice(2)", "type": "Array", "desc": "string arguments passed to worker." }, { "textRaw": "`silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) ", "name": "silent", "default": "false", "type": "Boolean", "desc": "whether or not to send output to parent's stdio." }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "desc": "

After calling .setupMaster() (or .fork()) this settings object will contain\nthe settings, including the default values.\n\n

\n

It is effectively frozen after being set, because .setupMaster() can\nonly be called once.\n\n

\n

This object is not supposed to be changed or set manually, by you.\n\n

\n" }, { "textRaw": "`worker` {Object} ", "name": "worker", "desc": "

A reference to the current worker object. Not available in the master process.\n\n

\n
const cluster = require('cluster');\n\nif (cluster.isMaster) {\n  console.log('I am master');\n  cluster.fork();\n  cluster.fork();\n} else if (cluster.isWorker) {\n  console.log(`I am worker #${cluster.worker.id}`);\n}
\n" }, { "textRaw": "`workers` {Object} ", "name": "workers", "desc": "

A hash that stores the active worker objects, keyed by id field. Makes it\neasy to loop through all the workers. It is only available in the master\nprocess.\n\n

\n

A worker is removed from cluster.workers after the worker has disconnected and\nexited. The order between these two events cannot be determined in advance.\nHowever, it is guaranteed that the removal from the cluster.workers list happens\nbefore last 'disconnect' or 'exit' event is emitted.\n\n

\n
// Go through all workers\nfunction eachWorker(callback) {\n  for (var id in cluster.workers) {\n    callback(cluster.workers[id]);\n  }\n}\neachWorker((worker) => {\n  worker.send('big announcement to all workers');\n});
\n

Should you wish to reference a worker over a communication channel, using\nthe worker's unique id is the easiest way to find the worker.\n\n

\n
socket.on('data', (id) => {\n  var worker = cluster.workers[id];\n});
\n" } ], "type": "module", "displayName": "Cluster" }, { "textRaw": "Console", "name": "console", "stability": 2, "stabilityText": "Stable", "desc": "

The console module provides a simple debugging console that is similar to the\nJavaScript console mechanism provided by web browsers.\n\n

\n

The module exports two specific components:\n\n

\n
    \n
  • A Console class with methods such as console.log(), console.error() and\nconsole.warn() that can be used to write to any Node.js stream.
  • \n
  • A global console instance configured to write to stdout and stderr.\nBecause this object is global, it can be used without calling\nrequire('console').
  • \n
\n

Example using the global console:\n\n

\n
console.log('hello world');\n  // Prints: hello world, to stdout\nconsole.log('hello %s', 'world');\n  // Prints: hello world, to stdout\nconsole.error(new Error('Whoops, something bad happened'));\n  // Prints: [Error: Whoops, something bad happened], to stderr\n\nconst name = 'Will Robinson';\nconsole.warn(`Danger ${name}! Danger!`);\n  // Prints: Danger Will Robinson! Danger!, to stderr
\n

Example using the Console class:\n\n

\n
const out = getStreamSomehow();\nconst err = getStreamSomehow();\nconst myConsole = new console.Console(out, err);\n\nmyConsole.log('hello world');\n  // Prints: hello world, to out\nmyConsole.log('hello %s', 'world');\n  // Prints: hello world, to out\nmyConsole.error(new Error('Whoops, something bad happened'));\n  // Prints: [Error: Whoops, something bad happened], to err\n\nconst name = 'Will Robinson';\nmyConsole.warn(`Danger ${name}! Danger!`);\n  // Prints: Danger Will Robinson! Danger!, to err
\n

While the API for the Console class is designed fundamentally around the\nWeb browser console object, the Console is Node.js is not intended to\nduplicate the browsers functionality exactly.\n\n

\n", "modules": [ { "textRaw": "Asynchronous vs Synchronous Consoles", "name": "asynchronous_vs_synchronous_consoles", "desc": "

The console functions are synchronous when the destination is a terminal or\na file (to avoid lost messages in case of premature exit) and asynchronous\nwhen the destination is a pipe (to avoid blocking for long periods of time).\n\n

\n

In the following example, stdout is non-blocking while stderr is blocking:\n\n

\n
$ node script.js 2> error.log | tee info.log
\n

Typically, the distinction between blocking/non-blocking is not important\nunless an application is logging significant amounts of data. High volume\nlogging should use a Console instance that writes to a pipe.\n\n

\n", "type": "module", "displayName": "Asynchronous vs Synchronous Consoles" } ], "classes": [ { "textRaw": "Class: Console", "type": "class", "name": "Console", "desc": "

The Console class can be used to create a simple logger with configurable\noutput streams and can be accessed using either require('console').Console\nor console.Console:\n\n

\n
const Console = require('console').Console;\nconst Console = console.Console;
\n", "methods": [ { "textRaw": "console.assert(value[, message][, ...])", "type": "method", "name": "assert", "desc": "

A simple assertion test that verifies whether value is truthy. If it is not,\nan AssertionError is throw. If provided, the error message is formatted\nusing [util.format()][] and used as the error message.\n\n

\n
console.assert(true, 'does nothing');\n  // OK\nconsole.assert(false, 'Whoops %s', 'didn\\'t work');\n  // AssertionError: Whoops didn't work
\n", "signatures": [ { "params": [ { "name": "value" }, { "name": "message", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.dir(obj[, options])", "type": "method", "name": "dir", "desc": "

Uses [util.inspect()][] on obj and prints the resulting string to stdout.\nThis function bypasses any custom inspect() function defined on obj. An\noptional options object may be passed that alters certain aspects of the\nformatted string:\n\n

\n
    \n
  • showHidden - if true then the object's non-enumerable and symbol\nproperties will be shown too. Defaults to false.

    \n
  • \n
  • depth - tells inspect how many times to recurse while formatting the\nobject. This is useful for inspecting large complicated objects. Defaults to\n2. To make it recurse indefinitely, pass null.

    \n
  • \n
  • colors - if true, then the output will be styled with ANSI color codes.\nDefaults to false. Colors are customizable; see\n[customizing util.inspect() colors][].

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "obj" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "console.error([data][, ...])", "type": "method", "name": "error", "desc": "

Prints to stderr with newline. Multiple arguments can be passed, with the first\nused as the primary message and all additional used as substitution\nvalues similar to printf() (the arguments are all passed to\n[util.format()][]).\n\n

\n
const code = 5;\nconsole.error('error #%d', code);\n  // Prints: error #5, to stderr\nconsole.error('error', code);\n  // Prints: error 5, to stderr
\n

If formatting elements (e.g. %d) are not found in the first string then\n[util.inspect()][] is called on each argument and the resulting string\nvalues are concatenated. See [util.format()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.info([data][, ...])", "type": "method", "name": "info", "desc": "

The console.info() function is an alias for [console.log()][].\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.log([data][, ...])", "type": "method", "name": "log", "desc": "

Prints to stdout with newline. Multiple arguments can be passed, with the first\nused as the primary message and all additional used as substitution\nvalues similar to printf() (the arguments are all passed to\n[util.format()][]).\n\n

\n
var count = 5;\nconsole.log('count: %d', count);\n  // Prints: count: 5, to stdout\nconsole.log('count: ', count);\n  // Prints: count: 5, to stdout
\n

If formatting elements (e.g. %d) are not found in the first string then\n[util.inspect()][] is called on each argument and the resulting string\nvalues are concatenated. See [util.format()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.time(label)", "type": "method", "name": "time", "desc": "

Used to calculate the duration of a specific operation. To start a timer, call\nthe console.time() method, giving it a unique label as the only parameter. To stop the\ntimer, and to get the elapsed time in milliseconds, just call the\n[console.timeEnd()][] method, again passing the\ntimer's unique label as the parameter.\n\n

\n", "signatures": [ { "params": [ { "name": "label" } ] } ] }, { "textRaw": "console.timeEnd(label)", "type": "method", "name": "timeEnd", "desc": "

Stops a timer that was previously started by calling [console.time()][] and\nprints the result to stdout:\n\n

\n
console.time('100-elements');\nfor (var i = 0; i < 100; i++) {\n  ;\n}\nconsole.timeEnd('100-elements');\n// prints 100-elements: 262ms
\n", "signatures": [ { "params": [ { "name": "label" } ] } ] }, { "textRaw": "console.trace(message[, ...])", "type": "method", "name": "trace", "desc": "

Prints to stderr the string 'Trace :', followed by the [util.format()][]\nformatted message and stack trace to the current position in the code.\n\n

\n
console.trace('Show me');\n  // Prints: (stack trace will vary based on where trace is called)\n  //  Trace: Show me\n  //    at repl:2:9\n  //    at REPLServer.defaultEval (repl.js:248:27)\n  //    at bound (domain.js:287:14)\n  //    at REPLServer.runBound [as eval] (domain.js:300:12)\n  //    at REPLServer.<anonymous> (repl.js:412:12)\n  //    at emitOne (events.js:82:20)\n  //    at REPLServer.emit (events.js:169:7)\n  //    at REPLServer.Interface._onLine (readline.js:210:10)\n  //    at REPLServer.Interface._line (readline.js:549:8)\n  //    at REPLServer.Interface._ttyWrite (readline.js:826:14)
\n", "signatures": [ { "params": [ { "name": "message" }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.warn([data][, ...])", "type": "method", "name": "warn", "desc": "

The console.warn() function is an alias for [console.error()][].\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] } ], "signatures": [ { "params": [ { "name": "stdout" }, { "name": "stderr", "optional": true } ], "desc": "

Creates a new Console by passing one or two writable stream instances.\nstdout is a writable stream to print log or info output. stderr\nis used for warning or error output. If stderr isn't passed, the warning\nand error output will be sent to the stdout.\n\n

\n
const output = fs.createWriteStream('./stdout.log');\nconst errorOutput = fs.createWriteStream('./stderr.log');\n// custom simple logger\nconst logger = new Console(output, errorOutput);\n// use it like console\nvar count = 5;\nlogger.log('count: %d', count);\n// in stdout.log: count 5
\n

The global console is a special Console whose output is sent to\nprocess.stdout and process.stderr. It is equivalent to calling:\n\n

\n
new Console(process.stdout, process.stderr);
\n" } ] } ], "type": "module", "displayName": "Console" }, { "textRaw": "Crypto", "name": "crypto", "stability": 2, "stabilityText": "Stable", "desc": "

Use require('crypto') to access this module.\n\n

\n

The crypto module offers a way of encapsulating secure credentials to be\nused as part of a secure HTTPS net or http connection.\n\n

\n

It also offers a set of wrappers for OpenSSL's hash, hmac, cipher,\ndecipher, sign and verify methods.\n\n

\n", "classes": [ { "textRaw": "Class: Certificate", "type": "class", "name": "Certificate", "desc": "

The class used for working with signed public key & challenges. The most\ncommon usage for this series of functions is when dealing with the <keygen>\nelement. https://www.openssl.org/docs/apps/spkac.html\n\n

\n

Returned by crypto.Certificate.\n\n

\n", "methods": [ { "textRaw": "Certificate.exportChallenge(spkac)", "type": "method", "name": "exportChallenge", "desc": "

Exports the encoded challenge associated with the SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] }, { "textRaw": "Certificate.exportPublicKey(spkac)", "type": "method", "name": "exportPublicKey", "desc": "

Exports the encoded public key from the supplied SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] }, { "textRaw": "Certificate.verifySpkac(spkac)", "type": "method", "name": "verifySpkac", "desc": "

Returns true of false based on the validity of the SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] } ] }, { "textRaw": "Class: Cipher", "type": "class", "name": "Cipher", "desc": "

Class for encrypting data.\n\n

\n

Returned by crypto.createCipher and crypto.createCipheriv.\n\n

\n

Cipher objects are [streams][] that are both readable and writable.\nThe written plain text data is used to produce the encrypted data on\nthe readable side. The legacy update and final methods are also\nsupported.\n\n

\n", "methods": [ { "textRaw": "cipher.final([output_encoding])", "type": "method", "name": "final", "desc": "

Returns any remaining enciphered contents, with output_encoding\nbeing one of: 'binary', 'base64' or 'hex'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n

Note: cipher object can not be used after final() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "cipher.getAuthTag()", "type": "method", "name": "getAuthTag", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod returns a Buffer that represents the authentication tag that\nhas been computed from the given data. Should be called after\nencryption has been completed using the final method!\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "cipher.setAAD(buffer)", "type": "method", "name": "setAAD", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod sets the value used for the additional authenticated data (AAD) input\nparameter.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "cipher.setAutoPadding(auto_padding=true)", "type": "method", "name": "setAutoPadding", "desc": "

You can disable automatic padding of the input data to block size. If\nauto_padding is false, the length of the entire input data must be a\nmultiple of the cipher's block size or final will fail. Useful for\nnon-standard padding, e.g. using 0x0 instead of PKCS padding. You\nmust call this before cipher.final.\n\n

\n", "signatures": [ { "params": [ { "name": "auto_padding", "default": "true" } ] } ] }, { "textRaw": "cipher.update(data[, input_encoding][, output_encoding])", "type": "method", "name": "update", "desc": "

Updates the cipher with data, the encoding of which is given in\ninput_encoding and can be 'utf8', 'ascii' or 'binary'. If no\nencoding is provided, then a buffer is expected.\nIf data is a Buffer then input_encoding is ignored.\n\n

\n

The output_encoding specifies the output format of the enciphered\ndata, and can be 'binary', 'base64' or 'hex'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n

Returns the enciphered contents, and can be called many times with new\ndata as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Decipher", "type": "class", "name": "Decipher", "desc": "

Class for decrypting data.\n\n

\n

Returned by [crypto.createDecipher][] and [crypto.createDecipheriv][].\n\n

\n

Decipher objects are [streams][] that are both readable and writable.\nThe written enciphered data is used to produce the plain-text data on\nthe the readable side. The legacy update and final methods are also\nsupported.\n\n

\n", "methods": [ { "textRaw": "decipher.final([output_encoding])", "type": "method", "name": "final", "desc": "

Returns any remaining plaintext which is deciphered, with\noutput_encoding being one of: 'binary', 'ascii' or 'utf8'. If\nno encoding is provided, then a buffer is returned.\n\n

\n

Note: decipher object can not be used after final() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "decipher.setAAD(buffer)", "type": "method", "name": "setAAD", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod sets the value used for the additional authenticated data (AAD) input\nparameter.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "decipher.setAuthTag(buffer)", "type": "method", "name": "setAuthTag", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod must be used to pass in the received authentication tag.\nIf no tag is provided or if the ciphertext has been tampered with,\nfinal will throw, thus indicating that the ciphertext should\nbe discarded due to failed authentication.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "decipher.setAutoPadding(auto_padding=true)", "type": "method", "name": "setAutoPadding", "desc": "

You can disable auto padding if the data has been encrypted without\nstandard block padding to prevent decipher.final from checking and\nremoving it. This will only work if the input data's length is a multiple of\nthe ciphers block size. You must call this before streaming data to\n[decipher.update][].\n\n

\n", "signatures": [ { "params": [ { "name": "auto_padding", "default": "true" } ] } ] }, { "textRaw": "decipher.update(data[, input_encoding][, output_encoding])", "type": "method", "name": "update", "desc": "

Updates the decipher with data, which is encoded in 'binary',\n'base64' or 'hex'. If no encoding is provided, then a buffer is\nexpected.\nIf data is a Buffer then input_encoding is ignored.\n\n

\n

The output_decoding specifies in what format to return the\ndeciphered plaintext: 'binary', 'ascii' or 'utf8'. If no\nencoding is provided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: DiffieHellman", "type": "class", "name": "DiffieHellman", "desc": "

The class for creating Diffie-Hellman key exchanges.\n\n

\n

Returned by crypto.createDiffieHellman.\n\n

\n", "methods": [ { "textRaw": "diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])", "type": "method", "name": "computeSecret", "desc": "

Computes the shared secret using other_public_key as the other\nparty's public key and returns the computed shared secret. Supplied\nkey is interpreted using specified input_encoding, and secret is\nencoded using specified output_encoding. Encodings can be\n'binary', 'hex', or 'base64'. If the input encoding is not\nprovided, then a buffer is expected.\n\n

\n

If no output encoding is given, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "other_public_key" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.generateKeys([encoding])", "type": "method", "name": "generateKeys", "desc": "

Generates private and public Diffie-Hellman key values, and returns\nthe public key in the specified encoding. This key should be\ntransferred to the other party. Encoding can be 'binary', 'hex',\nor 'base64'. If no encoding is provided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getGenerator([encoding])", "type": "method", "name": "getGenerator", "desc": "

Returns the Diffie-Hellman generator in the specified encoding, which can\nbe 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPrime([encoding])", "type": "method", "name": "getPrime", "desc": "

Returns the Diffie-Hellman prime in the specified encoding, which can\nbe 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPrivateKey([encoding])", "type": "method", "name": "getPrivateKey", "desc": "

Returns the Diffie-Hellman private key in the specified encoding,\nwhich can be 'binary', 'hex', or 'base64'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPublicKey([encoding])", "type": "method", "name": "getPublicKey", "desc": "

Returns the Diffie-Hellman public key in the specified encoding, which\ncan be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.setPrivateKey(private_key[, encoding])", "type": "method", "name": "setPrivateKey", "desc": "

Sets the Diffie-Hellman private key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.setPublicKey(public_key[, encoding])", "type": "method", "name": "setPublicKey", "desc": "

Sets the Diffie-Hellman public key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "encoding", "optional": true } ] } ] } ], "properties": [ { "textRaw": "diffieHellman.verifyError", "name": "verifyError", "desc": "

A bit field containing any warnings and/or errors as a result of a check performed\nduring initialization. The following values are valid for this property\n(defined in constants module):\n\n

\n
    \n
  • DH_CHECK_P_NOT_SAFE_PRIME
  • \n
  • DH_CHECK_P_NOT_PRIME
  • \n
  • DH_UNABLE_TO_CHECK_GENERATOR
  • \n
  • DH_NOT_SUITABLE_GENERATOR
  • \n
\n" } ] }, { "textRaw": "Class: ECDH", "type": "class", "name": "ECDH", "desc": "

The class for creating EC Diffie-Hellman key exchanges.\n\n

\n

Returned by crypto.createECDH.\n\n

\n", "methods": [ { "textRaw": "ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding])", "type": "method", "name": "computeSecret", "desc": "

Computes the shared secret using other_public_key as the other\nparty's public key and returns the computed shared secret. Supplied\nkey is interpreted using specified input_encoding, and secret is\nencoded using specified output_encoding. Encodings can be\n'binary', 'hex', or 'base64'. If the input encoding is not\nprovided, then a buffer is expected.\n\n

\n

If no output encoding is given, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "other_public_key" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.generateKeys([encoding[, format]])", "type": "method", "name": "generateKeys", "desc": "

Generates private and public EC Diffie-Hellman key values, and returns\nthe public key in the specified format and encoding. This key should be\ntransferred to the other party.\n\n

\n

Format specifies point encoding and can be 'compressed', 'uncompressed', or\n'hybrid'. If no format is provided - the point will be returned in\n'uncompressed' format.\n\n

\n

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding" }, { "name": "format]", "optional": true } ] } ] }, { "textRaw": "ECDH.getPrivateKey([encoding])", "type": "method", "name": "getPrivateKey", "desc": "

Returns the EC Diffie-Hellman private key in the specified encoding,\nwhich can be 'binary', 'hex', or 'base64'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.getPublicKey([encoding[, format]])", "type": "method", "name": "getPublicKey", "desc": "

Returns the EC Diffie-Hellman public key in the specified encoding and format.\n\n

\n

Format specifies point encoding and can be 'compressed', 'uncompressed', or\n'hybrid'. If no format is provided - the point will be returned in\n'uncompressed' format.\n\n

\n

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding" }, { "name": "format]", "optional": true } ] } ] }, { "textRaw": "ECDH.setPrivateKey(private_key[, encoding])", "type": "method", "name": "setPrivateKey", "desc": "

Sets the EC Diffie-Hellman private key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n

Example (obtaining a shared secret):\n\n

\n
const crypto = require('crypto');\nconst alice = crypto.createECDH('secp256k1');\nconst bob = crypto.createECDH('secp256k1');\n\nalice.generateKeys();\nbob.generateKeys();\n\nconst alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');\nconst bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');\n\n/* alice_secret and bob_secret should be the same */\nconsole.log(alice_secret == bob_secret);
\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.setPublicKey(public_key[, encoding])", "type": "method", "name": "setPublicKey", "desc": "

Sets the EC Diffie-Hellman public key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Hash", "type": "class", "name": "Hash", "desc": "

The class for creating hash digests of data.\n\n

\n

It is a [stream][] that is both readable and writable. The written data\nis used to compute the hash. Once the writable side of the stream is ended,\nuse the read() method to get the computed hash digest. The legacy update\nand digest methods are also supported.\n\n

\n

Returned by crypto.createHash.\n\n

\n", "methods": [ { "textRaw": "hash.digest([encoding])", "type": "method", "name": "digest", "desc": "

Calculates the digest of all of the passed data to be hashed. The\nencoding can be 'hex', 'binary' or 'base64'. If no encoding\nis provided, then a buffer is returned.\n\n

\n

Note: hash object can not be used after digest() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "hash.update(data[, input_encoding])", "type": "method", "name": "update", "desc": "

Updates the hash content with the given data, the encoding of which\nis given in input_encoding and can be 'utf8', 'ascii' or\n'binary'. If no encoding is provided, and the input is a string, an\nencoding of 'binary' is enforced. If data is a Buffer then\ninput_encoding is ignored.\n\n

\n

This can be called many times with new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Hmac", "type": "class", "name": "Hmac", "desc": "

Class for creating cryptographic hmac content.\n\n

\n

Returned by crypto.createHmac.\n\n

\n", "methods": [ { "textRaw": "hmac.digest([encoding])", "type": "method", "name": "digest", "desc": "

Calculates the digest of all of the passed data to the hmac. The\nencoding can be 'hex', 'binary' or 'base64'. If no encoding\nis provided, then a buffer is returned.\n\n

\n

Note: hmac object can not be used after digest() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "hmac.update(data)", "type": "method", "name": "update", "desc": "

Update the hmac content with the given data. This can be called\nmany times with new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] } ] }, { "textRaw": "Class: Sign", "type": "class", "name": "Sign", "desc": "

Class for generating signatures.\n\n

\n

Returned by crypto.createSign.\n\n

\n

Sign objects are writable [streams][]. The written data is used to\ngenerate the signature. Once all of the data has been written, the\nsign method will return the signature. The legacy update method\nis also supported.\n\n

\n", "methods": [ { "textRaw": "sign.sign(private_key[, output_format])", "type": "method", "name": "sign", "desc": "

Calculates the signature on all the updated data passed through the\nsign.\n\n

\n

private_key can be an object or a string. If private_key is a string, it is\ntreated as the key with no passphrase.\n\n

\n

private_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : A string of passphrase for the private key
  • \n
\n

Returns the signature in output_format which can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nreturned.\n\n

\n

Note: sign object can not be used after sign() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "output_format", "optional": true } ] } ] }, { "textRaw": "sign.update(data)", "type": "method", "name": "update", "desc": "

Updates the sign object with data. This can be called many times\nwith new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] } ] }, { "textRaw": "Class: Verify", "type": "class", "name": "Verify", "desc": "

Class for verifying signatures.\n\n

\n

Returned by crypto.createVerify.\n\n

\n

Verify objects are writable [streams][]. The written data is used to\nvalidate against the supplied signature. Once all of the data has been\nwritten, the verify method will return true if the supplied signature\nis valid. The legacy update method is also supported.\n\n

\n", "methods": [ { "textRaw": "verifier.update(data)", "type": "method", "name": "update", "desc": "

Updates the verifier object with data. This can be called many times\nwith new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] }, { "textRaw": "verifier.verify(object, signature[, signature_format])", "type": "method", "name": "verify", "desc": "

Verifies the signed data by using the object and signature.\nobject is a string containing a PEM encoded object, which can be\none of RSA public key, DSA public key, or X.509 certificate.\nsignature is the previously calculated signature for the data, in\nthe signature_format which can be 'binary', 'hex' or 'base64'.\nIf no encoding is specified, then a buffer is expected.\n\n

\n

Returns true or false depending on the validity of the signature for\nthe data and public key.\n\n

\n

Note: verifier object can not be used after verify() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "object" }, { "name": "signature" }, { "name": "signature_format", "optional": true } ] } ] } ] } ], "properties": [ { "textRaw": "crypto.DEFAULT_ENCODING", "name": "DEFAULT_ENCODING", "desc": "

The default encoding to use for functions that can take either strings\nor buffers. The default value is 'buffer', which makes it default\nto using Buffer objects. This is here to make the crypto module more\neasily compatible with legacy programs that expected 'binary' to be\nthe default encoding.\n\n

\n

Note that new programs will probably expect buffers, so only use this\nas a temporary measure.\n\n

\n" } ], "methods": [ { "textRaw": "crypto.createCipher(algorithm, password)", "type": "method", "name": "createCipher", "desc": "

Creates and returns a cipher object, with the given algorithm and\npassword.\n\n

\n

algorithm is dependent on OpenSSL, examples are 'aes192', etc. On\nrecent releases, openssl list-cipher-algorithms will display the\navailable cipher algorithms. password is used to derive key and IV,\nwhich must be a 'binary' encoded string or a [buffer][].\n\n

\n

It is a [stream][] that is both readable and writable. The written data\nis used to compute the hash. Once the writable side of the stream is ended,\nuse the read() method to get the enciphered contents. The legacy update\nand final methods are also supported.\n\n

\n

Note: createCipher derives keys with the OpenSSL function [EVP_BytesToKey][]\nwith the digest algorithm set to MD5, one iteration, and no salt. The lack of\nsalt allows dictionary attacks as the same password always creates the same key.\nThe low iteration count and non-cryptographically secure hash algorithm allow\npasswords to be tested very rapidly.\n\n

\n

In line with OpenSSL's recommendation to use pbkdf2 instead of [EVP_BytesToKey][] it\nis recommended you derive a key and iv yourself with [crypto.pbkdf2][] and to\nthen use [createCipheriv()][] to create the cipher stream.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "password" } ] } ] }, { "textRaw": "crypto.createCipheriv(algorithm, key, iv)", "type": "method", "name": "createCipheriv", "desc": "

Creates and returns a cipher object, with the given algorithm, key and\niv.\n\n

\n

algorithm is the same as the argument to createCipher(). key is\nthe raw key used by the algorithm. iv is an [initialization vector][].\n\n

\n

key and iv must be 'binary' encoded strings or [buffers][].\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" }, { "name": "iv" } ] } ] }, { "textRaw": "crypto.createCredentials(details)", "type": "method", "name": "createCredentials", "stability": 0, "stabilityText": "Deprecated: Use [`tls.createSecureContext`][] instead.", "desc": "

Creates a credentials object, with the optional details being a\ndictionary with keys:\n\n

\n
    \n
  • pfx : A string or buffer holding the PFX or PKCS12 encoded private\nkey, certificate and CA certificates
  • \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : A string of passphrase for the private key or pfx
  • \n
  • cert : A string holding the PEM encoded certificate
  • \n
  • ca : Either a string or list of strings of PEM encoded CA\ncertificates to trust.
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs\n(Certificate Revocation List)
  • \n
  • ciphers: A string describing the ciphers to use or exclude.\nConsult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT\nfor details on the format.
  • \n
\n

If no 'ca' details are given, then Node.js will use the default\npublicly trusted list of CAs as given in\n

\n

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.\n\n

\n", "signatures": [ { "params": [ { "name": "details" } ] } ] }, { "textRaw": "crypto.createDecipher(algorithm, password)", "type": "method", "name": "createDecipher", "desc": "

Creates and returns a decipher object, with the given algorithm and\nkey. This is the mirror of the [createCipher()][] above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "password" } ] } ] }, { "textRaw": "crypto.createDecipheriv(algorithm, key, iv)", "type": "method", "name": "createDecipheriv", "desc": "

Creates and returns a decipher object, with the given algorithm, key\nand iv. This is the mirror of the [createCipheriv()][] above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" }, { "name": "iv" } ] } ] }, { "textRaw": "crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])", "type": "method", "name": "createDiffieHellman", "desc": "

Creates a Diffie-Hellman key exchange object using the supplied prime and an\noptional specific generator.\ngenerator can be a number, string, or Buffer.\nIf no generator is specified, then 2 is used.\nprime_encoding and generator_encoding can be 'binary', 'hex', or 'base64'.\nIf no prime_encoding is specified, then a Buffer is expected for prime.\nIf no generator_encoding is specified, then a Buffer is expected for generator.\n\n

\n", "signatures": [ { "params": [ { "name": "prime" }, { "name": "prime_encoding", "optional": true }, { "name": "generator", "optional": true }, { "name": "generator_encoding", "optional": true } ] } ] }, { "textRaw": "crypto.createDiffieHellman(prime_length[, generator])", "type": "method", "name": "createDiffieHellman", "desc": "

Creates a Diffie-Hellman key exchange object and generates a prime of\nprime_length bits and using an optional specific numeric generator.\nIf no generator is specified, then 2 is used.\n\n

\n", "signatures": [ { "params": [ { "name": "prime_length" }, { "name": "generator", "optional": true } ] } ] }, { "textRaw": "crypto.createECDH(curve_name)", "type": "method", "name": "createECDH", "desc": "

Creates an Elliptic Curve (EC) Diffie-Hellman key exchange object using a\npredefined curve specified by the curve_name string. Use [getCurves()][] to\nobtain a list of available curve names. On recent releases,\nopenssl ecparam -list_curves will also display the name and description of\neach available elliptic curve.\n\n

\n", "signatures": [ { "params": [ { "name": "curve_name" } ] } ] }, { "textRaw": "crypto.createHash(algorithm)", "type": "method", "name": "createHash", "desc": "

Creates and returns a hash object, a cryptographic hash with the given\nalgorithm which can be used to generate hash digests.\n\n

\n

algorithm is dependent on the available algorithms supported by the\nversion of OpenSSL on the platform. Examples are 'sha256',\n'sha512', etc. On recent releases, openssl\nlist-message-digest-algorithms will display the available digest\nalgorithms.\n\n

\n

Example: this program that takes the sha256 sum of a file\n\n

\n
const filename = process.argv[2];\nconst crypto = require('crypto');\nconst fs = require('fs');\n\nconst shasum = crypto.createHash('sha256');\n\nconst s = fs.ReadStream(filename);\ns.on('data', (d) => {\n  shasum.update(d);\n});\n\ns.on('end', () => {\n  var d = shasum.digest('hex');\n  console.log(`${d}  ${filename}`);\n});
\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.createHmac(algorithm, key)", "type": "method", "name": "createHmac", "desc": "

Creates and returns a hmac object, a cryptographic hmac with the given\nalgorithm and key.\n\n

\n

It is a [stream][] that is both readable and writable. The written\ndata is used to compute the hmac. Once the writable side of the\nstream is ended, use the read() method to get the computed digest.\nThe legacy update and digest methods are also supported.\n\n

\n

algorithm is dependent on the available algorithms supported by\nOpenSSL - see createHash above. key is the hmac key to be used.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" } ] } ] }, { "textRaw": "crypto.createSign(algorithm)", "type": "method", "name": "createSign", "desc": "

Creates and returns a signing object, with the given algorithm. On\nrecent OpenSSL releases, openssl list-public-key-algorithms will\ndisplay the available signing algorithms. Examples are 'RSA-SHA256'.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.createVerify(algorithm)", "type": "method", "name": "createVerify", "desc": "

Creates and returns a verification object, with the given algorithm.\nThis is the mirror of the signing object above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.getCiphers()", "type": "method", "name": "getCiphers", "desc": "

Returns an array with the names of the supported ciphers.\n\n

\n

Example:\n\n

\n
const ciphers = crypto.getCiphers();\nconsole.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.getCurves()", "type": "method", "name": "getCurves", "desc": "

Returns an array with the names of the supported elliptic curves.\n\n

\n

Example:\n\n

\n
const curves = crypto.getCurves();\nconsole.log(curves); // ['secp256k1', 'secp384r1', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.getDiffieHellman(group_name)", "type": "method", "name": "getDiffieHellman", "desc": "

Creates a predefined Diffie-Hellman key exchange object. The\nsupported groups are: 'modp1', 'modp2', 'modp5' (defined in\n[RFC 2412][], but see [Caveats][]) and 'modp14', 'modp15',\n'modp16', 'modp17', 'modp18' (defined in [RFC 3526][]). The\nreturned object mimics the interface of objects created by\n[crypto.createDiffieHellman()][] above, but will not allow changing\nthe keys (with [diffieHellman.setPublicKey()][] for example). The\nadvantage of using this routine is that the parties do not have to\ngenerate nor exchange group modulus beforehand, saving both processor\nand communication time.\n\n

\n

Example (obtaining a shared secret):\n\n

\n
const crypto = require('crypto');\nconst alice = crypto.getDiffieHellman('modp14');\nconst bob = crypto.getDiffieHellman('modp14');\n\nalice.generateKeys();\nbob.generateKeys();\n\nconst alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');\nconst bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');\n\n/* alice_secret and bob_secret should be the same */\nconsole.log(alice_secret == bob_secret);
\n", "signatures": [ { "params": [ { "name": "group_name" } ] } ] }, { "textRaw": "crypto.getHashes()", "type": "method", "name": "getHashes", "desc": "

Returns an array with the names of the supported hash algorithms.\n\n

\n

Example:\n\n

\n
const hashes = crypto.getHashes();\nconsole.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)", "type": "method", "name": "pbkdf2", "desc": "

Asynchronous PBKDF2 function. Applies the selected HMAC digest function\n(default: SHA1) to derive a key of the requested byte length from the password,\nsalt and number of iterations. The callback gets two arguments:\n(err, derivedKey).\n\n

\n

The number of iterations passed to pbkdf2 should be as high as possible, the\nhigher the number, the more secure it will be, but will take a longer amount of\ntime to complete.\n\n

\n

Chosen salts should also be unique. It is recommended that the salts are random\nand their length is greater than 16 bytes. See [NIST SP 800-132] for details.\n\n

\n

Example:\n\n

\n
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', function(err, key) {\n  if (err)\n    throw err;\n  console.log(key.toString('hex'));  // 'c5e478d...1469e50'\n});
\n

You can get a list of supported digest functions with [crypto.getHashes()][].\n\n

\n", "signatures": [ { "params": [ { "name": "password" }, { "name": "salt" }, { "name": "iterations" }, { "name": "keylen" }, { "name": "digest", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest])", "type": "method", "name": "pbkdf2Sync", "desc": "

Synchronous PBKDF2 function. Returns derivedKey or throws error.\n\n

\n", "signatures": [ { "params": [ { "name": "password" }, { "name": "salt" }, { "name": "iterations" }, { "name": "keylen" }, { "name": "digest", "optional": true } ] } ] }, { "textRaw": "crypto.privateDecrypt(private_key, buffer)", "type": "method", "name": "privateDecrypt", "desc": "

Decrypts buffer with private_key.\n\n

\n

private_key can be an object or a string. If private_key is a string, it is\ntreated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.\n\n

\n

private_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : An optional string of passphrase for the private key
  • \n
  • padding : An optional padding value, one of the following:
      \n
    • constants.RSA_NO_PADDING
    • \n
    • constants.RSA_PKCS1_PADDING
    • \n
    • constants.RSA_PKCS1_OAEP_PADDING
    • \n
    \n
  • \n
\n

NOTE: All paddings are defined in constants module.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.privateEncrypt(private_key, buffer)", "type": "method", "name": "privateEncrypt", "desc": "

See above for details. Has the same API as crypto.privateDecrypt.\nDefault padding is RSA_PKCS1_PADDING.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.publicDecrypt(public_key, buffer)", "type": "method", "name": "publicDecrypt", "desc": "

See above for details. Has the same API as crypto.publicEncrypt. Default\npadding is RSA_PKCS1_PADDING.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.publicEncrypt(public_key, buffer)", "type": "method", "name": "publicEncrypt", "desc": "

Encrypts buffer with public_key. Only RSA is currently supported.\n\n

\n

public_key can be an object or a string. If public_key is a string, it is\ntreated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.\nSince RSA public keys may be derived from private keys you may pass a private\nkey to this method.\n\n

\n

public_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : An optional string of passphrase for the private key
  • \n
  • padding : An optional padding value, one of the following:
      \n
    • constants.RSA_NO_PADDING
    • \n
    • constants.RSA_PKCS1_PADDING
    • \n
    • constants.RSA_PKCS1_OAEP_PADDING
    • \n
    \n
  • \n
\n

NOTE: All paddings are defined in constants module.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.randomBytes(size[, callback])", "type": "method", "name": "randomBytes", "desc": "

Generates cryptographically strong pseudo-random data. Usage:\n\n

\n
// async\ncrypto.randomBytes(256, (ex, buf) => {\n  if (ex) throw ex;\n  console.log('Have %d bytes of random data: %s', buf.length, buf);\n});\n\n// sync\nconst buf = crypto.randomBytes(256);\nconsole.log('Have %d bytes of random data: %s', buf.length, buf);
\n

NOTE: This will block if there is insufficient entropy, although it should\nnormally never take longer than a few milliseconds. The only time when this\nmay conceivably block is right after boot, when the whole system is still\nlow on entropy.\n\n

\n", "signatures": [ { "params": [ { "name": "size" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "crypto.setEngine(engine[, flags])", "type": "method", "name": "setEngine", "desc": "

Load and set engine for some/all OpenSSL functions (selected by flags).\n\n

\n

engine could be either an id or a path to the engine's shared library.\n\n

\n

flags is optional and has ENGINE_METHOD_ALL value by default. It could take\none of or mix of following flags (defined in constants module):\n\n

\n
    \n
  • ENGINE_METHOD_RSA
  • \n
  • ENGINE_METHOD_DSA
  • \n
  • ENGINE_METHOD_DH
  • \n
  • ENGINE_METHOD_RAND
  • \n
  • ENGINE_METHOD_ECDH
  • \n
  • ENGINE_METHOD_ECDSA
  • \n
  • ENGINE_METHOD_CIPHERS
  • \n
  • ENGINE_METHOD_DIGESTS
  • \n
  • ENGINE_METHOD_STORE
  • \n
  • ENGINE_METHOD_PKEY_METH
  • \n
  • ENGINE_METHOD_PKEY_ASN1_METH
  • \n
  • ENGINE_METHOD_ALL
  • \n
  • ENGINE_METHOD_NONE
  • \n
\n", "signatures": [ { "params": [ { "name": "engine" }, { "name": "flags", "optional": true } ] } ] } ], "modules": [ { "textRaw": "Recent API Changes", "name": "recent_api_changes", "desc": "

The Crypto module was added to Node.js before there was the concept of a\nunified Stream API, and before there were Buffer objects for handling\nbinary data.\n\n

\n

As such, the streaming classes don't have the typical methods found on\nother Node.js classes, and many methods accepted and returned\nBinary-encoded strings by default rather than Buffers. This was\nchanged to use Buffers by default instead.\n\n

\n

This is a breaking change for some use cases, but not all.\n\n

\n

For example, if you currently use the default arguments to the Sign\nclass, and then pass the results to the Verify class, without ever\ninspecting the data, then it will continue to work as before. Where\nyou once got a binary string and then presented the binary string to\nthe Verify object, you'll now get a Buffer, and present the Buffer to\nthe Verify object.\n\n

\n

However, if you were doing things with the string data that will not\nwork properly on Buffers (such as, concatenating them, storing in\ndatabases, etc.), or you are passing binary strings to the crypto\nfunctions without an encoding argument, then you will need to start\nproviding encoding arguments to specify which encoding you'd like to\nuse. To switch to the previous style of using binary strings by\ndefault, set the crypto.DEFAULT_ENCODING field to 'binary'. Note\nthat new programs will probably expect buffers, so only use this as a\ntemporary measure.\n\n

\n", "type": "module", "displayName": "Recent API Changes" }, { "textRaw": "Caveats", "name": "caveats", "desc": "

The crypto module still supports some algorithms which are already\ncompromised. And the API also allows the use of ciphers and hashes\nwith a small key size that are considered to be too weak for safe use.\n\n

\n

Users should take full responsibility for selecting the crypto\nalgorithm and key size according to their security requirements.\n\n

\n

Based on the recommendations of [NIST SP 800-131A]:\n\n

\n
    \n
  • MD5 and SHA-1 are no longer acceptable where collision resistance is\nrequired such as digital signatures.
  • \n
  • The key used with RSA, DSA and DH algorithms is recommended to have\nat least 2048 bits and that of the curve of ECDSA and ECDH at least\n224 bits, to be safe to use for several years.
  • \n
  • The DH groups of modp1, modp2 and modp5 have a key size\nsmaller than 2048 bits and are not recommended.
  • \n
\n

See the reference for other recommendations and details.\n\n

\n", "type": "module", "displayName": "Caveats" } ], "type": "module", "displayName": "Crypto" }, { "textRaw": "UDP / Datagram Sockets", "name": "dgram", "stability": 2, "stabilityText": "Stable", "desc": "

The dgram module provides an implementation of UDP Datagram sockets.\n\n

\n
const dgram = require('dgram');\nconst server = dgram.createSocket('udp4');\n\nserver.on('error', (err) => {\n  console.log(`server error:\\n${err.stack}`);\n  server.close();\n});\n\nserver.on('message', (msg, rinfo) => {\n  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);\n});\n\nserver.on('listening', () => {\n  var address = server.address();\n  console.log(`server listening ${address.address}:${address.port}`);\n});\n\nserver.bind(41234);\n// server listening 0.0.0.0:41234
\n", "classes": [ { "textRaw": "Class: dgram.Socket", "type": "class", "name": "dgram.Socket", "desc": "

The dgram.Socket object is an [EventEmitter][] that encapsulates the\ndatagram functionality.\n\n

\n

New instances of dgram.Socket are created using [dgram.createSocket()][].\nThe new keyword is not to be used to create dgram.Socket instances.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

The 'close' event is emitted after a socket is closed with [close()][].\nOnce triggered, no new 'message' events will be emitted on this socket.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

The 'error' event is emitted whenever any error occurs. The event handler\nfunction is passed a single Error object.\n\n

\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "desc": "

The 'listening' event is emitted whenever a socket begins listening for\ndatagram messages. This occurs as soon as UDP sockets are created.\n\n

\n", "params": [] }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

The 'message' event is emitted when a new datagram is available on a socket.\nThe event handler function is passed two arguments: msg and rinfo. The\nmsg argument is a [Buffer][] and rinfo is an object with the sender's\naddress information provided by the address, family and port properties:\n\n

\n
socket.on('message', (msg, rinfo) => {\n  console.log('Received %d bytes from %s:%d\\n',\n              msg.length, rinfo.address, rinfo.port);\n});
\n" } ], "methods": [ { "textRaw": "socket.addMembership(multicastAddress[, multicastInterface])", "type": "method", "name": "addMembership", "signatures": [ { "params": [ { "textRaw": "`multicastAddress` String ", "name": "multicastAddress", "desc": "String" }, { "textRaw": "`multicastInterface` String, Optional ", "name": "multicastInterface", "optional": true, "desc": "String" } ] }, { "params": [ { "name": "multicastAddress" }, { "name": "multicastInterface", "optional": true } ] } ], "desc": "

Tells the kernel to join a multicast group at the given multicastAddress\nusing the IP_ADD_MEMBERSHIP socket option. If the multicastInterface\nargument is not specified, the operating system will try to add membership to\nall valid networking interfaces.\n\n

\n" }, { "textRaw": "socket.address()", "type": "method", "name": "address", "desc": "

Returns an object containing the address information for a socket.\nFor UDP sockets, this object will contain address, family and port\nproperties.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.bind(options[, callback])", "type": "method", "name": "bind", "signatures": [ { "params": [ { "textRaw": "`options` {Object} - Required. Supports the following properties: ", "options": [ { "textRaw": "`port` {Number} - Required. ", "name": "port", "type": "Number", "desc": "Required." }, { "textRaw": "`address` {String} - Optional. ", "name": "address", "type": "String", "desc": "Optional." }, { "textRaw": "`exclusive` {Boolean} - Optional. ", "name": "exclusive", "type": "Boolean", "desc": "Optional." } ], "name": "options", "type": "Object", "desc": "Required. Supports the following properties:" }, { "textRaw": "`callback` {Function} - Optional. ", "name": "callback", "type": "Function", "desc": "Optional.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a\nnamed port and optional address that are passed as properties of an\noptions object passed as the first argument. If port is not specified, the\noperating system will attempt to bind to a random port. If address is not\nspecified, the operating system will attempt to listen on all addresses. Once\nbinding is complete, a 'listening' event is emitted and the optional\ncallback function is called.\n\n

\n

The options object may contain an additional exclusive property that is\nuse when using dgram.Socket objects with the [cluster] module. When\nexclusive is set to false (the default), cluster workers will use the same\nunderlying socket handle allowing connection handling duties to be shared.\nWhen exclusive is true, however, the handle is not shared and attempted\nport sharing results in an error.\n\n

\n

An example socket listening on an exclusive port is shown below.\n\n

\n
socket.bind({\n  address: 'localhost',\n  port: 8000,\n  exclusive: true\n});
\n" }, { "textRaw": "socket.close([callback])", "type": "method", "name": "close", "desc": "

Close the underlying socket and stop listening for data on it. If a callback is\nprovided, it is added as a listener for the ['close'][] event.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "socket.dropMembership(multicastAddress[, multicastInterface])", "type": "method", "name": "dropMembership", "signatures": [ { "params": [ { "textRaw": "`multicastAddress` String ", "name": "multicastAddress", "desc": "String" }, { "textRaw": "`multicastInterface` String, Optional ", "name": "multicastInterface", "optional": true, "desc": "String" } ] }, { "params": [ { "name": "multicastAddress" }, { "name": "multicastInterface", "optional": true } ] } ], "desc": "

Instructs the kernel to leave a multicast group at multicastAddress using the\nIP_DROP_MEMBERSHIP socket option. This method is automatically called by the\nkernel when the socket is closed or the process terminates, so most apps will\nnever have reason to call this.\n\n

\n

If multicastInterface is not specified, the operating system will attempt to\ndrop membership on all valid interfaces.\n\n

\n" }, { "textRaw": "socket.send(buf, offset, length, port, address[, callback])", "type": "method", "name": "send", "signatures": [ { "params": [ { "textRaw": "`buf` Buffer object or string. Message to be sent ", "name": "buf", "desc": "Buffer object or string. Message to be sent" }, { "textRaw": "`offset` Integer. Offset in the buffer where the message starts. ", "name": "offset", "desc": "Integer. Offset in the buffer where the message starts." }, { "textRaw": "`length` Integer. Number of bytes in the message. ", "name": "length", "desc": "Integer. Number of bytes in the message." }, { "textRaw": "`port` Integer. Destination port. ", "name": "port", "desc": "Integer. Destination port." }, { "textRaw": "`address` String. Destination hostname or IP address. ", "name": "address", "desc": "String. Destination hostname or IP address." }, { "textRaw": "`callback` Function. Called when the message has been sent. Optional. ", "name": "callback", "desc": "Function. Called when the message has been sent. Optional.", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "offset" }, { "name": "length" }, { "name": "port" }, { "name": "address" }, { "name": "callback", "optional": true } ] } ], "desc": "

Broadcasts a datagram on the socket. The destination port and address must\nbe specified.\n\n

\n

The buf argument is a [Buffer] object containing the message. The offset\nand length specify the offset within the Buffer where the message begins\nand the number of bytes in the message, respectively. With messages that\ncontain multi-byte characters, offset and length will be calculated with\nrespect to [byte length][] and not the character position.\n\n

\n

The address argument is a string. If the value of address is a host name,\nDNS will be used to resolve the address of the host. If the address is not\nspecified or is an empty string, '0.0.0.0' or '::0' will be used instead.\nIt is possible, depending on the network configuration, that these defaults\nmay not work; accordingly, it is best to be explicit about the destination\naddress.\n\n

\n

If the socket has not been previously bound with a call to bind, the socket\nis assigned a random port number and is bound to the "all interfaces" address\n('0.0.0.0' for udp4 sockets, '::0' for udp6 sockets.)\n\n

\n

An optional callback function may be specified to as a way of reporting\nDNS errors or for determining when it is safe to reuse the buf object.\nNote that DNS lookups delay the time to send for at least one tick of the\nNode.js event loop.\n\n

\n

The only way to know for sure that the datagram has been sent is by using a\ncallback. If an error occurs and a callback is given, the error will be\npassed as the first argument to the callback. If a callback is not given,\nthe error is emitted as an 'error' event on the socket object.\n\n

\n

Example of sending a UDP packet to a random port on localhost;\n\n

\n
const dgram = require('dgram');\nconst message = new Buffer('Some bytes');\nconst client = dgram.createSocket('udp4');\nclient.send(message, 0, message.length, 41234, 'localhost', (err) => {\n  client.close();\n});
\n

A Note about UDP datagram size\n\n

\n

The maximum size of an IPv4/v6 datagram depends on the MTU\n(Maximum Transmission Unit) and on the Payload Length field size.\n\n

\n
    \n
  • The Payload Length field is 16 bits wide, which means that a normal\npayload exceed 64K octets including the internet header and data\n(65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header);\nthis is generally true for loopback interfaces, but such long datagram\nmessages are impractical for most hosts and networks.

    \n
  • \n
  • The MTU is the largest size a given link layer technology can support for\ndatagram messages. For any link, IPv4 mandates a minimum MTU of 68\noctets, while the recommended MTU for IPv4 is 576 (typically recommended\nas the MTU for dial-up type applications), whether they arrive whole or in\nfragments.

    \n

    For IPv6, the minimum MTU is 1280 octets, however, the mandatory minimum\nfragment reassembly buffer size is 1500 octets. The value of 68 octets is\nvery small, since most current link layer technologies, like Ethernet, have a\nminimum MTU of 1500.

    \n
  • \n
\n

It is impossible to know in advance the MTU of each link through which\na packet might travel. Sending a datagram greater than the receiver MTU will\nnot work because the packet will get silently dropped without informing the\nsource that the data did not reach its intended recipient.\n\n

\n" }, { "textRaw": "socket.setBroadcast(flag)", "type": "method", "name": "setBroadcast", "signatures": [ { "params": [ { "textRaw": "`flag` Boolean ", "name": "flag", "desc": "Boolean" } ] }, { "params": [ { "name": "flag" } ] } ], "desc": "

Sets or clears the SO_BROADCAST socket option. When set to true, UDP\npackets may be sent to a local interface's broadcast address.\n\n

\n" }, { "textRaw": "socket.setMulticastLoopback(flag)", "type": "method", "name": "setMulticastLoopback", "signatures": [ { "params": [ { "textRaw": "`flag` Boolean ", "name": "flag", "desc": "Boolean" } ] }, { "params": [ { "name": "flag" } ] } ], "desc": "

Sets or clears the IP_MULTICAST_LOOP socket option. When set to true,\nmulticast packets will also be received on the local interface.\n\n

\n" }, { "textRaw": "socket.setMulticastTTL(ttl)", "type": "method", "name": "setMulticastTTL", "signatures": [ { "params": [ { "textRaw": "`ttl` Integer ", "name": "ttl", "desc": "Integer" } ] }, { "params": [ { "name": "ttl" } ] } ], "desc": "

Sets the IP_MULTICAST_TTL socket option. While TTL generally stands for\n"Time to Live", in this context it specifies the number of IP hops that a\npacket is allowed to travel through, specifically for multicast traffic. Each\nrouter or gateway that forwards a packet decrements the TTL. If the TTL is\ndecremented to 0 by a router, it will not be forwarded.\n\n

\n

The argument passed to to socket.setMulticastTTL() is a number of hops\nbetween 0 and 255. The default on most systems is 1 but can vary.\n\n

\n" }, { "textRaw": "socket.setTTL(ttl)", "type": "method", "name": "setTTL", "signatures": [ { "params": [ { "textRaw": "`ttl` Integer ", "name": "ttl", "desc": "Integer" } ] }, { "params": [ { "name": "ttl" } ] } ], "desc": "

Sets the IP_TTL socket option. While TTL generally stands for "Time to Live",\nin this context it specifies the number of IP hops that a packet is allowed to\ntravel through. Each router or gateway that forwards a packet decrements the\nTTL. If the TTL is decremented to 0 by a router, it will not be forwarded.\nChanging TTL values is typically done for network probes or when multicasting.\n\n

\n

The argument to socket.setTTL() is a number of hops between 1 and 255.\nThe default on most systems is 64 but can vary.\n\n

\n" }, { "textRaw": "socket.ref()", "type": "method", "name": "ref", "desc": "

By default, binding a socket will cause it to block the Node.js process from\nexiting as long as the socket is open. The socket.unref() method can be used\nto exclude the socket from the reference counting that keeps the Node.js\nprocess active. The socket.ref() method adds the socket back to the reference\ncounting and restores the default behavior.\n\n

\n

Calling socket.ref() multiples times will have no additional effect.\n\n

\n

The socket.ref() method returns a reference to the socket so calls can be\nchained.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.unref()", "type": "method", "name": "unref", "desc": "

By default, binding a socket will cause it to block the Node.js process from\nexiting as long as the socket is open. The socket.unref() method can be used\nto exclude the socket from the reference counting that keeps the Node.js\nprocess active, allowing the process to exit even if the socket is still\nlistening.\n\n

\n

Calling socket.unref() multiple times will have no addition effect.\n\n

\n

The socket.unref() method returns a reference to the socket so calls can be\nchained.\n\n

\n", "signatures": [ { "params": [] } ] } ], "modules": [ { "textRaw": "[socket.bind([port][, address][, callback])]", "name": "[socket.bind([port][,_address][,_callback])]", "desc": "

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a\nnamed port and optional address. If port is not specified, the operating\nsystem will attempt to bind to a random port. If address is not specified,\nthe operating system will attempt to listen on all addresses. Once binding is\ncomplete, a 'listening' event is emitted and the optional callback function\nis called.\n\n

\n

Note that specifying both a 'listening' event listener and passing a\ncallback to the socket.bind() method is not harmful but not very\nuseful.\n\n

\n

A bound datagram socket keeps the Node.js process running to receive\ndatagram messages.\n\n

\n

If binding fails, an 'error' event is generated. In rare case (e.g.\nattempting to bind with a closed socket), an [Error][] may be thrown.\n\n

\n

Example of a UDP server listening on port 41234:\n\n

\n
const dgram = require('dgram');\nconst server = dgram.createSocket('udp4');\n\nserver.on('error', (err) => {\n  console.log(`server error:\\n${err.stack}`);\n  server.close();\n});\n\nserver.on('message', (msg, rinfo) => {\n  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);\n});\n\nserver.on('listening', () => {\n  var address = server.address();\n  console.log(`server listening ${address.address}:${address.port}`);\n});\n\nserver.bind(41234);\n// server listening 0.0.0.0:41234
\n", "type": "module", "displayName": "[socket.bind([port][, address][, callback])]" }, { "textRaw": "Change to asynchronous `socket.bind()` behavior", "name": "change_to_asynchronous_`socket.bind()`_behavior", "desc": "

As of Node.js v0.10, [dgram.Socket#bind()][] changed to an asynchronous\nexecution model. Legacy code that assumes synchronous behavior, as in the\nfollowing example:\n\n

\n
const s = dgram.createSocket('udp4');\ns.bind(1234);\ns.addMembership('224.0.0.114');
\n

Must be changed to pass a callback function to the [dgram.Socket#bind()][]\nfunction:\n\n

\n
const s = dgram.createSocket('udp4');\ns.bind(1234, () => {\n  s.addMembership('224.0.0.114');\n});
\n", "type": "module", "displayName": "Change to asynchronous `socket.bind()` behavior" } ] } ], "modules": [ { "textRaw": "`dgram` module functions", "name": "`dgram`_module_functions", "methods": [ { "textRaw": "dgram.createSocket(options[, callback])", "type": "method", "name": "createSocket", "signatures": [ { "return": { "textRaw": "Returns: Socket object ", "name": "return", "desc": "Socket object" }, "params": [ { "textRaw": "`options` Object ", "name": "options", "desc": "Object" }, { "textRaw": "`callback` Function. Attached as a listener to `'message'` events. ", "name": "callback", "desc": "Function. Attached as a listener to `'message'` events.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

Creates a dgram.Socket object. The options argument is an object that\nshould contain a type field of either udp4 or udp6 and an optional\nboolean reuseAddr field.\n\n

\n

When reuseAddr is true [socket.bind()][] will reuse the address, even if\nanother process has already bound a socket on it. reuseAddr defaults to\nfalse. An optional callback function can be passed specified which is added\nas a listener for 'message' events.\n\n

\n

Once the socket is created, calling [socket.bind()][] will instruct the\nsocket to begin listening for datagram messages. When address and port are\nnot passed to [socket.bind()][] the method will bind the socket to the "all\ninterfaces" address on a random port (it does the right thing for both udp4\nand udp6 sockets). The bound address and port can be retrieved using\n[socket.address().address][] and [socket.address().port][].\n\n

\n" } ], "type": "module", "displayName": "`dgram` module functions" } ], "methods": [ { "textRaw": "dgram.createSocket(type[, callback])", "type": "method", "name": "createSocket", "signatures": [ { "return": { "textRaw": "Returns: Socket object ", "name": "return", "desc": "Socket object" }, "params": [ { "textRaw": "`type` String. Either 'udp4' or 'udp6' ", "name": "type", "desc": "String. Either 'udp4' or 'udp6'" }, { "textRaw": "`callback` Function. Attached as a listener to `'message'` events. Optional ", "name": "callback", "optional": true, "desc": "Function. Attached as a listener to `'message'` events." } ] }, { "params": [ { "name": "type" }, { "name": "callback", "optional": true } ] } ], "desc": "

Creates a dgram.Socket object of the specified type. The type argument\ncan be either udp4 or udp6. An optional callback function can be passed\nwhich is added as a listener for 'message' events.\n\n

\n

Once the socket is created, calling [socket.bind()][] will instruct the\nsocket to begin listening for datagram messages. When address and port are\nnot passed to [socket.bind()][] the method will bind the socket to the "all\ninterfaces" address on a random port (it does the right thing for both udp4\nand udp6 sockets). The bound address and port can be retrieved using\n[socket.address().address][] and [socket.address().port][].\n\n

\n" } ], "type": "module", "displayName": "dgram" }, { "textRaw": "DNS", "name": "dns", "stability": 2, "stabilityText": "Stable", "desc": "

The dns module contains functions belonging to two different categories:\n\n

\n

1) Functions that use the underlying operating system facilities to perform\nname resolution, and that do not necessarily perform any network communication.\nThis category contains only one function: [dns.lookup()][]. Developers\nlooking to perform name resolution in the same way that other applications on\nthe same operating system behave should use [dns.lookup()][].\n\n

\n

For example, looking up nodejs.org.\n\n

\n
const dns = require('dns');\n\ndns.lookup('nodejs.org', (err, addresses, family) => {\n  console.log('addresses:', addresses);\n});
\n

2) Functions that connect to an actual DNS server to perform name resolution,\nand that always use the network to perform DNS queries. This category\ncontains all functions in the dns module except [dns.lookup()][]. These\nfunctions do not use the same set of configuration files used by\n[dns.lookup()][] (e.g. /etc/hosts). These functions should be used by\ndevelopers who do not want to use the underlying operating system's facilities\nfor name resolution, and instead want to always perform DNS queries.\n\n

\n

Below is an example that resolves 'nodejs.org' then reverse resolves the IP\naddresses that are returned.\n\n

\n
const dns = require('dns');\n\ndns.resolve4('nodejs.org', (err, addresses) => {\n  if (err) throw err;\n\n  console.log(`addresses: ${JSON.stringify(addresses)}`);\n\n  addresses.forEach((a) => {\n    dns.reverse(a, (err, hostnames) => {\n      if (err) {\n        throw err;\n      }\n      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);\n    });\n  });\n});
\n

There are subtle consequences in choosing one over the other, please consult\nthe [Implementation considerations section][] for more information.\n\n

\n", "methods": [ { "textRaw": "dns.getServers()", "type": "method", "name": "getServers", "desc": "

Returns an array of IP address strings that are being used for name\nresolution.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "dns.lookup(hostname[, options], callback)", "type": "method", "name": "lookup", "desc": "

Resolves a hostname (e.g. 'nodejs.org') into the first found A (IPv4) or\nAAAA (IPv6) record. options can be an object or integer. If options is\nnot provided, then IPv4 and IPv6 addresses are both valid. If options is\nan integer, then it must be 4 or 6.\n\n

\n

Alternatively, options can be an object containing these properties:\n\n

\n
    \n
  • family {Number} - The record family. If present, must be the integer\n4 or 6. If not provided, both IP v4 and v6 addresses are accepted.
  • \n
  • hints: {Number} - If present, it should be one or more of the supported\ngetaddrinfo flags. If hints is not provided, then no flags are passed to\ngetaddrinfo. Multiple flags can be passed through hints by logically\nORing their values.\nSee [supported getaddrinfo flags][] below for more information on supported\nflags.
  • \n
  • all: {Boolean} - When true, the callback returns all resolved addresses\nin an array, otherwise returns a single address. Defaults to false.
  • \n
\n

All properties are optional. An example usage of options is shown below.\n\n

\n
{\n  family: 4,\n  hints: dns.ADDRCONFIG | dns.V4MAPPED,\n  all: false\n}
\n

The callback function has arguments (err, address, family). address is a\nstring representation of an IPv4 or IPv6 address. family is either the\ninteger 4 or 6 and denotes the family of address (not necessarily the\nvalue initially passed to lookup).\n\n

\n

With the all option set to true, the arguments change to\n(err, addresses), with addresses being an array of objects with the\nproperties address and family.\n\n

\n

On error, err is an [Error][] object, where err.code is the error code.\nKeep in mind that err.code will be set to 'ENOENT' not only when\nthe hostname does not exist but also when the lookup fails in other ways\nsuch as no available file descriptors.\n\n

\n

dns.lookup() does not necessarily have anything to do with the DNS protocol.\nThe implementation uses an operating system facility that can associate names\nwith addresses, and vice versa. This implementation can have subtle but\nimportant consequences on the behavior of any Node.js program. Please take some\ntime to consult the [Implementation considerations section][] before using\ndns.lookup().\n\n

\n", "modules": [ { "textRaw": "Supported getaddrinfo flags", "name": "supported_getaddrinfo_flags", "desc": "

The following flags can be passed as hints to [dns.lookup()][].\n\n

\n
    \n
  • dns.ADDRCONFIG: Returned address types are determined by the types\nof addresses supported by the current system. For example, IPv4 addresses\nare only returned if the current system has at least one IPv4 address\nconfigured. Loopback addresses are not considered.
  • \n
  • dns.V4MAPPED: If the IPv6 family was specified, but no IPv6 addresses were\nfound, then return IPv4 mapped IPv6 addresses. Note that it is not supported\non some operating systems (e.g FreeBSD 10.1).
  • \n
\n", "type": "module", "displayName": "Supported getaddrinfo flags" } ], "signatures": [ { "params": [ { "name": "hostname" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "dns.lookupService(address, port, callback)", "type": "method", "name": "lookupService", "desc": "

Resolves the given address and port into a hostname and service using\nthe operating system's underlying getnameinfo implementation.\n\n

\n

The callback has arguments (err, hostname, service). The hostname and\nservice arguments are strings (e.g. 'localhost' and 'http' respectively).\n\n

\n

On error, err is an [Error][] object, where err.code is the error code.\n\n

\n
const dns = require('dns');\ndns.lookupService('127.0.0.1', 22, (err, hostname, service) => {\n  console.log(hostname, service);\n    // Prints: localhost ssh\n});
\n", "signatures": [ { "params": [ { "name": "address" }, { "name": "port" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve(hostname[, rrtype], callback)", "type": "method", "name": "resolve", "desc": "

Uses the DNS protocol to resolve a hostname (e.g. 'nodejs.org') into an\narray of the record types specified by rrtype.\n\n

\n

Valid values for rrtype are:\n\n

\n
    \n
  • 'A' - IPV4 addresses, default
  • \n
  • 'AAAA' - IPV6 addresses
  • \n
  • 'MX' - mail exchange records
  • \n
  • 'TXT' - text records
  • \n
  • 'SRV' - SRV records
  • \n
  • 'PTR' - used for reverse IP lookups
  • \n
  • 'NS' - name server records
  • \n
  • 'CNAME' - canonical name records
  • \n
  • 'SOA' - start of authority record
  • \n
\n

The callback function has arguments (err, addresses). When successful,\naddresses will be an array. The type of each item in addresses is\ndetermined by the record type, and described in the documentation for the\ncorresponding lookup methods below.\n\n

\n

On error, err is an [Error][] object, where err.code is\none of the error codes listed below.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "rrtype", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve4(hostname, callback)", "type": "method", "name": "resolve4", "desc": "

Uses the DNS protocol to resolve a IPv4 addresses (A records) for the\nhostname. The addresses argument passed to the callback function\nwill contain an array of IPv4 addresses (e.g.\n['74.125.79.104', '74.125.79.105', '74.125.79.106']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve6(hostname, callback)", "type": "method", "name": "resolve6", "desc": "

Uses the DNS protocol to resolve a IPv6 addresses (AAAA records) for the\nhostname. The addresses argument passed to the callback function\nwill contain an array of IPv6 addresses.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveCname(hostname, callback)", "type": "method", "name": "resolveCname", "desc": "

Uses the DNS protocol to resolve CNAME records for the hostname. The\naddresses argument passed to the callback function\nwill contain an of canonical name records available for the hostname\n(e.g. ['bar.example.com']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveMx(hostname, callback)", "type": "method", "name": "resolveMx", "desc": "

Uses the DNS protocol to resolve mail exchange records (MX records) for the\nhostname. The addresses argument passed to the callback function will\ncontain an array of objects containing both a priority and exchange\nproperty (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveNs(hostname, callback)", "type": "method", "name": "resolveNs", "desc": "

Uses the DNS protocol to resolve name server records (NS records) for the\nhostname. The addresses argument passed to the callback function will\ncontain an array of name server records available for hostname\n(e.g., ['ns1.example.com', 'ns2.example.com']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveSoa(hostname, callback)", "type": "method", "name": "resolveSoa", "desc": "

Uses the DNS protocol to resolve a start of authority record (SOA record) for\nthe hostname. The addresses argument passed to the callback function will\nbe an object with the following properties:\n\n

\n
    \n
  • nsname
  • \n
  • hostmaster
  • \n
  • serial
  • \n
  • refresh
  • \n
  • retry
  • \n
  • expire
  • \n
  • minttl

    \n

    {

    \n
    nsname: 'ns.example.com',\nhostmaster: 'root.example.com',\nserial: 2013101809,\nrefresh: 10000,\nretry: 2400,\nexpire: 604800,\nminttl: 3600
    \n

    }

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveSrv(hostname, callback)", "type": "method", "name": "resolveSrv", "desc": "

Uses the DNS protocol to resolve service records (SRV records) for the\nhostname. The addresses argument passed to the callback function will\nbe an array of objects with the following properties:\n\n

\n
    \n
  • priority
  • \n
  • weight
  • \n
  • port
  • \n
  • name

    \n

    {

    \n
    priority: 10,\nweight: 5,\nport: 21223,\nname: 'service.example.com'
    \n

    }

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveTxt(hostname, callback)", "type": "method", "name": "resolveTxt", "desc": "

Uses the DNS protocol to resolve text queries (TXT records) for the\nhostname. The addresses argument passed to the callback function is\nis a two-dimentional array of the text records available for hostname (e.g.,\n[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of\none record. Depending on the use case, these could be either joined together or\ntreated separately.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.reverse(ip, callback)", "type": "method", "name": "reverse", "desc": "

Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an\narray of hostnames.\n\n

\n

The callback function has arguments (err, hostnames), where hostnames\nis an array of resolved hostnames for the given ip.\n\n

\n

On error, err is an [Error][] object, where err.code is\none of the error codes listed below.\n\n

\n", "signatures": [ { "params": [ { "name": "ip" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.setServers(servers)", "type": "method", "name": "setServers", "desc": "

Sets the IP addresses of the servers to be used when resolving. The servers\nargument is an array of IPv4 or IPv6 addresses.\n\n

\n

If a port specified on the address it will be removed.\n\n

\n

An error will be thrown if an invalid address is provided.\n\n

\n

The dns.setServers() method must not be called while a DNS query is in\nprogress.\n\n

\n", "signatures": [ { "params": [ { "name": "servers" } ] } ] } ], "modules": [ { "textRaw": "Error codes", "name": "error_codes", "desc": "

Each DNS query can return one of the following error codes:\n\n

\n
    \n
  • dns.NODATA: DNS server returned answer with no data.
  • \n
  • dns.FORMERR: DNS server claims query was misformatted.
  • \n
  • dns.SERVFAIL: DNS server returned general failure.
  • \n
  • dns.NOTFOUND: Domain name not found.
  • \n
  • dns.NOTIMP: DNS server does not implement requested operation.
  • \n
  • dns.REFUSED: DNS server refused query.
  • \n
  • dns.BADQUERY: Misformatted DNS query.
  • \n
  • dns.BADNAME: Misformatted hostname.
  • \n
  • dns.BADFAMILY: Unsupported address family.
  • \n
  • dns.BADRESP: Misformatted DNS reply.
  • \n
  • dns.CONNREFUSED: Could not contact DNS servers.
  • \n
  • dns.TIMEOUT: Timeout while contacting DNS servers.
  • \n
  • dns.EOF: End of file.
  • \n
  • dns.FILE: Error reading file.
  • \n
  • dns.NOMEM: Out of memory.
  • \n
  • dns.DESTRUCTION: Channel is being destroyed.
  • \n
  • dns.BADSTR: Misformatted string.
  • \n
  • dns.BADFLAGS: Illegal flags specified.
  • \n
  • dns.NONAME: Given hostname is not numeric.
  • \n
  • dns.BADHINTS: Illegal hints flags specified.
  • \n
  • dns.NOTINITIALIZED: c-ares library initialization not yet performed.
  • \n
  • dns.LOADIPHLPAPI: Error loading iphlpapi.dll.
  • \n
  • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
  • \n
  • dns.CANCELLED: DNS query cancelled.
  • \n
\n", "type": "module", "displayName": "Error codes" }, { "textRaw": "Implementation considerations", "name": "implementation_considerations", "desc": "

Although [dns.lookup()][] and the various dns.resolve*()/dns.reverse()\nfunctions have the same goal of associating a network name with a network\naddress (or vice versa), their behavior is quite different. These differences\ncan have subtle but significant consequences on the behavior of Node.js\nprograms.\n\n

\n", "modules": [ { "textRaw": "`dns.lookup()`", "name": "`dns.lookup()`", "desc": "

Under the hood, [dns.lookup()][] uses the same operating system facilities\nas most other programs. For instance, [dns.lookup()][] will almost always\nresolve a given name the same way as the ping command. On most POSIX-like\noperating systems, the behavior of the [dns.lookup()][] function can be\nmodified by changing settings in nsswitch.conf(5) and/or resolv.conf(5),\nbut note that changing these files will change the behavior of all other\nprograms running on the same operating system.\n\n

\n

Though the call to dns.lookup() will be asynchronous from JavaScript's\nperspective, it is implemented as a synchronous call to getaddrinfo(3) that\nruns on libuv's threadpool. Because libuv's threadpool has a fixed size, it\nmeans that if for whatever reason the call to getaddrinfo(3) takes a long\ntime, other operations that could run on libuv's threadpool (such as filesystem\noperations) will experience degraded performance. In order to mitigate this\nissue, one potential solution is to increase the size of libuv's threadpool by\nsetting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than\n4 (its current default value). For more information on libuv's threadpool, see\n[the official libuv documentation][].\n\n

\n", "type": "module", "displayName": "`dns.lookup()`" }, { "textRaw": "`dns.resolve()`, `dns.resolve*()` and `dns.reverse()`", "name": "`dns.resolve()`,_`dns.resolve*()`_and_`dns.reverse()`", "desc": "

These functions are implemented quite differently than [dns.lookup()][]. They\ndo not use getaddrinfo(3) and they always perform a DNS query on the\nnetwork. This network communication is always done asynchronously, and does not\nuse libuv's threadpool.\n\n

\n

As a result, these functions cannot have the same negative impact on other\nprocessing that happens on libuv's threadpool that [dns.lookup()][] can have.\n\n

\n

They do not use the same set of configuration files than what [dns.lookup()][]\nuses. For instance, they do not use the configuration from /etc/hosts.\n\n

\n", "type": "module", "displayName": "`dns.resolve()`, `dns.resolve*()` and `dns.reverse()`" } ], "type": "module", "displayName": "Implementation considerations" } ], "type": "module", "displayName": "DNS" }, { "textRaw": "Domain", "name": "domain", "stability": 0, "stabilityText": "Deprecated", "desc": "

This module is pending deprecation. Once a replacement API has been\nfinalized, this module will be fully deprecated. Most end users should\nnot have cause to use this module. Users who absolutely must have\nthe functionality that domains provide may rely on it for the time being\nbut should expect to have to migrate to a different solution\nin the future.\n\n

\n

Domains provide a way to handle multiple different IO operations as a\nsingle group. If any of the event emitters or callbacks registered to a\ndomain emit an 'error' event, or throw an error, then the domain object\nwill be notified, rather than losing the context of the error in the\nprocess.on('uncaughtException') handler, or causing the program to\nexit immediately with an error code.\n\n

\n", "miscs": [ { "textRaw": "Warning: Don't Ignore Errors!", "name": "Warning: Don't Ignore Errors!", "type": "misc", "desc": "

Domain error handlers are not a substitute for closing down your\nprocess when an error occurs.\n\n

\n

By the very nature of how [throw][] works in JavaScript, there is almost\nnever any way to safely "pick up where you left off", without leaking\nreferences, or creating some other sort of undefined brittle state.\n\n

\n

The safest way to respond to a thrown error is to shut down the\nprocess. Of course, in a normal web server, you might have many\nconnections open, and it is not reasonable to abruptly shut those down\nbecause an error was triggered by someone else.\n\n

\n

The better approach is to send an error response to the request that\ntriggered the error, while letting the others finish in their normal\ntime, and stop listening for new requests in that worker.\n\n

\n

In this way, domain usage goes hand-in-hand with the cluster module,\nsince the master process can fork a new worker when a worker\nencounters an error. For Node.js programs that scale to multiple\nmachines, the terminating proxy or service registry can take note of\nthe failure, and react accordingly.\n\n

\n

For example, this is not a good idea:\n\n

\n
// XXX WARNING!  BAD IDEA!\n\nvar d = require('domain').create();\nd.on('error', (er) => {\n  // The error won't crash the process, but what it does is worse!\n  // Though we've prevented abrupt process restarting, we are leaking\n  // resources like crazy if this ever happens.\n  // This is no better than process.on('uncaughtException')!\n  console.log('error, but oh well', er.message);\n});\nd.run(() => {\n  require('http').createServer((req, res) => {\n    handleRequest(req, res);\n  }).listen(PORT);\n});
\n

By using the context of a domain, and the resilience of separating our\nprogram into multiple worker processes, we can react more\nappropriately, and handle errors with much greater safety.\n\n

\n
// Much better!\n\nconst cluster = require('cluster');\nconst PORT = +process.env.PORT || 1337;\n\nif (cluster.isMaster) {\n  // In real life, you'd probably use more than just 2 workers,\n  // and perhaps not put the master and worker in the same file.\n  //\n  // You can also of course get a bit fancier about logging, and\n  // implement whatever custom logic you need to prevent DoS\n  // attacks and other bad behavior.\n  //\n  // See the options in the cluster documentation.\n  //\n  // The important thing is that the master does very little,\n  // increasing our resilience to unexpected errors.\n\n  cluster.fork();\n  cluster.fork();\n\n  cluster.on('disconnect', (worker) => {\n    console.error('disconnect!');\n    cluster.fork();\n  });\n\n} else {\n  // the worker\n  //\n  // This is where we put our bugs!\n\n  const domain = require('domain');\n\n  // See the cluster documentation for more details about using\n  // worker processes to serve requests.  How it works, caveats, etc.\n\n  const server = require('http').createServer((req, res) => {\n    var d = domain.create();\n    d.on('error', (er) => {\n      console.error('error', er.stack);\n\n      // Note: we're in dangerous territory!\n      // By definition, something unexpected occurred,\n      // which we probably didn't want.\n      // Anything can happen now!  Be very careful!\n\n      try {\n        // make sure we close down within 30 seconds\n        var killtimer = setTimeout(() => {\n          process.exit(1);\n        }, 30000);\n        // But don't keep the process open just for that!\n        killtimer.unref();\n\n        // stop taking new requests.\n        server.close();\n\n        // Let the master know we're dead.  This will trigger a\n        // 'disconnect' in the cluster master, and then it will fork\n        // a new worker.\n        cluster.worker.disconnect();\n\n        // try to send an error to the request that triggered the problem\n        res.statusCode = 500;\n        res.setHeader('content-type', 'text/plain');\n        res.end('Oops, there was a problem!\\n');\n      } catch (er2) {\n        // oh well, not much we can do at this point.\n        console.error('Error sending 500!', er2.stack);\n      }\n    });\n\n    // Because req and res were created before this domain existed,\n    // we need to explicitly add them.\n    // See the explanation of implicit vs explicit binding below.\n    d.add(req);\n    d.add(res);\n\n    // Now run the handler function in the domain.\n    d.run(() => {\n      handleRequest(req, res);\n    });\n  });\n  server.listen(PORT);\n}\n\n// This part isn't important.  Just an example routing thing.\n// You'd put your fancy application logic here.\nfunction handleRequest(req, res) {\n  switch(req.url) {\n    case '/error':\n      // We do some async stuff, and then...\n      setTimeout(() => {\n        // Whoops!\n        flerb.bark();\n      });\n      break;\n    default:\n      res.end('ok');\n  }\n}
\n" }, { "textRaw": "Additions to Error objects", "name": "Additions to Error objects", "type": "misc", "desc": "

Any time an Error object is routed through a domain, a few extra fields\nare added to it.\n\n

\n
    \n
  • error.domain The domain that first handled the error.
  • \n
  • error.domainEmitter The event emitter that emitted an 'error' event\nwith the error object.
  • \n
  • error.domainBound The callback function which was bound to the\ndomain, and passed an error as its first argument.
  • \n
  • error.domainThrown A boolean indicating whether the error was\nthrown, emitted, or passed to a bound callback function.
  • \n
\n" }, { "textRaw": "Implicit Binding", "name": "Implicit Binding", "type": "misc", "desc": "

If domains are in use, then all new EventEmitter objects (including\nStream objects, requests, responses, etc.) will be implicitly bound to\nthe active domain at the time of their creation.\n\n

\n

Additionally, callbacks passed to lowlevel event loop requests (such as\nto fs.open, or other callback-taking methods) will automatically be\nbound to the active domain. If they throw, then the domain will catch\nthe error.\n\n

\n

In order to prevent excessive memory usage, Domain objects themselves\nare not implicitly added as children of the active domain. If they\nwere, then it would be too easy to prevent request and response objects\nfrom being properly garbage collected.\n\n

\n

If you want to nest Domain objects as children of a parent Domain,\nthen you must explicitly add them.\n\n

\n

Implicit binding routes thrown errors and 'error' events to the\nDomain's 'error' event, but does not register the EventEmitter on the\nDomain, so [domain.dispose()][] will not shut down the EventEmitter.\nImplicit binding only takes care of thrown errors and 'error' events.\n\n

\n" }, { "textRaw": "Explicit Binding", "name": "Explicit Binding", "type": "misc", "desc": "

Sometimes, the domain in use is not the one that ought to be used for a\nspecific event emitter. Or, the event emitter could have been created\nin the context of one domain, but ought to instead be bound to some\nother domain.\n\n

\n

For example, there could be one domain in use for an HTTP server, but\nperhaps we would like to have a separate domain to use for each request.\n\n

\n

That is possible via explicit binding.\n\n

\n

For example:\n\n

\n
// create a top-level domain for the server\nconst domain = require('domain');\nconst http = require('http');\nconst serverDomain = domain.create();\n\nserverDomain.run(() => {\n  // server is created in the scope of serverDomain\n  http.createServer((req, res) => {\n    // req and res are also created in the scope of serverDomain\n    // however, we'd prefer to have a separate domain for each request.\n    // create it first thing, and add req and res to it.\n    var reqd = domain.create();\n    reqd.add(req);\n    reqd.add(res);\n    reqd.on('error', (er) => {\n      console.error('Error', er, req.url);\n      try {\n        res.writeHead(500);\n        res.end('Error occurred, sorry.');\n      } catch (er) {\n        console.error('Error sending 500', er, req.url);\n      }\n    });\n  }).listen(1337);\n});
\n" } ], "methods": [ { "textRaw": "domain.create()", "type": "method", "name": "create", "signatures": [ { "return": { "textRaw": "return: {Domain} ", "name": "return", "type": "Domain" }, "params": [] }, { "params": [] } ], "desc": "

Returns a new Domain object.\n\n

\n" } ], "classes": [ { "textRaw": "Class: Domain", "type": "class", "name": "Domain", "desc": "

The Domain class encapsulates the functionality of routing errors and\nuncaught exceptions to the active Domain object.\n\n

\n

Domain is a child class of [EventEmitter][]. To handle the errors that it\ncatches, listen to its 'error' event.\n\n

\n", "methods": [ { "textRaw": "domain.run(fn[, arg][, ...])", "type": "method", "name": "run", "signatures": [ { "params": [ { "textRaw": "`fn` {Function} ", "name": "fn", "type": "Function" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] }, { "params": [ { "name": "fn" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ], "desc": "

Run the supplied function in the context of the domain, implicitly\nbinding all event emitters, timers, and lowlevel requests that are\ncreated in that context. Optionally, arguments can be passed to\nthe function.\n\n

\n

This is the most basic way to use a domain.\n\n

\n

Example:\n\n

\n
const domain = require('domain');\nconst fs = require('fs');\nconst d = domain.create();\nd.on('error', (er) => {\n  console.error('Caught error!', er);\n});\nd.run(() => {\n  process.nextTick(() => {\n    setTimeout(() => { // simulating some various async stuff\n      fs.open('non-existent file', 'r', (er, fd) => {\n        if (er) throw er;\n        // proceed...\n      });\n    }, 100);\n  });\n});
\n

In this example, the d.on('error') handler will be triggered, rather\nthan crashing the program.\n\n

\n" }, { "textRaw": "domain.add(emitter)", "type": "method", "name": "add", "signatures": [ { "params": [ { "textRaw": "`emitter` {EventEmitter | Timer} emitter or timer to be added to the domain ", "name": "emitter", "type": "EventEmitter | Timer", "desc": "emitter or timer to be added to the domain" } ] }, { "params": [ { "name": "emitter" } ] } ], "desc": "

Explicitly adds an emitter to the domain. If any event handlers called by\nthe emitter throw an error, or if the emitter emits an 'error' event, it\nwill be routed to the domain's 'error' event, just like with implicit\nbinding.\n\n

\n

This also works with timers that are returned from [setInterval()][] and\n[setTimeout()][]. If their callback function throws, it will be caught by\nthe domain 'error' handler.\n\n

\n

If the Timer or EventEmitter was already bound to a domain, it is removed\nfrom that one, and bound to this one instead.\n\n

\n" }, { "textRaw": "domain.remove(emitter)", "type": "method", "name": "remove", "signatures": [ { "params": [ { "textRaw": "`emitter` {EventEmitter | Timer} emitter or timer to be removed from the domain ", "name": "emitter", "type": "EventEmitter | Timer", "desc": "emitter or timer to be removed from the domain" } ] }, { "params": [ { "name": "emitter" } ] } ], "desc": "

The opposite of [domain.add(emitter)][]. Removes domain handling from the\nspecified emitter.\n\n

\n" }, { "textRaw": "domain.bind(callback)", "type": "method", "name": "bind", "signatures": [ { "return": { "textRaw": "return: {Function} The bound function ", "name": "return", "type": "Function", "desc": "The bound function" }, "params": [ { "textRaw": "`callback` {Function} The callback function ", "name": "callback", "type": "Function", "desc": "The callback function" } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

The returned function will be a wrapper around the supplied callback\nfunction. When the returned function is called, any errors that are\nthrown will be routed to the domain's 'error' event.\n\n

\n

Example

\n
const d = domain.create();\n\nfunction readSomeFile(filename, cb) {\n  fs.readFile(filename, 'utf8', d.bind(function(er, data) {\n    // if this throws, it will also be passed to the domain\n    return cb(er, data ? JSON.parse(data) : null);\n  }));\n}\n\nd.on('error', (er) => {\n  // an error occurred somewhere.\n  // if we throw it now, it will crash the program\n  // with the normal line number and stack message.\n});
\n" }, { "textRaw": "domain.intercept(callback)", "type": "method", "name": "intercept", "signatures": [ { "return": { "textRaw": "return: {Function} The intercepted function ", "name": "return", "type": "Function", "desc": "The intercepted function" }, "params": [ { "textRaw": "`callback` {Function} The callback function ", "name": "callback", "type": "Function", "desc": "The callback function" } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

This method is almost identical to [domain.bind(callback)][]. However, in\naddition to catching thrown errors, it will also intercept [Error][]\nobjects sent as the first argument to the function.\n\n

\n

In this way, the common if (err) return callback(err); pattern can be replaced\nwith a single error handler in a single place.\n\n

\n

Example

\n
const d = domain.create();\n\nfunction readSomeFile(filename, cb) {\n  fs.readFile(filename, 'utf8', d.intercept(function(data) {\n    // note, the first argument is never passed to the\n    // callback since it is assumed to be the 'Error' argument\n    // and thus intercepted by the domain.\n\n    // if this throws, it will also be passed to the domain\n    // so the error-handling logic can be moved to the 'error'\n    // event on the domain instead of being repeated throughout\n    // the program.\n    return cb(null, JSON.parse(data));\n  }));\n}\n\nd.on('error', (er) => {\n  // an error occurred somewhere.\n  // if we throw it now, it will crash the program\n  // with the normal line number and stack message.\n});
\n" }, { "textRaw": "domain.enter()", "type": "method", "name": "enter", "desc": "

The enter method is plumbing used by the run, bind, and intercept\nmethods to set the active domain. It sets domain.active and process.domain\nto the domain, and implicitly pushes the domain onto the domain stack managed\nby the domain module (see [domain.exit()][] for details on the domain stack). The\ncall to enter delimits the beginning of a chain of asynchronous calls and I/O\noperations bound to a domain.\n\n

\n

Calling enter changes only the active domain, and does not alter the domain\nitself. enter and exit can be called an arbitrary number of times on a\nsingle domain.\n\n

\n

If the domain on which enter is called has been disposed, enter will return\nwithout setting the domain.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "domain.exit()", "type": "method", "name": "exit", "desc": "

The exit method exits the current domain, popping it off the domain stack.\nAny time execution is going to switch to the context of a different chain of\nasynchronous calls, it's important to ensure that the current domain is exited.\nThe call to exit delimits either the end of or an interruption to the chain\nof asynchronous calls and I/O operations bound to a domain.\n\n

\n

If there are multiple, nested domains bound to the current execution context,\nexit will exit any domains nested within this domain.\n\n

\n

Calling exit changes only the active domain, and does not alter the domain\nitself. enter and exit can be called an arbitrary number of times on a\nsingle domain.\n\n

\n

If the domain on which exit is called has been disposed, exit will return\nwithout exiting the domain.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "domain.dispose()", "type": "method", "name": "dispose", "desc": "
Stability: 0 - Deprecated.  Please recover from failed IO actions\nexplicitly via error event handlers set on the domain.
\n

Once dispose has been called, the domain will no longer be used by callbacks\nbound into the domain via run, bind, or intercept, and a 'dispose' event\nis emitted.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "`members` {Array} ", "name": "members", "desc": "

An array of timers and event emitters that have been explicitly added\nto the domain.\n\n

\n" } ] } ], "type": "module", "displayName": "Domain" }, { "textRaw": "Events", "name": "Events", "stability": 2, "stabilityText": "Stable", "type": "module", "desc": "

Much of the Node.js core API is built around an idiomatic asynchronous\nevent-driven architecture in which certain kinds of objects (called "emitters")\nperiodically emit named events that cause Function objects ("listeners") to be\ncalled.\n\n

\n

For instance: a [net.Server][] object emits an event each time a peer\nconnects to it; a [fs.ReadStream][] emits an event when the file is opened;\na [stream][] emits an event whenever data is available to be read.\n\n

\n

All objects that emit events are instances of the EventEmitter class. These\nobjects expose an eventEmitter.on() function that allows one or more\nFunctions to be attached to named events emitted by the object. Typically,\nevent names are camel-cased strings but any valid JavaScript property key\ncan be used.\n\n

\n

When the EventEmitter object emits an event, all of the Functions attached\nto that specific event are called synchronously. Any values returned by the\ncalled listeners are ignored and will be discarded.\n\n

\n

The following example shows a simple EventEmitter instance with a single\nlistener. The eventEmitter.on() method is used to register listeners, while\nthe eventEmitter.emit() method is used to trigger the event.\n\n

\n
const EventEmitter = require('events');\nconst util = require('util');\n\nfunction MyEmitter() {\n  EventEmitter.call(this);\n}\nutil.inherits(MyEmitter, EventEmitter);\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', function() {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');
\n

Any object can become an EventEmitter through inheritance. The example above\nuses the traditional Node.js style prototypical inheritance using\nthe util.inherits() method. It is, however, possible to use ES6 classes as\nwell:\n\n

\n
const EventEmitter = require('events');\n\nclass MyEmitter extends EventEmitter {}\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', function() {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');
\n", "modules": [ { "textRaw": "Passing arguments and `this` to listeners", "name": "passing_arguments_and_`this`_to_listeners", "desc": "

The eventEmitter.emit() method allows an arbitrary set of arguments to be\npassed to the listener functions. It is important to keep in mind that when an\nordinary listener function is called by the EventEmitter, the standard this\nkeyword is intentionally set to reference the EventEmitter to which the\nlistener is attached.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', function(a, b) {\n  console.log(a, b, this);\n    // Prints:\n    //   a b MyEmitter {\n    //     domain: null,\n    //     _events: { event: [Function] },\n    //     _eventsCount: 1,\n    //     _maxListeners: undefined }\n});\nmyEmitter.emit('event', 'a', 'b');
\n

It is possible to use ES6 Arrow Functions as listeners, however, when doing so,\nthe this keyword will no longer reference the EventEmitter instance:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', (a, b) => {\n  console.log(a, b, this);\n    // Prints: a b {}\n});\nmyEmitter.emit('event', 'a', 'b');
\n", "type": "module", "displayName": "Passing arguments and `this` to listeners" }, { "textRaw": "Asynchronous vs. Synchronous", "name": "asynchronous_vs._synchronous", "desc": "

The EventListener calls all listeners synchronously in the order in which\nthey were registered. This is important to ensure the proper sequencing of\nevents and to avoid race conditions or logic errors. When appropriate,\nlistener functions can switch to an asynchronous mode of operation using\nthe setImmediate() or process.nextTick() methods:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', (a, b) => {\n  setImmediate(() => {\n    console.log('this happens asynchronously');\n  });\n});\nmyEmitter.emit('event', 'a', 'b');
\n", "type": "module", "displayName": "Asynchronous vs. Synchronous" }, { "textRaw": "Handling events only once", "name": "handling_events_only_once", "desc": "

When a listener is registered using the eventEmitter.on() method, that\nlistener will be invoked every time the named event is emitted.\n\n

\n
const myEmitter = new MyEmitter();\nvar m = 0;\nmyEmitter.on('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n  // Prints: 1\nmyEmitter.emit('event');\n  // Prints: 2
\n

Using the eventEmitter.once() method, it is possible to register a listener\nthat is immediately unregistered after it is called.\n\n

\n
const myEmitter = new MyEmitter();\nvar m = 0;\nmyEmitter.once('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n  // Prints: 1\nmyEmitter.emit('event');\n  // Ignored
\n", "type": "module", "displayName": "Handling events only once" }, { "textRaw": "Error events", "name": "error_events", "desc": "

When an error occurs within an EventEmitter instance, the typical action is\nfor an 'error' event to be emitted. These are treated as a special case\nwithin Node.js.\n\n

\n

If an EventEmitter does not have at least one listener registered for the\n'error' event, and an 'error' event is emitted, the error is thrown, a\nstack trace is printed, and the Node.js process exits.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.emit('error', new Error('whoops!'));\n  // Throws and crashes Node.js
\n

To guard against crashing the Node.js process, developers can either register\na listener for the process.on('uncaughtException') event or use the\n[domain][] module (Note, however, that the domain module has been\ndeprecated).\n\n

\n
const myEmitter = new MyEmitter();\n\nprocess.on('uncaughtException', (err) => {\n  console.log('whoops! there was an error');\n});\n\nmyEmitter.emit('error', new Error('whoops!'));\n  // Prints: whoops! there was an error
\n

As a best practice, developers should always register listeners for the\n'error' event:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('error', (err) => {\n  console.log('whoops! there was an error');\n});\nmyEmitter.emit('error', new Error('whoops!'));\n  // Prints: whoops! there was an error
\n", "type": "module", "displayName": "Error events" } ], "classes": [ { "textRaw": "Class: EventEmitter", "type": "class", "name": "EventEmitter", "desc": "

The EventEmitter class is defined and exposed by the events module:\n\n

\n
const EventEmitter = require('events');
\n

All EventEmitters emit the event 'newListener' when new listeners are\nadded and 'removeListener' when a listener is removed.\n\n

\n", "events": [ { "textRaw": "Event: 'newListener'", "type": "event", "name": "newListener", "params": [], "desc": "

The EventEmitter instance will emit it's own 'newListener' event before\na listener is added to it's internal array of listeners.\n\n

\n

Listeners registered for the 'newListener' event will be passed the event\nname and a reference to the listener being added.\n\n

\n

The fact that the event is triggered before adding the listener has a subtle\nbut important side effect: any additional listeners registered to the same\nname within the 'newListener' callback will be inserted before the\nlistener that is in the process of being added.\n\n

\n
const myEmitter = new MyEmitter();\n// Only do this once so we don't loop forever\nmyEmitter.once('newListener', (event, listener) => {\n  if (event === 'event') {\n    // Insert a new listener in front\n    myEmitter.on('event', () => {\n      console.log('B');\n    });\n  }\n});\nmyEmitter.on('event', () => {\n  console.log('A');\n});\nmyEmitter.emit('event');\n  // Prints:\n  //   B\n  //   A
\n" }, { "textRaw": "Event: 'removeListener'", "type": "event", "name": "removeListener", "params": [], "desc": "

The 'removeListener' event is emitted after a listener is removed.\n\n

\n" } ], "methods": [ { "textRaw": "EventEmitter.listenerCount(emitter, event)", "type": "method", "name": "listenerCount", "stability": 0, "stabilityText": "Deprecated: Use [`emitter.listenerCount()`][] instead.", "desc": "

A class method that returns the number of listeners for the given event\nregistered on the given emitter.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', () => {});\nmyEmitter.on('event', () => {});\nconsole.log(EventEmitter.listenerCount(myEmitter, 'event'));\n  // Prints: 2
\n", "signatures": [ { "params": [ { "name": "emitter" }, { "name": "event" } ] } ] }, { "textRaw": "emitter.addListener(event, listener)", "type": "method", "name": "addListener", "desc": "

Alias for emitter.on(event, listener).\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.emit(event[, arg1][, arg2][, ...])", "type": "method", "name": "emit", "desc": "

Synchronously calls each of the listeners registered for event, in the order\nthey were registered, passing the supplied arguments to each.\n\n

\n

Returns true if event had listeners, false otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "arg1", "optional": true }, { "name": "arg2", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "emitter.getMaxListeners()", "type": "method", "name": "getMaxListeners", "desc": "

Returns the current max listener value for the EventEmitter which is either\nset by [emitter.setMaxListeners(n)][] or defaults to\n[EventEmitter.defaultMaxListeners][].\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "emitter.listenerCount(event)", "type": "method", "name": "listenerCount", "signatures": [ { "params": [ { "textRaw": "`event` {Value} The type of event ", "name": "event", "type": "Value", "desc": "The type of event" } ] }, { "params": [ { "name": "event" } ] } ], "desc": "

Returns the number of listeners listening to the event type.\n\n

\n" }, { "textRaw": "emitter.listeners(event)", "type": "method", "name": "listeners", "desc": "

Returns a copy of the array of listeners for the specified event.\n\n

\n
server.on('connection', (stream) => {\n  console.log('someone connected!');\n});\nconsole.log(util.inspect(server.listeners('connection')));\n  // Prints: [ [Function] ]
\n", "signatures": [ { "params": [ { "name": "event" } ] } ] }, { "textRaw": "emitter.on(event, listener)", "type": "method", "name": "on", "desc": "

Adds the listener function to the end of the listeners array for the\nspecified event. No checks are made to see if the listener has already\nbeen added. Multiple calls passing the same combination of event and\nlistener will result in the listener being added, and called, multiple\ntimes.\n\n

\n
server.on('connection', (stream) => {\n  console.log('someone connected!');\n});
\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.once(event, listener)", "type": "method", "name": "once", "desc": "

Adds a one time listener function for the event. This listener is\ninvoked only the next time event is triggered, after which it is removed.\n\n

\n
server.once('connection', (stream) => {\n  console.log('Ah, we have our first user!');\n});
\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.removeAllListeners([event])", "type": "method", "name": "removeAllListeners", "desc": "

Removes all listeners, or those of the specified event.\n\n

\n

Note that it is bad practice to remove listeners added elsewhere in the code,\nparticularly when the EventEmitter instance was created by some other\ncomponent or module (e.g. sockets or file streams).\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event", "optional": true } ] } ] }, { "textRaw": "emitter.removeListener(event, listener)", "type": "method", "name": "removeListener", "desc": "

Removes the specified listener from the listener array for the specified\nevent.\n\n

\n
var callback = function(stream) {\n  console.log('someone connected!');\n};\nserver.on('connection', callback);\n// ...\nserver.removeListener('connection', callback);
\n

removeListener will remove, at most, one instance of a listener from the\nlistener array. If any single listener has been added multiple times to the\nlistener array for the specified event, then removeListener must be called\nmultiple times to remove each instance.\n\n

\n

Because listeners are managed using an internal array, calling this will\nchange the position indices of any listener registered after the listener\nbeing removed. This will not impact the order in which listeners are called,\nbut it will means that any copies of the listener array as returned by\nthe emitter.listeners() method will need to be recreated.\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.setMaxListeners(n)", "type": "method", "name": "setMaxListeners", "desc": "

By default EventEmitters will print a warning if more than 10 listeners are\nadded for a particular event. This is a useful default that helps finding\nmemory leaks. Obviously, not all events should be limited to just 10 listeners.\nThe emitter.setMaxListeners() method allows the limit to be modified for this\nspecific EventEmitter instance. The value can be set to Infinity (or 0)\nfor to indicate an unlimited number of listeners.\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "n" } ] } ] } ], "properties": [ { "textRaw": "EventEmitter.defaultMaxListeners", "name": "defaultMaxListeners", "desc": "

By default, a maximum of 10 listeners can be registered for any single\nevent. This limit can be changed for individual EventEmitter instances\nusing the [emitter.setMaxListeners(n)][] method. To change the default\nfor all EventEmitter instances, the EventEmitter.defaultMaxListeners\nproperty can be used.\n\n

\n

Take caution when setting the EventEmitter.defaultMaxListeners because the\nchange effects all EventEmitter instances, including those created before\nthe change is made. However, calling [emitter.setMaxListeners(n)][] still has\nprecedence over EventEmitter.defaultMaxListeners.\n\n

\n

Note that this is not a hard limit. The EventEmitter instance will allow\nmore listeners to be added but will output a trace warning to stderr indicating\nthat a possible EventEmitter memory leak has been detected. For any single\nEventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners()\nmethods can be used to temporarily avoid this warning:\n\n

\n
emitter.setMaxListeners(emitter.getMaxListeners() + 1);\nemitter.once('event', () => {\n  // do stuff\n  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));\n});
\n" } ] } ] }, { "textRaw": "File System", "name": "fs", "stability": 2, "stabilityText": "Stable", "desc": "

File I/O is provided by simple wrappers around standard POSIX functions. To\nuse this module do require('fs'). All the methods have asynchronous and\nsynchronous forms.\n\n

\n

The asynchronous form always takes a completion callback as its last argument.\nThe arguments passed to the completion callback depend on the method, but the\nfirst argument is always reserved for an exception. If the operation was\ncompleted successfully, then the first argument will be null or undefined.\n\n

\n

When using the synchronous form any exceptions are immediately thrown.\nYou can use try/catch to handle exceptions or allow them to bubble up.\n\n

\n

Here is an example of the asynchronous version:\n\n

\n
const fs = require('fs');\n\nfs.unlink('/tmp/hello', (err) => {\n  if (err) throw err;\n  console.log('successfully deleted /tmp/hello');\n});
\n

Here is the synchronous version:\n\n

\n
const fs = require('fs');\n\nfs.unlinkSync('/tmp/hello');\nconsole.log('successfully deleted /tmp/hello');
\n

With the asynchronous methods there is no guaranteed ordering. So the\nfollowing is prone to error:\n\n

\n
fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  console.log('renamed complete');\n});\nfs.stat('/tmp/world', (err, stats) => {\n  if (err) throw err;\n  console.log(`stats: ${JSON.stringify(stats)}`);\n});
\n

It could be that fs.stat is executed before fs.rename.\nThe correct way to do this is to chain the callbacks.\n\n

\n
fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  fs.stat('/tmp/world', (err, stats) => {\n    if (err) throw err;\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  });\n});
\n

In busy processes, the programmer is strongly encouraged to use the\nasynchronous versions of these calls. The synchronous versions will block\nthe entire process until they complete--halting all connections.\n\n

\n

The relative path to a filename can be used. Remember, however, that this path\nwill be relative to process.cwd().\n\n

\n

Most fs functions let you omit the callback argument. If you do, a default\ncallback is used that rethrows errors. To get a trace to the original call\nsite, set the NODE_DEBUG environment variable:\n\n

\n
$ cat script.js\nfunction bad() {\n  require('fs').readFile('/');\n}\nbad();\n\n$ env NODE_DEBUG=fs node script.js\nfs.js:66\n        throw err;\n              ^\nError: EISDIR, read\n    at rethrow (fs.js:61:21)\n    at maybeCallback (fs.js:79:42)\n    at Object.fs.readFile (fs.js:153:18)\n    at bad (/path/to/script.js:2:17)\n    at Object.<anonymous> (/path/to/script.js:5:1)\n    <etc.>
\n", "classes": [ { "textRaw": "Class: fs.FSWatcher", "type": "class", "name": "fs.FSWatcher", "desc": "

Objects returned from fs.watch() are of this type.\n\n

\n", "events": [ { "textRaw": "Event: 'change'", "type": "event", "name": "change", "params": [], "desc": "

Emitted when something changes in a watched directory or file.\nSee more details in [fs.watch()][].\n\n

\n" }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs.\n\n

\n" } ], "methods": [ { "textRaw": "watcher.close()", "type": "method", "name": "close", "desc": "

Stop watching for changes on the given fs.FSWatcher.\n\n

\n", "signatures": [ { "params": [] } ] } ] }, { "textRaw": "Class: fs.ReadStream", "type": "class", "name": "fs.ReadStream", "desc": "

ReadStream is a [Readable Stream][].\n\n

\n", "events": [ { "textRaw": "Event: 'open'", "type": "event", "name": "open", "params": [], "desc": "

Emitted when the ReadStream's file is opened.\n\n

\n" } ] }, { "textRaw": "Class: fs.Stats", "type": "class", "name": "fs.Stats", "desc": "

Objects returned from [fs.stat()][], [fs.lstat()][] and [fs.fstat()][] and their\nsynchronous counterparts are of this type.\n\n

\n
    \n
  • stats.isFile()
  • \n
  • stats.isDirectory()
  • \n
  • stats.isBlockDevice()
  • \n
  • stats.isCharacterDevice()
  • \n
  • stats.isSymbolicLink() (only valid with [fs.lstat()][])
  • \n
  • stats.isFIFO()
  • \n
  • stats.isSocket()
  • \n
\n

For a regular file [util.inspect(stats)][] would return a string very\nsimilar to this:\n\n

\n
{ dev: 2114,\n  ino: 48064969,\n  mode: 33188,\n  nlink: 1,\n  uid: 85,\n  gid: 100,\n  rdev: 0,\n  size: 527,\n  blksize: 4096,\n  blocks: 8,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
\n

Please note that atime, mtime, birthtime, and ctime are\ninstances of [Date][MDN-Date] object and to compare the values of\nthese objects you should use appropriate methods. For most general\nuses [getTime()][MDN-Date-getTime] will return the number of\nmilliseconds elapsed since 1 January 1970 00:00:00 UTC and this\ninteger should be sufficient for any comparison, however there are\nadditional methods which can be used for displaying fuzzy information.\nMore details can be found in the [MDN JavaScript Reference][MDN-Date]\npage.\n\n

\n", "modules": [ { "textRaw": "Stat Time Values", "name": "stat_time_values", "desc": "

The times in the stat object have the following semantics:\n\n

\n
    \n
  • atime "Access Time" - Time when file data last accessed. Changed\nby the mknod(2), utimes(2), and read(2) system calls.
  • \n
  • mtime "Modified Time" - Time when file data last modified.\nChanged by the mknod(2), utimes(2), and write(2) system calls.
  • \n
  • ctime "Change Time" - Time when file status was last changed\n(inode data modification). Changed by the chmod(2), chown(2),\nlink(2), mknod(2), rename(2), unlink(2), utimes(2),\nread(2), and write(2) system calls.
  • \n
  • birthtime "Birth Time" - Time of file creation. Set once when the\nfile is created. On filesystems where birthtime is not available,\nthis field may instead hold either the ctime or\n1970-01-01T00:00Z (ie, unix epoch timestamp 0). On Darwin and\nother FreeBSD variants, also set if the atime is explicitly set to\nan earlier value than the current birthtime using the utimes(2)\nsystem call.
  • \n
\n

Prior to Node v0.12, the ctime held the birthtime on Windows\nsystems. Note that as of v0.12, ctime is not "creation time", and\non Unix systems, it never was.\n\n

\n", "type": "module", "displayName": "Stat Time Values" } ] }, { "textRaw": "Class: fs.WriteStream", "type": "class", "name": "fs.WriteStream", "desc": "

WriteStream is a [Writable Stream][].\n\n

\n", "events": [ { "textRaw": "Event: 'open'", "type": "event", "name": "open", "params": [], "desc": "

Emitted when the WriteStream's file is opened.\n\n

\n" } ], "properties": [ { "textRaw": "writeStream.bytesWritten", "name": "bytesWritten", "desc": "

The number of bytes written so far. Does not include data that is still queued\nfor writing.\n\n

\n" } ] } ], "methods": [ { "textRaw": "fs.access(path[, mode], callback)", "type": "method", "name": "access", "desc": "

Tests a user's permissions for the file specified by path. mode is an\noptional integer that specifies the accessibility checks to be performed. The\nfollowing constants define the possible values of mode. It is possible to\ncreate a mask consisting of the bitwise OR of two or more values.\n\n

\n
    \n
  • fs.F_OK - File is visible to the calling process. This is useful for\ndetermining if a file exists, but says nothing about rwx permissions.\nDefault if no mode is specified.
  • \n
  • fs.R_OK - File can be read by the calling process.
  • \n
  • fs.W_OK - File can be written by the calling process.
  • \n
  • fs.X_OK - File can be executed by the calling process. This has no effect\non Windows (will behave like fs.F_OK).
  • \n
\n

The final argument, callback, is a callback function that is invoked with\na possible error argument. If any of the accessibility checks fail, the error\nargument will be populated. The following example checks if the file\n/etc/passwd can be read and written by the current process.\n\n

\n
fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) {\n  console.log(err ? 'no access!' : 'can read/write');\n});
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.accessSync(path[, mode])", "type": "method", "name": "accessSync", "desc": "

Synchronous version of [fs.access()][]. This throws if any accessibility checks\nfail, and does nothing otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.appendFile(file, data[, options], callback)", "type": "method", "name": "appendFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`data` {String | Buffer} ", "name": "data", "type": "String | Buffer" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `'utf8'` ", "name": "encoding", "type": "String | Null", "desc": "default = `'utf8'`" }, { "textRaw": "`mode` {Number} default = `0o666` ", "name": "mode", "type": "Number", "desc": "default = `0o666`" }, { "textRaw": "`flag` {String} default = `'a'` ", "name": "flag", "type": "String", "desc": "default = `'a'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously append data to a file, creating the file if it does not yet exist.\ndata can be a string or a buffer.\n\n

\n

Example:\n\n

\n
fs.appendFile('message.txt', 'data to append', (err) => {\n  if (err) throw err;\n  console.log('The "data to append" was appended to file!');\n});
\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.appendFile('message.txt', 'data to append', 'utf8', callback);
\n

Any specified file descriptor has to have been opened for appending.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.appendFileSync(file, data[, options])", "type": "method", "name": "appendFileSync", "desc": "

The synchronous version of [fs.appendFile()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.chmod(path, mode, callback)", "type": "method", "name": "chmod", "desc": "

Asynchronous chmod(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.chmodSync(path, mode)", "type": "method", "name": "chmodSync", "desc": "

Synchronous chmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.chown(path, uid, gid, callback)", "type": "method", "name": "chown", "desc": "

Asynchronous chown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.chownSync(path, uid, gid)", "type": "method", "name": "chownSync", "desc": "

Synchronous chown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.close(fd, callback)", "type": "method", "name": "close", "desc": "

Asynchronous close(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.closeSync(fd)", "type": "method", "name": "closeSync", "desc": "

Synchronous close(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.createReadStream(path[, options])", "type": "method", "name": "createReadStream", "desc": "

Returns a new [ReadStream][] object. (See [Readable Stream][]).\n\n

\n

Be aware that, unlike the default value set for highWaterMark on a\nreadable stream (16 kb), the stream returned by this method has a\ndefault value of 64 kb for the same parameter.\n\n

\n

options is an object or string with the following defaults:\n\n

\n
{ flags: 'r',\n  encoding: null,\n  fd: null,\n  mode: 0o666,\n  autoClose: true\n}
\n

options can include start and end values to read a range of bytes from\nthe file instead of the entire file. Both start and end are inclusive and\nstart at 0. The encoding can be any one of those accepted by [Buffer][].\n\n

\n

If fd is specified, ReadStream will ignore the path argument and will use\nthe specified file descriptor. This means that no 'open' event will be emitted.\nNote that fd should be blocking; non-blocking fds should be passed to\n[net.Socket][].\n\n

\n

If autoClose is false, then the file descriptor won't be closed, even if\nthere's an error. It is your responsibility to close it and make sure\nthere's no file descriptor leak. If autoClose is set to true (default\nbehavior), on error or end the file descriptor will be closed\nautomatically.\n\n

\n

mode sets the file mode (permission and sticky bits), but only if the\nfile was created.\n\n

\n

An example to read the last 10 bytes of a file which is 100 bytes long:\n\n

\n
fs.createReadStream('sample.txt', {start: 90, end: 99});
\n

If options is a string, then it specifies the encoding.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.createWriteStream(path[, options])", "type": "method", "name": "createWriteStream", "desc": "

Returns a new [WriteStream][] object. (See [Writable Stream][]).\n\n

\n

options is an object or string with the following defaults:\n\n

\n
{ flags: 'w',\n  defaultEncoding: 'utf8',\n  fd: null,\n  mode: 0o666 }
\n

options may also include a start option to allow writing data at\nsome position past the beginning of the file. Modifying a file rather\nthan replacing it may require a flags mode of r+ rather than the\ndefault mode w. The defaultEncoding can be any one of those accepted by [Buffer][].\n\n

\n

Like [ReadStream][], if fd is specified, WriteStream will ignore the\npath argument and will use the specified file descriptor. This means that no\n'open' event will be emitted. Note that fd should be blocking; non-blocking\nfds should be passed to [net.Socket][].\n\n

\n

If options is a string, then it specifies the encoding.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.exists(path, callback)", "type": "method", "name": "exists", "stability": 0, "stabilityText": "Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead.", "desc": "

Test whether or not the given path exists by checking with the file system.\nThen call the callback argument with either true or false. Example:\n\n

\n
fs.exists('/etc/passwd', (exists) => {\n  console.log(exists ? 'it\\'s there' : 'no passwd!');\n});
\n

fs.exists() should not be used to check if a file exists before calling\nfs.open(). Doing so introduces a race condition since other processes may\nchange the file's state between the two calls. Instead, user code should\ncall fs.open() directly and handle the error raised if the file is\nnon-existent.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.existsSync(path)", "type": "method", "name": "existsSync", "stability": 0, "stabilityText": "Deprecated: Use [`fs.statSync()`][] or [`fs.accessSync()`][] instead.", "desc": "

Synchronous version of [fs.exists()][].\nReturns true if the file exists, false otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.fchmod(fd, mode, callback)", "type": "method", "name": "fchmod", "desc": "

Asynchronous fchmod(2). No arguments other than a possible exception\nare given to the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fchmodSync(fd, mode)", "type": "method", "name": "fchmodSync", "desc": "

Synchronous fchmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.fchown(fd, uid, gid, callback)", "type": "method", "name": "fchown", "desc": "

Asynchronous fchown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fchownSync(fd, uid, gid)", "type": "method", "name": "fchownSync", "desc": "

Synchronous fchown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.fstat(fd, callback)", "type": "method", "name": "fstat", "desc": "

Asynchronous fstat(2). The callback gets two arguments (err, stats) where\nstats is a fs.Stats object. fstat() is identical to [stat()][], except that\nthe file to be stat-ed is specified by the file descriptor fd.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fstatSync(fd)", "type": "method", "name": "fstatSync", "desc": "

Synchronous fstat(2). Returns an instance of fs.Stats.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.fsync(fd, callback)", "type": "method", "name": "fsync", "desc": "

Asynchronous fsync(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fsyncSync(fd)", "type": "method", "name": "fsyncSync", "desc": "

Synchronous fsync(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.ftruncate(fd, len, callback)", "type": "method", "name": "ftruncate", "desc": "

Asynchronous ftruncate(2). No arguments other than a possible exception are\ngiven to the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "len" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.ftruncateSync(fd, len)", "type": "method", "name": "ftruncateSync", "desc": "

Synchronous ftruncate(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "len" } ] } ] }, { "textRaw": "fs.futimes(fd, atime, mtime, callback)", "type": "method", "name": "futimes", "desc": "

Change the file timestamps of a file referenced by the supplied file\ndescriptor.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "atime" }, { "name": "mtime" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.futimesSync(fd, atime, mtime)", "type": "method", "name": "futimesSync", "desc": "

Synchronous version of [fs.futimes()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "atime" }, { "name": "mtime" } ] } ] }, { "textRaw": "fs.lchmod(path, mode, callback)", "type": "method", "name": "lchmod", "desc": "

Asynchronous lchmod(2). No arguments other than a possible exception\nare given to the completion callback.\n\n

\n

Only available on Mac OS X.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lchmodSync(path, mode)", "type": "method", "name": "lchmodSync", "desc": "

Synchronous lchmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.lchown(path, uid, gid, callback)", "type": "method", "name": "lchown", "desc": "

Asynchronous lchown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lchownSync(path, uid, gid)", "type": "method", "name": "lchownSync", "desc": "

Synchronous lchown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.link(srcpath, dstpath, callback)", "type": "method", "name": "link", "desc": "

Asynchronous link(2). No arguments other than a possible exception are given to\nthe completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "srcpath" }, { "name": "dstpath" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.linkSync(srcpath, dstpath)", "type": "method", "name": "linkSync", "desc": "

Synchronous link(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "srcpath" }, { "name": "dstpath" } ] } ] }, { "textRaw": "fs.lstat(path, callback)", "type": "method", "name": "lstat", "desc": "

Asynchronous lstat(2). The callback gets two arguments (err, stats) where\nstats is a fs.Stats object. lstat() is identical to stat(), except that if\npath is a symbolic link, then the link itself is stat-ed, not the file that it\nrefers to.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lstatSync(path)", "type": "method", "name": "lstatSync", "desc": "

Synchronous lstat(2). Returns an instance of fs.Stats.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.mkdir(path[, mode], callback)", "type": "method", "name": "mkdir", "desc": "

Asynchronous mkdir(2). No arguments other than a possible exception are given\nto the completion callback. mode defaults to 0o777.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.mkdirSync(path[, mode])", "type": "method", "name": "mkdirSync", "desc": "

Synchronous mkdir(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.open(path, flags[, mode], callback)", "type": "method", "name": "open", "desc": "

Asynchronous file open. See open(2). flags can be:\n\n

\n
    \n
  • 'r' - Open file for reading.\nAn exception occurs if the file does not exist.

    \n
  • \n
  • 'r+' - Open file for reading and writing.\nAn exception occurs if the file does not exist.

    \n
  • \n
  • 'rs' - Open file for reading in synchronous mode. Instructs the operating\nsystem to bypass the local file system cache.

    \n

    This is primarily useful for opening files on NFS mounts as it allows you to\nskip the potentially stale local cache. It has a very real impact on I/O\nperformance so don't use this flag unless you need it.

    \n

    Note that this doesn't turn fs.open() into a synchronous blocking call.\nIf that's what you want then you should be using fs.openSync()

    \n
  • \n
  • 'rs+' - Open file for reading and writing, telling the OS to open it\nsynchronously. See notes for 'rs' about using this with caution.

    \n
  • \n
  • 'w' - Open file for writing.\nThe file is created (if it does not exist) or truncated (if it exists).

    \n
  • \n
  • 'wx' - Like 'w' but fails if path exists.

    \n
  • \n
  • 'w+' - Open file for reading and writing.\nThe file is created (if it does not exist) or truncated (if it exists).

    \n
  • \n
  • 'wx+' - Like 'w+' but fails if path exists.

    \n
  • \n
  • 'a' - Open file for appending.\nThe file is created if it does not exist.

    \n
  • \n
  • 'ax' - Like 'a' but fails if path exists.

    \n
  • \n
  • 'a+' - Open file for reading and appending.\nThe file is created if it does not exist.

    \n
  • \n
  • 'ax+' - Like 'a+' but fails if path exists.

    \n
  • \n
\n

mode sets the file mode (permission and sticky bits), but only if the file was\ncreated. It defaults to 0666, readable and writeable.\n\n

\n

The callback gets two arguments (err, fd).\n\n

\n

The exclusive flag 'x' (O_EXCL flag in open(2)) ensures that path is newly\ncreated. On POSIX systems, path is considered to exist even if it is a symlink\nto a non-existent file. The exclusive flag may or may not work with network file\nsystems.\n\n

\n

flags can also be a number as documented by open(2); commonly used constants\nare available from require('constants'). On Windows, flags are translated to\ntheir equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE,\nor O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "flags" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.openSync(path, flags[, mode])", "type": "method", "name": "openSync", "desc": "

Synchronous version of [fs.open()][]. Returns an integer representing the file\ndescriptor.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "flags" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.read(fd, buffer, offset, length, position, callback)", "type": "method", "name": "read", "desc": "

Read data from the file specified by fd.\n\n

\n

buffer is the buffer that the data will be written to.\n\n

\n

offset is the offset in the buffer to start writing at.\n\n

\n

length is an integer specifying the number of bytes to read.\n\n

\n

position is an integer specifying where to begin reading from in the file.\nIf position is null, data will be read from the current file position.\n\n

\n

The callback is given the three arguments, (err, bytesRead, buffer).\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readdir(path, callback)", "type": "method", "name": "readdir", "desc": "

Asynchronous readdir(3). Reads the contents of a directory.\nThe callback gets two arguments (err, files) where files is an array of\nthe names of the files in the directory excluding '.' and '..'.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readdirSync(path)", "type": "method", "name": "readdirSync", "desc": "

Synchronous readdir(3). Returns an array of filenames excluding '.' and\n'..'.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.readFile(file[, options], callback)", "type": "method", "name": "readFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `null` ", "name": "encoding", "type": "String | Null", "desc": "default = `null`" }, { "textRaw": "`flag` {String} default = `'r'` ", "name": "flag", "type": "String", "desc": "default = `'r'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously reads the entire contents of a file. Example:\n\n

\n
fs.readFile('/etc/passwd', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});
\n

The callback is passed two arguments (err, data), where data is the\ncontents of the file.\n\n

\n

If no encoding is specified, then the raw buffer is returned.\n\n

\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.readFile('/etc/passwd', 'utf8', callback);
\n

Any specified file descriptor has to support reading.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.readFileSync(file[, options])", "type": "method", "name": "readFileSync", "desc": "

Synchronous version of [fs.readFile][]. Returns the contents of the file.\n\n

\n

If the encoding option is specified then this function returns a\nstring. Otherwise it returns a buffer.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.readlink(path, callback)", "type": "method", "name": "readlink", "desc": "

Asynchronous readlink(2). The callback gets two arguments (err,\nlinkString).\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readlinkSync(path)", "type": "method", "name": "readlinkSync", "desc": "

Synchronous readlink(2). Returns the symbolic link's string value.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.realpath(path[, cache], callback)", "type": "method", "name": "realpath", "desc": "

Asynchronous realpath(2). The callback gets two arguments (err,\nresolvedPath). May use process.cwd to resolve relative paths. cache is an\nobject literal of mapped paths that can be used to force a specific path\nresolution or avoid additional fs.stat calls for known real paths.\n\n

\n

Example:\n\n

\n
var cache = {'/etc':'/private/etc'};\nfs.realpath('/etc/passwd', cache, (err, resolvedPath) => {\n  if (err) throw err;\n  console.log(resolvedPath);\n});
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "cache", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readSync(fd, buffer, offset, length, position)", "type": "method", "name": "readSync", "desc": "

Synchronous version of [fs.read()][]. Returns the number of bytesRead.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position" } ] } ] }, { "textRaw": "fs.realpathSync(path[, cache])", "type": "method", "name": "realpathSync", "desc": "

Synchronous realpath(2). Returns the resolved path. cache is an\nobject literal of mapped paths that can be used to force a specific path\nresolution or avoid additional fs.stat calls for known real paths.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "cache", "optional": true } ] } ] }, { "textRaw": "fs.rename(oldPath, newPath, callback)", "type": "method", "name": "rename", "desc": "

Asynchronous rename(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "oldPath" }, { "name": "newPath" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.renameSync(oldPath, newPath)", "type": "method", "name": "renameSync", "desc": "

Synchronous rename(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "oldPath" }, { "name": "newPath" } ] } ] }, { "textRaw": "fs.rmdir(path, callback)", "type": "method", "name": "rmdir", "desc": "

Asynchronous rmdir(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.rmdirSync(path)", "type": "method", "name": "rmdirSync", "desc": "

Synchronous rmdir(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.stat(path, callback)", "type": "method", "name": "stat", "desc": "

Asynchronous stat(2). The callback gets two arguments (err, stats) where\nstats is a [fs.Stats][] object. See the [fs.Stats][] section below for more\ninformation.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.statSync(path)", "type": "method", "name": "statSync", "desc": "

Synchronous stat(2). Returns an instance of [fs.Stats][].\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.symlink(target, path[, type], callback)", "type": "method", "name": "symlink", "desc": "

Asynchronous symlink(2). No arguments other than a possible exception are given\nto the completion callback.\nThe type argument can be set to 'dir', 'file', or 'junction' (default\nis 'file') and is only available on Windows (ignored on other platforms).\nNote that Windows junction points require the destination path to be absolute. When using\n'junction', the target argument will automatically be normalized to absolute path.\n\n

\n

Here is an example below:\n\n

\n
fs.symlink('./foo', './new-port');
\n

It would create a symlic link named with "new-port" that points to "foo".\n\n

\n", "signatures": [ { "params": [ { "name": "target" }, { "name": "path" }, { "name": "type", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.symlinkSync(target, path[, type])", "type": "method", "name": "symlinkSync", "desc": "

Synchronous symlink(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "target" }, { "name": "path" }, { "name": "type", "optional": true } ] } ] }, { "textRaw": "fs.truncate(path, len, callback)", "type": "method", "name": "truncate", "desc": "

Asynchronous truncate(2). No arguments other than a possible exception are\ngiven to the completion callback. A file descriptor can also be passed as the\nfirst argument. In this case, fs.ftruncate() is called.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "len" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.truncateSync(path, len)", "type": "method", "name": "truncateSync", "desc": "

Synchronous truncate(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "len" } ] } ] }, { "textRaw": "fs.unlink(path, callback)", "type": "method", "name": "unlink", "desc": "

Asynchronous unlink(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.unlinkSync(path)", "type": "method", "name": "unlinkSync", "desc": "

Synchronous unlink(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.unwatchFile(filename[, listener])", "type": "method", "name": "unwatchFile", "desc": "

Stop watching for changes on filename. If listener is specified, only that\nparticular listener is removed. Otherwise, all listeners are removed and you\nhave effectively stopped watching filename.\n\n

\n

Calling fs.unwatchFile() with a filename that is not being watched is a\nno-op, not an error.\n\n

\n

Note: [fs.watch()][] is more efficient than fs.watchFile() and fs.unwatchFile().\nfs.watch() should be used instead of fs.watchFile() and fs.unwatchFile()\nwhen possible.\n\n

\n", "signatures": [ { "params": [ { "name": "filename" }, { "name": "listener", "optional": true } ] } ] }, { "textRaw": "fs.utimes(path, atime, mtime, callback)", "type": "method", "name": "utimes", "desc": "

Change file timestamps of the file referenced by the supplied path.\n\n

\n

Note: the arguments atime and mtime of the following related functions does\nfollow the below rules:\n\n

\n
    \n
  • If the value is a numberable string like '123456789', the value would get\nconverted to corresponding number.
  • \n
  • If the value is NaN or Infinity, the value would get converted to\nDate.now().
  • \n
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "atime" }, { "name": "mtime" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.utimesSync(path, atime, mtime)", "type": "method", "name": "utimesSync", "desc": "

Synchronous version of [fs.utimes()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "atime" }, { "name": "mtime" } ] } ] }, { "textRaw": "fs.watch(filename[, options][, listener])", "type": "method", "name": "watch", "desc": "

Watch for changes on filename, where filename is either a file or a\ndirectory. The returned object is a [fs.FSWatcher][].\n\n

\n

The second argument is optional. The options if provided should be an object.\nThe supported boolean members are persistent and recursive. persistent\nindicates whether the process should continue to run as long as files are being\nwatched. recursive indicates whether all subdirectories should be watched, or\nonly the current directory. This applies when a directory is specified, and only\non supported platforms (See Caveats below).\n\n

\n

The default is { persistent: true, recursive: false }.\n\n

\n

The listener callback gets two arguments (event, filename). event is either\n'rename' or 'change', and filename is the name of the file which triggered\nthe event.\n\n

\n", "miscs": [ { "textRaw": "Caveats", "name": "Caveats", "type": "misc", "desc": "

The fs.watch API is not 100% consistent across platforms, and is\nunavailable in some situations.\n\n

\n

The recursive option is only supported on OS X and Windows.\n\n

\n", "miscs": [ { "textRaw": "Availability", "name": "Availability", "type": "misc", "desc": "

This feature depends on the underlying operating system providing a way\nto be notified of filesystem changes.\n\n

\n
    \n
  • On Linux systems, this uses inotify.
  • \n
  • On BSD systems, this uses kqueue.
  • \n
  • On OS X, this uses kqueue for files and 'FSEvents' for directories.
  • \n
  • On SunOS systems (including Solaris and SmartOS), this uses event ports.
  • \n
  • On Windows systems, this feature depends on ReadDirectoryChangesW.
  • \n
\n

If the underlying functionality is not available for some reason, then\nfs.watch will not be able to function. For example, watching files or\ndirectories on network file systems (NFS, SMB, etc.) often doesn't work\nreliably or at all.\n\n

\n

You can still use fs.watchFile, which uses stat polling, but it is slower and\nless reliable.\n\n

\n" }, { "textRaw": "Filename Argument", "name": "Filename Argument", "type": "misc", "desc": "

Providing filename argument in the callback is only supported on Linux and\nWindows. Even on supported platforms, filename is not always guaranteed to\nbe provided. Therefore, don't assume that filename argument is always\nprovided in the callback, and have some fallback logic if it is null.\n\n

\n
fs.watch('somedir', (event, filename) => {\n  console.log(`event is: ${event}`);\n  if (filename) {\n    console.log(`filename provided: ${filename}`);\n  } else {\n    console.log('filename not provided');\n  }\n});
\n" } ] } ], "signatures": [ { "params": [ { "name": "filename" }, { "name": "options", "optional": true }, { "name": "listener", "optional": true } ] } ] }, { "textRaw": "fs.watchFile(filename[, options], listener)", "type": "method", "name": "watchFile", "desc": "

Watch for changes on filename. The callback listener will be called each\ntime the file is accessed.\n\n

\n

The options argument may be omitted. If provided, it should be an object. The\noptions object may contain a boolean named persistent that indicates\nwhether the process should continue to run as long as files are being watched.\nThe options object may specify an interval property indicating how often the\ntarget should be polled in milliseconds. The default is\n{ persistent: true, interval: 5007 }.\n\n

\n

The listener gets two arguments the current stat object and the previous\nstat object:\n\n

\n
fs.watchFile('message.text', (curr, prev) => {\n  console.log(`the current mtime is: ${curr.mtime}`);\n  console.log(`the previous mtime was: ${prev.mtime}`);\n});
\n

These stat objects are instances of fs.Stat.\n\n

\n

If you want to be notified when the file was modified, not just accessed,\nyou need to compare curr.mtime and prev.mtime.\n\n

\n

Note: when an fs.watchFile operation results in an ENOENT error, it will\n invoke the listener once, with all the fields zeroed (or, for dates, the Unix\n Epoch). In Windows, blksize and blocks fields will be undefined, instead\n of zero. If the file is created later on, the listener will be called again,\n with the latest stat objects. This is a change in functionality since v0.10.\n\n

\n

Note: [fs.watch()][] is more efficient than fs.watchFile and fs.unwatchFile.\nfs.watch should be used instead of fs.watchFile and fs.unwatchFile\nwhen possible.\n\n

\n", "signatures": [ { "params": [ { "name": "filename" }, { "name": "options", "optional": true }, { "name": "listener" } ] } ] }, { "textRaw": "fs.write(fd, buffer, offset, length[, position], callback)", "type": "method", "name": "write", "desc": "

Write buffer to the file specified by fd.\n\n

\n

offset and length determine the part of the buffer to be written.\n\n

\n

position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position. See pwrite(2).\n\n

\n

The callback will be given three arguments (err, written, buffer) where\nwritten specifies how many bytes were written from buffer.\n\n

\n

Note that it is unsafe to use fs.write multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.write(fd, data[, position[, encoding]], callback)", "type": "method", "name": "write", "desc": "

Write data to the file specified by fd. If data is not a Buffer instance\nthen the value will be coerced to a string.\n\n

\n

position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number' the data will be written at\nthe current position. See pwrite(2).\n\n

\n

encoding is the expected string encoding.\n\n

\n

The callback will receive the arguments (err, written, string) where written\nspecifies how many bytes the passed string required to be written. Note that\nbytes written is not the same as string characters. See [Buffer.byteLength][].\n\n

\n

Unlike when writing buffer, the entire string must be written. No substring\nmay be specified. This is because the byte offset of the resulting data may not\nbe the same as the string offset.\n\n

\n

Note that it is unsafe to use fs.write multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.writeFile(file, data[, options], callback)", "type": "method", "name": "writeFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`data` {String | Buffer} ", "name": "data", "type": "String | Buffer" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `'utf8'` ", "name": "encoding", "type": "String | Null", "desc": "default = `'utf8'`" }, { "textRaw": "`mode` {Number} default = `0o666` ", "name": "mode", "type": "Number", "desc": "default = `0o666`" }, { "textRaw": "`flag` {String} default = `'w'` ", "name": "flag", "type": "String", "desc": "default = `'w'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string or a buffer.\n\n

\n

The encoding option is ignored if data is a buffer. It defaults\nto 'utf8'.\n\n

\n

Example:\n\n

\n
fs.writeFile('message.txt', 'Hello Node.js', (err) => {\n  if (err) throw err;\n  console.log('It\\'s saved!');\n});
\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);
\n

Any specified file descriptor has to support writing.\n\n

\n

Note that it is unsafe to use fs.writeFile multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.writeFileSync(file, data[, options])", "type": "method", "name": "writeFileSync", "desc": "

The synchronous version of [fs.writeFile()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.writeSync(fd, buffer, offset, length[, position])", "type": "method", "name": "writeSync", "desc": "

Synchronous versions of [fs.write()][]. Returns the number of bytes written.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true } ] }, { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position", "optional": true } ] } ] }, { "textRaw": "fs.writeSync(fd, data[, position[, encoding]])", "type": "method", "name": "writeSync", "desc": "

Synchronous versions of [fs.write()][]. Returns the number of bytes written.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true } ] } ] } ], "type": "module", "displayName": "fs" }, { "textRaw": "HTTP", "name": "http", "stability": 2, "stabilityText": "Stable", "desc": "

To use the HTTP server and client one must require('http').\n\n

\n

The HTTP interfaces in Node.js are designed to support many features\nof the protocol which have been traditionally difficult to use.\nIn particular, large, possibly chunk-encoded, messages. The interface is\ncareful to never buffer entire requests or responses--the\nuser is able to stream data.\n\n

\n

HTTP message headers are represented by an object like this:\n\n

\n
{ 'content-length': '123',\n  'content-type': 'text/plain',\n  'connection': 'keep-alive',\n  'host': 'mysite.com',\n  'accept': '*/*' }
\n

Keys are lowercased. Values are not modified.\n\n

\n

In order to support the full spectrum of possible HTTP applications, Node.js's\nHTTP API is very low-level. It deals with stream handling and message\nparsing only. It parses a message into headers and body but it does not\nparse the actual headers or the body.\n\n

\n

See [message.headers][] for details on how duplicate headers are handled.\n\n

\n

The raw headers as they were received are retained in the rawHeaders\nproperty, which is an array of [key, value, key2, value2, ...]. For\nexample, the previous message header object might have a rawHeaders\nlist like the following:\n\n

\n
[ 'ConTent-Length', '123456',\n  'content-LENGTH', '123',\n  'content-type', 'text/plain',\n  'CONNECTION', 'keep-alive',\n  'Host', 'mysite.com',\n  'accepT', '*/*' ]
\n", "classes": [ { "textRaw": "Class: http.Agent", "type": "class", "name": "http.Agent", "desc": "

The HTTP Agent is used for pooling sockets used in HTTP client\nrequests.\n\n

\n

The HTTP Agent also defaults client requests to using\nConnection:keep-alive. If no pending HTTP requests are waiting on a\nsocket to become free the socket is closed. This means that Node.js's\npool has the benefit of keep-alive when under load but still does not\nrequire developers to manually close the HTTP clients using\nKeepAlive.\n\n

\n

If you opt into using HTTP KeepAlive, you can create an Agent object\nwith that flag set to true. (See the [constructor options][] below.)\nThen, the Agent will keep unused sockets in a pool for later use. They\nwill be explicitly marked so as to not keep the Node.js process running.\nHowever, it is still a good idea to explicitly [destroy()][] KeepAlive\nagents when they are no longer in use, so that the Sockets will be shut\ndown.\n\n

\n

Sockets are removed from the agent's pool when the socket emits either\na 'close' event or a special 'agentRemove' event. This means that if\nyou intend to keep one HTTP request open for a long time and don't\nwant it to stay in the pool you can do something along the lines of:\n\n

\n
http.get(options, (res) => {\n  // Do stuff\n}).on('socket', (socket) => {\n  socket.emit('agentRemove');\n});
\n

Alternatively, you could just opt out of pooling entirely using\nagent:false:\n\n

\n
http.get({\n  hostname: 'localhost',\n  port: 80,\n  path: '/',\n  agent: false  // create a new agent just for this one request\n}, (res) => {\n  // Do stuff with response\n})
\n", "methods": [ { "textRaw": "agent.destroy()", "type": "method", "name": "destroy", "desc": "

Destroy any sockets that are currently in use by the agent.\n\n

\n

It is usually not necessary to do this. However, if you are using an\nagent with KeepAlive enabled, then it is best to explicitly shut down\nthe agent when you know that it will no longer be used. Otherwise,\nsockets may hang open for quite a long time before the server\nterminates them.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "agent.getName(options)", "type": "method", "name": "getName", "desc": "

Get a unique name for a set of request options, to determine whether a\nconnection can be reused. In the http agent, this returns\nhost:port:localAddress. In the https agent, the name includes the\nCA, cert, ciphers, and other HTTPS/TLS-specific options that determine\nsocket reusability.\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] } ], "properties": [ { "textRaw": "agent.freeSockets", "name": "freeSockets", "desc": "

An object which contains arrays of sockets currently awaiting use by\nthe Agent when HTTP KeepAlive is used. Do not modify.\n\n

\n" }, { "textRaw": "agent.maxFreeSockets", "name": "maxFreeSockets", "desc": "

By default set to 256. For Agents supporting HTTP KeepAlive, this\nsets the maximum number of sockets that will be left open in the free\nstate.\n\n

\n" }, { "textRaw": "agent.maxSockets", "name": "maxSockets", "desc": "

By default set to Infinity. Determines how many concurrent sockets the agent\ncan have open per origin. Origin is either a 'host:port' or\n'host:port:localAddress' combination.\n\n

\n" }, { "textRaw": "agent.requests", "name": "requests", "desc": "

An object which contains queues of requests that have not yet been assigned to\nsockets. Do not modify.\n\n

\n" }, { "textRaw": "agent.sockets", "name": "sockets", "desc": "

An object which contains arrays of sockets currently in use by the\nAgent. Do not modify.\n\n

\n" } ], "signatures": [ { "params": [ { "textRaw": "`options` {Object} Set of configurable options to set on the agent. Can have the following fields: ", "options": [ { "textRaw": "`keepAlive` {Boolean} Keep sockets around in a pool to be used by other requests in the future. Default = `false` ", "name": "keepAlive", "type": "Boolean", "desc": "Keep sockets around in a pool to be used by other requests in the future. Default = `false`" }, { "textRaw": "`keepAliveMsecs` {Integer} When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = `1000`. Only relevant if `keepAlive` is set to `true`. ", "name": "keepAliveMsecs", "type": "Integer", "desc": "When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = `1000`. Only relevant if `keepAlive` is set to `true`." }, { "textRaw": "`maxSockets` {Number} Maximum number of sockets to allow per host. Default = `Infinity`. ", "name": "maxSockets", "type": "Number", "desc": "Maximum number of sockets to allow per host. Default = `Infinity`." }, { "textRaw": "`maxFreeSockets` {Number} Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`. Default = `256`. ", "name": "maxFreeSockets", "type": "Number", "desc": "Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`. Default = `256`." } ], "name": "options", "type": "Object", "desc": "Set of configurable options to set on the agent. Can have the following fields:", "optional": true } ], "desc": "

The default [http.globalAgent][] that is used by [http.request()][] has all\nof these values set to their respective defaults.\n\n

\n

To configure any of them, you must create your own [http.Agent][] object.\n\n

\n
const http = require('http');\nvar keepAliveAgent = new http.Agent({ keepAlive: true });\noptions.agent = keepAliveAgent;\nhttp.request(options, onResponseCallback);
\n" }, { "params": [ { "name": "options", "optional": true } ], "desc": "

The default [http.globalAgent][] that is used by [http.request()][] has all\nof these values set to their respective defaults.\n\n

\n

To configure any of them, you must create your own [http.Agent][] object.\n\n

\n
const http = require('http');\nvar keepAliveAgent = new http.Agent({ keepAlive: true });\noptions.agent = keepAliveAgent;\nhttp.request(options, onResponseCallback);
\n" } ] }, { "textRaw": "Class: http.ClientRequest", "type": "class", "name": "http.ClientRequest", "desc": "

This object is created internally and returned from [http.request()][]. It\nrepresents an in-progress request whose header has already been queued. The\nheader is still mutable using the setHeader(name, value), getHeader(name),\nremoveHeader(name) API. The actual header will be sent along with the first\ndata chunk or when closing the connection.\n\n

\n

To get the response, add a listener for 'response' to the request object.\n'response' will be emitted from the request object when the response\nheaders have been received. The 'response' event is executed with one\nargument which is an instance of [http.IncomingMessage][].\n\n

\n

During the 'response' event, one can add listeners to the\nresponse object; particularly to listen for the 'data' event.\n\n

\n

If no 'response' handler is added, then the response will be\nentirely discarded. However, if you add a 'response' event handler,\nthen you must consume the data from the response object, either by\ncalling response.read() whenever there is a 'readable' event, or\nby adding a 'data' handler, or by calling the .resume() method.\nUntil the data is consumed, the 'end' event will not fire. Also, until\nthe data is read it will consume memory that can eventually lead to a\n'process out of memory' error.\n\n

\n

Note: Node.js does not check whether Content-Length and the length of the body\nwhich has been transmitted are equal or not.\n\n

\n

The request implements the [Writable Stream][] interface. This is an\n[EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'abort'", "type": "event", "name": "abort", "desc": "

function () { }\n\n

\n

Emitted when the request has been aborted by the client. This event is only\nemitted on the first call to abort().\n\n

\n", "params": [] }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

function (response, socket, head) { }\n\n

\n

Emitted each time a server responds to a request with a CONNECT method. If this\nevent isn't being listened for, clients receiving a CONNECT method will have\ntheir connections closed.\n\n

\n

A client server pair that show you how to listen for the 'connect' event.\n\n

\n
const http = require('http');\nconst net = require('net');\nconst url = require('url');\n\n// Create an HTTP tunneling proxy\nvar proxy = http.createServer( (req, res) => {\n  res.writeHead(200, {'Content-Type': 'text/plain'});\n  res.end('okay');\n});\nproxy.on('connect', (req, cltSocket, head) => {\n  // connect to an origin server\n  var srvUrl = url.parse(`http://${req.url}`);\n  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {\n    cltSocket.write('HTTP/1.1 200 Connection Established\\r\\n' +\n                    'Proxy-agent: Node.js-Proxy\\r\\n' +\n                    '\\r\\n');\n    srvSocket.write(head);\n    srvSocket.pipe(cltSocket);\n    cltSocket.pipe(srvSocket);\n  });\n});\n\n// now that proxy is running\nproxy.listen(1337, '127.0.0.1', () => {\n\n  // make a request to a tunneling proxy\n  var options = {\n    port: 1337,\n    hostname: '127.0.0.1',\n    method: 'CONNECT',\n    path: 'www.google.com:80'\n  };\n\n  var req = http.request(options);\n  req.end();\n\n  req.on('connect', (res, socket, head) => {\n    console.log('got connected!');\n\n    // make a request over an HTTP tunnel\n    socket.write('GET / HTTP/1.1\\r\\n' +\n                 'Host: www.google.com:80\\r\\n' +\n                 'Connection: close\\r\\n' +\n                 '\\r\\n');\n    socket.on('data', (chunk) => {\n      console.log(chunk.toString());\n    });\n    socket.on('end', () => {\n      proxy.close();\n    });\n  });\n});
\n", "params": [] }, { "textRaw": "Event: 'continue'", "type": "event", "name": "continue", "desc": "

function () { }\n\n

\n

Emitted when the server sends a '100 Continue' HTTP response, usually because\nthe request contained 'Expect: 100-continue'. This is an instruction that\nthe client should send the request body.\n\n

\n", "params": [] }, { "textRaw": "Event: 'response'", "type": "event", "name": "response", "desc": "

function (response) { }\n\n

\n

Emitted when a response is received to this request. This event is emitted only\nonce. The response argument will be an instance of [http.IncomingMessage][].\n\n

\n

Options:\n\n

\n
    \n
  • host: A domain name or IP address of the server to issue the request to.
  • \n
  • port: Port of remote server.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath)
  • \n
\n", "params": [] }, { "textRaw": "Event: 'socket'", "type": "event", "name": "socket", "desc": "

function (socket) { }\n\n

\n

Emitted after a socket is assigned to this request.\n\n

\n", "params": [] }, { "textRaw": "Event: 'upgrade'", "type": "event", "name": "upgrade", "desc": "

function (response, socket, head) { }\n\n

\n

Emitted each time a server responds to a request with an upgrade. If this\nevent isn't being listened for, clients receiving an upgrade header will have\ntheir connections closed.\n\n

\n

A client server pair that show you how to listen for the 'upgrade' event.\n\n

\n
const http = require('http');\n\n// Create an HTTP server\nvar srv = http.createServer( (req, res) => {\n  res.writeHead(200, {'Content-Type': 'text/plain'});\n  res.end('okay');\n});\nsrv.on('upgrade', (req, socket, head) => {\n  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\\r\\n' +\n               'Upgrade: WebSocket\\r\\n' +\n               'Connection: Upgrade\\r\\n' +\n               '\\r\\n');\n\n  socket.pipe(socket); // echo back\n});\n\n// now that server is running\nsrv.listen(1337, '127.0.0.1', () => {\n\n  // make a request\n  var options = {\n    port: 1337,\n    hostname: '127.0.0.1',\n    headers: {\n      'Connection': 'Upgrade',\n      'Upgrade': 'websocket'\n    }\n  };\n\n  var req = http.request(options);\n  req.end();\n\n  req.on('upgrade', (res, socket, upgradeHead) => {\n    console.log('got upgraded!');\n    socket.end();\n    process.exit(0);\n  });\n});
\n", "params": [] } ], "methods": [ { "textRaw": "request.abort()", "type": "method", "name": "abort", "desc": "

Marks the request as aborting. Calling this will cause remaining data\nin the response to be dropped and the socket to be destroyed.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "request.end([data][, encoding][, callback])", "type": "method", "name": "end", "desc": "

Finishes sending the request. If any parts of the body are\nunsent, it will flush them to the stream. If the request is\nchunked, this will send the terminating '0\\r\\n\\r\\n'.\n\n

\n

If data is specified, it is equivalent to calling\n[response.write(data, encoding)][] followed by request.end(callback).\n\n

\n

If callback is specified, it will be called when the request stream\nis finished.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "request.flushHeaders()", "type": "method", "name": "flushHeaders", "desc": "

Flush the request headers.\n\n

\n

For efficiency reasons, Node.js normally buffers the request headers until you\ncall request.end() or write the first chunk of request data. It then tries\nhard to pack the request headers and data into a single TCP packet.\n\n

\n

That's usually what you want (it saves a TCP round-trip) but not when the first\ndata isn't sent until possibly much later. request.flushHeaders() lets you bypass\nthe optimization and kickstart the request.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "request.setNoDelay([noDelay])", "type": "method", "name": "setNoDelay", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setNoDelay()][] will be called.\n\n

\n", "signatures": [ { "params": [ { "name": "noDelay", "optional": true } ] } ] }, { "textRaw": "request.setSocketKeepAlive([enable][, initialDelay])", "type": "method", "name": "setSocketKeepAlive", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setKeepAlive()][] will be called.\n\n

\n", "signatures": [ { "params": [ { "name": "enable", "optional": true }, { "name": "initialDelay", "optional": true } ] } ] }, { "textRaw": "request.setTimeout(timeout[, callback])", "type": "method", "name": "setTimeout", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setTimeout()][] will be called.\n\n

\n
    \n
  • timeout {Number} Milliseconds before a request is considered to be timed out.
  • \n
  • callback {Function} Optional function to be called when a timeout occurs. Same as binding to the timeout event.
  • \n
\n", "signatures": [ { "params": [ { "name": "timeout" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "request.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "desc": "

Sends a chunk of the body. By calling this method\nmany times, the user can stream a request body to a\nserver--in that case it is suggested to use the\n['Transfer-Encoding', 'chunked'] header line when\ncreating the request.\n\n

\n

The chunk argument should be a [Buffer][] or a string.\n\n

\n

The encoding argument is optional and only applies when chunk is a string.\nDefaults to 'utf8'.\n\n

\n

The callback argument is optional and will be called when this chunk of data\nis flushed.\n\n

\n

Returns request.\n\n

\n", "signatures": [ { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] } ] }, { "textRaw": "Class: http.Server", "type": "class", "name": "http.Server", "desc": "

This is an [EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'checkContinue'", "type": "event", "name": "checkContinue", "desc": "

function (request, response) { }\n\n

\n

Emitted each time a request with an http Expect: 100-continue is received.\nIf this event isn't listened for, the server will automatically respond\nwith a 100 Continue as appropriate.\n\n

\n

Handling this event involves calling [response.writeContinue()][] if the client\nshould continue to send the request body, or generating an appropriate HTTP\nresponse (e.g., 400 Bad Request) if the client should not continue to send the\nrequest body.\n\n

\n

Note that when this event is emitted and handled, the 'request' event will\nnot be emitted.\n\n

\n", "params": [] }, { "textRaw": "Event: 'clientError'", "type": "event", "name": "clientError", "desc": "

function (exception, socket) { }\n\n

\n

If a client connection emits an 'error' event, it will be forwarded here.\n\n

\n

socket is the [net.Socket][] object that the error originated from.\n\n

\n", "params": [] }, { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Emitted when the server closes.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

function (request, socket, head) { }\n\n

\n

Emitted each time a client requests a http CONNECT method. If this event isn't\nlistened for, then clients requesting a CONNECT method will have their\nconnections closed.\n\n

\n
    \n
  • request is the arguments for the http request, as it is in the request\nevent.
  • \n
  • socket is the network socket between the server and client.
  • \n
  • head is an instance of Buffer, the first packet of the tunneling stream,\nthis may be empty.
  • \n
\n

After this event is emitted, the request's socket will not have a 'data'\nevent listener, meaning you will need to bind to it in order to handle data\nsent to the server on that socket.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connection'", "type": "event", "name": "connection", "desc": "

function (socket) { }\n\n

\n

When a new TCP stream is established. socket is an object of type\n[net.Socket][]. Usually users will not want to access this event. In\nparticular, the socket will not emit 'readable' events because of how\nthe protocol parser attaches to the socket. The socket can also be\naccessed at request.connection.\n\n

\n", "params": [] }, { "textRaw": "Event: 'request'", "type": "event", "name": "request", "desc": "

function (request, response) { }\n\n

\n

Emitted each time there is a request. Note that there may be multiple requests\nper connection (in the case of keep-alive connections).\n request is an instance of [http.IncomingMessage][] and response is\nan instance of [http.ServerResponse][].\n\n

\n", "params": [] }, { "textRaw": "Event: 'upgrade'", "type": "event", "name": "upgrade", "desc": "

function (request, socket, head) { }\n\n

\n

Emitted each time a client requests a http upgrade. If this event isn't\nlistened for, then clients requesting an upgrade will have their connections\nclosed.\n\n

\n
    \n
  • request is the arguments for the http request, as it is in the request\nevent.
  • \n
  • socket is the network socket between the server and client.
  • \n
  • head is an instance of Buffer, the first packet of the upgraded stream,\nthis may be empty.
  • \n
\n

After this event is emitted, the request's socket will not have a 'data'\nevent listener, meaning you will need to bind to it in order to handle data\nsent to the server on that socket.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections. See [net.Server.close()][].\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(handle[, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`handle` {Object} ", "name": "handle", "type": "Object" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "handle" }, { "name": "callback", "optional": true } ] } ], "desc": "

The handle object can be set to either a server or socket (anything\nwith an underlying _handle member), or a {fd: <n>} object.\n\n

\n

This will cause the server to accept connections on the specified\nhandle, but it is presumed that the file descriptor or handle has\nalready been bound to a port or domain socket.\n\n

\n

Listening on a file descriptor is not supported on Windows.\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen()][].\n\n

\n

Returns server.\n\n

\n" }, { "textRaw": "server.listen(path[, callback])", "type": "method", "name": "listen", "desc": "

Start a UNIX socket server listening for connections on the given path.\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen(path)][].\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(port[, hostname][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

To listen to a unix socket, supply a filename instead of port and hostname.\n\n

\n

Backlog is the maximum length of the queue of pending connections.\nThe actual length will be determined by your OS through sysctl settings such as\ntcp_max_syn_backlog and somaxconn on linux. The default value of this\nparameter is 511 (not 512).\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen(port)][].\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Sets the timeout value for sockets, and emits a 'timeout' event on\nthe Server object, passing the socket as an argument, if a timeout\noccurs.\n\n

\n

If there is a 'timeout' event listener on the Server object, then it\nwill be called with the timed-out socket as an argument.\n\n

\n

By default, the Server's timeout value is 2 minutes, and sockets are\ndestroyed automatically if they time out. However, if you assign a\ncallback to the Server's 'timeout' event, then you are responsible\nfor handling socket timeouts.\n\n

\n

Returns server.\n\n

\n" } ], "properties": [ { "textRaw": "server.maxHeadersCount", "name": "maxHeadersCount", "desc": "

Limits maximum incoming headers count, equal to 1000 by default. If set to 0 -\nno limit will be applied.\n\n

\n" }, { "textRaw": "`timeout` {Number} Default = 120000 (2 minutes) ", "name": "timeout", "desc": "

The number of milliseconds of inactivity before a socket is presumed\nto have timed out.\n\n

\n

Note that the socket timeout logic is set up on connection, so\nchanging this value only affects new connections to the server, not\nany existing connections.\n\n

\n

Set to 0 to disable any kind of automatic timeout behavior on incoming\nconnections.\n\n

\n", "shortDesc": "Default = 120000 (2 minutes)" } ] }, { "textRaw": "Class: http.ServerResponse", "type": "class", "name": "http.ServerResponse", "desc": "

This object is created internally by a HTTP server--not by the user. It is\npassed as the second parameter to the 'request' event.\n\n

\n

The response implements the [Writable Stream][] interface. This is an\n[EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Indicates that the underlying connection was terminated before\n[response.end()][] was called or able to flush.\n\n

\n", "params": [] }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

function () { }\n\n

\n

Emitted when the response has been sent. More specifically, this event is\nemitted when the last segment of the response headers and body have been\nhanded off to the operating system for transmission over the network. It\ndoes not imply that the client has received anything yet.\n\n

\n

After this event, no more events will be emitted on the response object.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "response.addTrailers(headers)", "type": "method", "name": "addTrailers", "desc": "

This method adds HTTP trailing headers (a header but at the end of the\nmessage) to the response.\n\n

\n

Trailers will only be emitted if chunked encoding is used for the\nresponse; if it is not (e.g., if the request was HTTP/1.0), they will\nbe silently discarded.\n\n

\n

Note that HTTP requires the Trailer header to be sent if you intend to\nemit trailers, with a list of the header fields in its value. E.g.,\n\n

\n
response.writeHead(200, { 'Content-Type': 'text/plain',\n                          'Trailer': 'Content-MD5' });\nresponse.write(fileData);\nresponse.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});\nresponse.end();
\n

Attempting to set a trailer field name that contains invalid characters will\nresult in a [TypeError][] being thrown.\n\n

\n", "signatures": [ { "params": [ { "name": "headers" } ] } ] }, { "textRaw": "response.end([data][, encoding][, callback])", "type": "method", "name": "end", "desc": "

This method signals to the server that all of the response headers and body\nhave been sent; that server should consider this message complete.\nThe method, response.end(), MUST be called on each response.\n\n

\n

If data is specified, it is equivalent to calling\n[response.write(data, encoding)][] followed by response.end(callback).\n\n

\n

If callback is specified, it will be called when the response stream\nis finished.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "response.getHeader(name)", "type": "method", "name": "getHeader", "desc": "

Reads out a header that's already been queued but not sent to the client. Note\nthat the name is case insensitive. This can only be called before headers get\nimplicitly flushed.\n\n

\n

Example:\n\n

\n
var contentType = response.getHeader('content-type');
\n", "signatures": [ { "params": [ { "name": "name" } ] } ] }, { "textRaw": "response.removeHeader(name)", "type": "method", "name": "removeHeader", "desc": "

Removes a header that's queued for implicit sending.\n\n

\n

Example:\n\n

\n
response.removeHeader('Content-Encoding');
\n", "signatures": [ { "params": [ { "name": "name" } ] } ] }, { "textRaw": "response.setHeader(name, value)", "type": "method", "name": "setHeader", "desc": "

Sets a single header value for implicit headers. If this header already exists\nin the to-be-sent headers, its value will be replaced. Use an array of strings\nhere if you need to send multiple headers with the same name.\n\n

\n

Example:\n\n

\n
response.setHeader('Content-Type', 'text/html');
\n

or\n\n

\n
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
\n

Attempting to set a header field name that contains invalid characters will\nresult in a [TypeError][] being thrown.\n\n

\n", "signatures": [ { "params": [ { "name": "name" }, { "name": "value" } ] } ] }, { "textRaw": "response.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Sets the Socket's timeout value to msecs. If a callback is\nprovided, then it is added as a listener on the 'timeout' event on\nthe response object.\n\n

\n

If no 'timeout' listener is added to the request, the response, or\nthe server, then sockets are destroyed when they time out. If you\nassign a handler on the request, the response, or the server's\n'timeout' events, then it is your responsibility to handle timed out\nsockets.\n\n

\n

Returns response.\n\n

\n" }, { "textRaw": "response.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "desc": "

If this method is called and [response.writeHead()][] has not been called,\nit will switch to implicit header mode and flush the implicit headers.\n\n

\n

This sends a chunk of the response body. This method may\nbe called multiple times to provide successive parts of the body.\n\n

\n

chunk can be a string or a buffer. If chunk is a string,\nthe second parameter specifies how to encode it into a byte stream.\nBy default the encoding is 'utf8'. The last parameter callback\nwill be called when this chunk of data is flushed.\n\n

\n

Note: This is the raw HTTP body and has nothing to do with\nhigher-level multi-part body encodings that may be used.\n\n

\n

The first time [response.write()][] is called, it will send the buffered\nheader information and the first body to the client. The second time\n[response.write()][] is called, Node.js assumes you're going to be streaming\ndata, and sends that separately. That is, the response is buffered up to the\nfirst chunk of body.\n\n

\n

Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n'drain' will be emitted when the buffer is free again.\n\n

\n", "signatures": [ { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "response.writeContinue()", "type": "method", "name": "writeContinue", "desc": "

Sends a HTTP/1.1 100 Continue message to the client, indicating that\nthe request body should be sent. See the ['checkContinue'][] event on Server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "response.writeHead(statusCode[, statusMessage][, headers])", "type": "method", "name": "writeHead", "desc": "

Sends a response header to the request. The status code is a 3-digit HTTP\nstatus code, like 404. The last argument, headers, are the response headers.\nOptionally one can give a human-readable statusMessage as the second\nargument.\n\n

\n

Example:\n\n

\n
var body = 'hello world';\nresponse.writeHead(200, {\n  'Content-Length': body.length,\n  'Content-Type': 'text/plain' });
\n

This method must only be called once on a message and it must\nbe called before [response.end()][] is called.\n\n

\n

If you call [response.write()][] or [response.end()][] before calling this, the\nimplicit/mutable headers will be calculated and call this function for you.\n\n

\n

Note that Content-Length is given in bytes not characters. The above example\nworks because the string 'hello world' contains only single byte characters.\nIf the body contains higher coded characters then Buffer.byteLength()\nshould be used to determine the number of bytes in a given encoding.\nAnd Node.js does not check whether Content-Length and the length of the body\nwhich has been transmitted are equal or not.\n\n

\n", "signatures": [ { "params": [ { "name": "statusCode" }, { "name": "statusMessage", "optional": true }, { "name": "headers", "optional": true } ] } ] } ], "properties": [ { "textRaw": "response.finished", "name": "finished", "desc": "

Boolean value that indicates whether the response has completed. Starts\nas false. After [response.end()][] executes, the value will be true.\n\n

\n" }, { "textRaw": "response.headersSent", "name": "headersSent", "desc": "

Boolean (read-only). True if headers were sent, false otherwise.\n\n

\n" }, { "textRaw": "response.sendDate", "name": "sendDate", "desc": "

When true, the Date header will be automatically generated and sent in\nthe response if it is not already present in the headers. Defaults to true.\n\n

\n

This should only be disabled for testing; HTTP requires the Date header\nin responses.\n\n

\n" }, { "textRaw": "response.statusCode", "name": "statusCode", "desc": "

When using implicit headers (not calling [response.writeHead()][] explicitly),\nthis property controls the status code that will be sent to the client when\nthe headers get flushed.\n\n

\n

Example:\n\n

\n
response.statusCode = 404;
\n

After response header was sent to the client, this property indicates the\nstatus code which was sent out.\n\n

\n" }, { "textRaw": "response.statusMessage", "name": "statusMessage", "desc": "

When using implicit headers (not calling [response.writeHead()][] explicitly), this property\ncontrols the status message that will be sent to the client when the headers get\nflushed. If this is left as undefined then the standard message for the status\ncode will be used.\n\n

\n

Example:\n\n

\n
response.statusMessage = 'Not found';
\n

After response header was sent to the client, this property indicates the\nstatus message which was sent out.\n\n

\n" } ] }, { "textRaw": "Class: http.IncomingMessage", "type": "class", "name": "http.IncomingMessage", "desc": "

An IncomingMessage object is created by [http.Server][] or\n[http.ClientRequest][] and passed as the first argument to the 'request'\nand 'response' event respectively. It may be used to access response status,\nheaders and data.\n\n

\n

It implements the [Readable Stream][] interface, as well as the\nfollowing additional events, methods, and properties.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Indicates that the underlying connection was closed.\nJust like 'end', this event occurs only once per response.\n\n

\n", "params": [] } ], "properties": [ { "textRaw": "message.headers", "name": "headers", "desc": "

The request/response headers object.\n\n

\n

Key-value pairs of header names and values. Header names are lower-cased.\nExample:\n\n

\n
// Prints something like:\n//\n// { 'user-agent': 'curl/7.22.0',\n//   host: '127.0.0.1:8000',\n//   accept: '*/*' }\nconsole.log(request.headers);
\n

Duplicates in raw headers are handled in the following ways, depending on the\nheader name:\n\n

\n
    \n
  • Duplicates of age, authorization, content-length, content-type,\netag, expires, from, host, if-modified-since, if-unmodified-since,\nlast-modified, location, max-forwards, proxy-authorization, referer,\nretry-after, or user-agent are discarded.
  • \n
  • set-cookie is always an array. Duplicates are added to the array.
  • \n
  • For all other headers, the values are joined together with ', '.
  • \n
\n" }, { "textRaw": "message.httpVersion", "name": "httpVersion", "desc": "

In case of server request, the HTTP version sent by the client. In the case of\nclient response, the HTTP version of the connected-to server.\nProbably either '1.1' or '1.0'.\n\n

\n

Also response.httpVersionMajor is the first integer and\nresponse.httpVersionMinor is the second.\n\n

\n" }, { "textRaw": "message.method", "name": "method", "desc": "

Only valid for request obtained from [http.Server][].\n\n

\n

The request method as a string. Read only. Example:\n'GET', 'DELETE'.\n\n

\n" }, { "textRaw": "message.rawHeaders", "name": "rawHeaders", "desc": "

The raw request/response headers list exactly as they were received.\n\n

\n

Note that the keys and values are in the same list. It is not a\nlist of tuples. So, the even-numbered offsets are key values, and the\nodd-numbered offsets are the associated values.\n\n

\n

Header names are not lowercased, and duplicates are not merged.\n\n

\n
// Prints something like:\n//\n// [ 'user-agent',\n//   'this is invalid because there can be only one',\n//   'User-Agent',\n//   'curl/7.22.0',\n//   'Host',\n//   '127.0.0.1:8000',\n//   'ACCEPT',\n//   '*/*' ]\nconsole.log(request.rawHeaders);
\n" }, { "textRaw": "message.rawTrailers", "name": "rawTrailers", "desc": "

The raw request/response trailer keys and values exactly as they were\nreceived. Only populated at the 'end' event.\n\n

\n" }, { "textRaw": "message.statusCode", "name": "statusCode", "desc": "

Only valid for response obtained from [http.ClientRequest][].\n\n

\n

The 3-digit HTTP response status code. E.G. 404.\n\n

\n" }, { "textRaw": "message.statusMessage", "name": "statusMessage", "desc": "

Only valid for response obtained from [http.ClientRequest][].\n\n

\n" }, { "textRaw": "message.socket", "name": "socket", "desc": "

The [net.Socket][] object associated with the connection.\n\n

\n

With HTTPS support, use [request.socket.getPeerCertificate()][] to obtain the\nclient's authentication details.\n\n

\n

The HTTP response status message (reason phrase). E.G. OK or Internal Server Error.\n\n

\n" }, { "textRaw": "message.trailers", "name": "trailers", "desc": "

The request/response trailers object. Only populated at the 'end' event.\n\n

\n" }, { "textRaw": "message.url", "name": "url", "desc": "

Only valid for request obtained from [http.Server][].\n\n

\n

Request URL string. This contains only the URL that is\npresent in the actual HTTP request. If the request is:\n\n

\n
GET /status?name=ryan HTTP/1.1\\r\\n\nAccept: text/plain\\r\\n\n\\r\\n
\n

Then request.url will be:\n\n

\n
'/status?name=ryan'
\n

If you would like to parse the URL into its parts, you can use\nrequire('url').parse(request.url). Example:\n\n

\n
node> require('url').parse('/status?name=ryan')\n{ href: '/status?name=ryan',\n  search: '?name=ryan',\n  query: 'name=ryan',\n  pathname: '/status' }
\n

If you would like to extract the params from the query string,\nyou can use the require('querystring').parse function, or pass\ntrue as the second argument to require('url').parse. Example:\n\n

\n
node> require('url').parse('/status?name=ryan', true)\n{ href: '/status?name=ryan',\n  search: '?name=ryan',\n  query: { name: 'ryan' },\n  pathname: '/status' }
\n" } ], "methods": [ { "textRaw": "message.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Calls message.connection.setTimeout(msecs, callback).\n\n

\n

Returns message.\n\n

\n" } ] } ], "properties": [ { "textRaw": "`METHODS` {Array} ", "name": "METHODS", "desc": "

A list of the HTTP methods that are supported by the parser.\n\n

\n" }, { "textRaw": "`STATUS_CODES` {Object} ", "name": "STATUS_CODES", "desc": "

A collection of all the standard HTTP response status codes, and the\nshort description of each. For example, http.STATUS_CODES[404] === 'Not\nFound'.\n\n

\n" }, { "textRaw": "http.globalAgent", "name": "globalAgent", "desc": "

Global instance of Agent which is used as the default for all http client\nrequests.\n\n

\n" } ], "methods": [ { "textRaw": "http.createClient([port][, host])", "type": "method", "name": "createClient", "stability": 0, "stabilityText": "Deprecated: Use [`http.request()`][] instead.", "desc": "

Constructs a new HTTP client. port and host refer to the server to be\nconnected to.\n\n

\n", "signatures": [ { "params": [ { "name": "port", "optional": true }, { "name": "host", "optional": true } ] } ] }, { "textRaw": "http.createServer([requestListener])", "type": "method", "name": "createServer", "desc": "

Returns a new instance of [http.Server][].\n\n

\n

The requestListener is a function which is automatically\nadded to the 'request' event.\n\n

\n", "signatures": [ { "params": [ { "name": "requestListener", "optional": true } ] } ] }, { "textRaw": "http.get(options[, callback])", "type": "method", "name": "get", "desc": "

Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and [http.request()][]\nis that it sets the method to GET and calls req.end() automatically.\n\n

\n

Example:\n\n

\n
http.get('http://www.google.com/index.html', (res) => {\n  console.log(`Got response: ${res.statusCode}`);\n  // consume response body\n  res.resume();\n}).on('error', (e) => {\n  console.log(`Got error: ${e.message}`);\n});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "http.request(options[, callback])", "type": "method", "name": "request", "desc": "

Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

Options:\n\n

\n
    \n
  • protocol: Protocol to use. Defaults to 'http:'.
  • \n
  • host: A domain name or IP address of the server to issue the request to.\nDefaults to 'localhost'.
  • \n
  • hostname: Alias for host. To support [url.parse()][] hostname is\npreferred over host.
  • \n
  • family: IP address family to use when resolving host and hostname.\nValid values are 4 or 6. When unspecified, both IP v4 and v6 will be\nused.
  • \n
  • port: Port of remote server. Defaults to 80.
  • \n
  • localAddress: Local interface to bind for network connections.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • \n
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • \n
  • path: Request path. Defaults to '/'. Should include query string if any.\nE.G. '/index.html?page=12'. An exception is thrown when the request path\ncontains illegal characters. Currently, only spaces are rejected but that\nmay change in the future.
  • \n
  • headers: An object containing request headers.
  • \n
  • auth: Basic authentication i.e. 'user:password' to compute an\nAuthorization header.
  • \n
  • agent: Controls [Agent][] behavior. When an Agent is used request will\ndefault to Connection: keep-alive. Possible values:
      \n
    • undefined (default): use [http.globalAgent][] for this host and port.
    • \n
    • Agent object: explicitly use the passed in Agent.
    • \n
    • false: opts out of connection pooling with an Agent, defaults request to\nConnection: close.
    • \n
    \n
  • \n
\n

The optional callback parameter will be added as a one time listener for\nthe 'response' event.\n\n

\n

http.request() returns an instance of the [http.ClientRequest][]\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.\n\n

\n

Example:\n\n

\n
var postData = querystring.stringify({\n  'msg' : 'Hello World!'\n});\n\nvar options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/x-www-form-urlencoded',\n    'Content-Length': postData.length\n  }\n};\n\nvar req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.')\n  })\n});\n\nreq.on('error', (e) => {\n  console.log(`problem with request: ${e.message}`);\n});\n\n// write data to request body\nreq.write(postData);\nreq.end();
\n

Note that in the example req.end() was called. With http.request() one\nmust always call req.end() to signify that you're done with the request -\neven if there is no data being written to the request body.\n\n

\n

If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.\n\n

\n

There are a few special headers that should be noted.\n\n

\n
    \n
  • Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

    \n
  • \n
  • Sending a 'Content-length' header will disable the default chunked encoding.

    \n
  • \n
  • Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', you should both set a timeout\nand listen for the 'continue' event. See RFC2616 Section 8.2.3 for more\ninformation.

    \n
  • \n
  • Sending an Authorization header will override using the auth option\nto compute basic authentication.

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] } ], "type": "module", "displayName": "HTTP" }, { "textRaw": "HTTPS", "name": "https", "stability": 2, "stabilityText": "Stable", "desc": "

HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a\nseparate module.\n\n

\n", "classes": [ { "textRaw": "Class: https.Agent", "type": "class", "name": "https.Agent", "desc": "

An Agent object for HTTPS similar to [http.Agent][]. See [https.request()][]\nfor more information.\n\n

\n" }, { "textRaw": "Class: https.Server", "type": "class", "name": "https.Server", "desc": "

This class is a subclass of tls.Server and emits events same as\n[http.Server][]. See [http.Server][] for more information.\n\n

\n", "methods": [ { "textRaw": "server.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "desc": "

See [http.Server#setTimeout()][].\n\n

\n", "signatures": [ { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ] } ], "properties": [ { "textRaw": "server.timeout", "name": "timeout", "desc": "

See [http.Server#timeout][].\n\n

\n" } ] } ], "methods": [ { "textRaw": "https.createServer(options[, requestListener])", "type": "method", "name": "createServer", "desc": "

Returns a new HTTPS web server object. The options is similar to\n[tls.createServer()][]. The requestListener is a function which is\nautomatically added to the 'request' event.\n\n

\n

Example:\n\n

\n
// curl -k https://localhost:8000/\nconst https = require('https');\nconst fs = require('fs');\n\nconst options = {\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')\n};\n\nhttps.createServer(options, (req, res) => {\n  res.writeHead(200);\n  res.end('hello world\\n');\n}).listen(8000);
\n

Or\n\n

\n
const https = require('https');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('server.pfx')\n};\n\nhttps.createServer(options, (req, res) => {\n  res.writeHead(200);\n  res.end('hello world\\n');\n}).listen(8000);
\n", "methods": [ { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

See [http.close()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(path[, callback])", "type": "method", "name": "listen", "desc": "

See [http.listen()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(port[, host][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

See [http.listen()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] } ], "signatures": [ { "params": [ { "name": "options" }, { "name": "requestListener", "optional": true } ] } ] }, { "textRaw": "https.get(options, callback)", "type": "method", "name": "get", "desc": "

Like [http.get()][] but for HTTPS.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

Example:\n\n

\n
const https = require('https');\n\nhttps.get('https://encrypted.google.com/', (res) => {\n  console.log('statusCode: ', res.statusCode);\n  console.log('headers: ', res.headers);\n\n  res.on('data', (d) => {\n    process.stdout.write(d);\n  });\n\n}).on('error', (e) => {\n  console.error(e);\n});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] }, { "textRaw": "https.request(options, callback)", "type": "method", "name": "request", "desc": "

Makes a request to a secure web server.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

All options from [http.request()][] are valid.\n\n

\n

Example:\n\n

\n
const https = require('https');\n\nvar options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET'\n};\n\nvar req = https.request(options, (res) => {\n  console.log('statusCode: ', res.statusCode);\n  console.log('headers: ', res.headers);\n\n  res.on('data', (d) => {\n    process.stdout.write(d);\n  });\n});\nreq.end();\n\nreq.on('error', (e) => {\n  console.error(e);\n});
\n

The options argument has the following options\n\n

\n
    \n
  • host: A domain name or IP address of the server to issue the request to.\nDefaults to 'localhost'.
  • \n
  • hostname: Alias for host. To support url.parse() hostname is\npreferred over host.
  • \n
  • family: IP address family to use when resolving host and hostname.\nValid values are 4 or 6. When unspecified, both IP v4 and v6 will be\nused.
  • \n
  • port: Port of remote server. Defaults to 443.
  • \n
  • localAddress: Local interface to bind for network connections.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • \n
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • \n
  • path: Request path. Defaults to '/'. Should include query string if any.\nE.G. '/index.html?page=12'. An exception is thrown when the request path\ncontains illegal characters. Currently, only spaces are rejected but that\nmay change in the future.
  • \n
  • headers: An object containing request headers.
  • \n
  • auth: Basic authentication i.e. 'user:password' to compute an\nAuthorization header.
  • \n
  • agent: Controls [Agent][] behavior. When an Agent is used request will\ndefault to Connection: keep-alive. Possible values:
      \n
    • undefined (default): use [globalAgent][] for this host and port.
    • \n
    • Agent object: explicitly use the passed in Agent.
    • \n
    • false: opts out of connection pooling with an Agent, defaults request to\nConnection: close.
    • \n
    \n
  • \n
\n

The following options from [tls.connect()][] can also be specified. However, a\n[globalAgent][] silently ignores these.\n\n

\n
    \n
  • pfx: Certificate, Private key and CA certificates to use for SSL. Default null.
  • \n
  • key: Private key to use for SSL. Default null.
  • \n
  • passphrase: A string of passphrase for the private key or pfx. Default null.
  • \n
  • cert: Public x509 certificate to use. Default null.
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.
  • \n
  • ciphers: A string describing the ciphers to use or exclude. Consult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for\ndetails on the format.
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails. Verification happens at the connection level, before the HTTP\nrequest is sent. Default true.
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].
  • \n
\n

In order to specify these options, use a custom [Agent][].\n\n

\n

Example:\n\n

\n
var options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET',\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')\n};\noptions.agent = new https.Agent(options);\n\nvar req = https.request(options, (res) => {\n  ...\n}
\n

Alternatively, opt out of connection pooling by not using an Agent.\n\n

\n

Example:\n\n

\n
var options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET',\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),\n  agent: false\n};\n\nvar req = https.request(options, (res) => {\n  ...\n}
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] } ], "properties": [ { "textRaw": "https.globalAgent", "name": "globalAgent", "desc": "

Global instance of [https.Agent][] for all HTTPS client requests.\n\n

\n" } ], "type": "module", "displayName": "HTTPS" }, { "textRaw": "Modules", "name": "module", "stability": 3, "stabilityText": "Locked", "desc": "

Node.js has a simple module loading system. In Node.js, files and modules are\nin one-to-one correspondence. As an example, foo.js loads the module\ncircle.js in the same directory.\n\n

\n

The contents of foo.js:\n\n

\n
const circle = require('./circle.js');\nconsole.log( `The area of a circle of radius 4 is ${circle.area(4)}`);
\n

The contents of circle.js:\n\n

\n
const PI = Math.PI;\n\nexports.area = function (r) {\n  return PI * r * r;\n};\n\nexports.circumference = function (r) {\n  return 2 * PI * r;\n};
\n

The module circle.js has exported the functions area() and\ncircumference(). To add functions and objects to the root of your module,\nyou can add them to the special exports object.\n\n

\n

Variables local to the module will be private, as though the module was wrapped\nin a function. In this example the variable PI is private to circle.js.\n\n

\n

If you want the root of your module's export to be a function (such as a\nconstructor) or if you want to export a complete object in one assignment\ninstead of building it one property at a time, assign it to module.exports\ninstead of exports.\n\n

\n

Below, bar.js makes use of the square module, which exports a constructor:\n\n

\n
const square = require('./square.js');\nvar mySquare = square(2);\nconsole.log(`The area of my square is ${mySquare.area()}`);
\n

The square module is defined in square.js:\n\n

\n
// assigning to exports will not modify module, must use module.exports\nmodule.exports = function(width) {\n  return {\n    area: function() {\n      return width * width;\n    }\n  };\n}
\n

The module system is implemented in the require("module") module.\n\n

\n", "miscs": [ { "textRaw": "Accessing the main module", "name": "Accessing the main module", "type": "misc", "desc": "

When a file is run directly from Node.js, require.main is set to its\nmodule. That means that you can determine whether a file has been run\ndirectly by testing\n\n

\n
require.main === module
\n

For a file foo.js, this will be true if run via node foo.js, but\nfalse if run by require('./foo').\n\n

\n

Because module provides a filename property (normally equivalent to\n__filename), the entry point of the current application can be obtained\nby checking require.main.filename.\n\n

\n" }, { "textRaw": "Addenda: Package Manager Tips", "name": "Addenda: Package Manager Tips", "type": "misc", "desc": "

The semantics of Node.js's require() function were designed to be general\nenough to support a number of reasonable directory structures. Package manager\nprograms such as dpkg, rpm, and npm will hopefully find it possible to\nbuild native packages from Node.js modules without modification.\n\n

\n

Below we give a suggested directory structure that could work:\n\n

\n

Let's say that we wanted to have the folder at\n/usr/lib/node/<some-package>/<some-version> hold the contents of a\nspecific version of a package.\n\n

\n

Packages can depend on one another. In order to install package foo, you\nmay have to install a specific version of package bar. The bar package\nmay itself have dependencies, and in some cases, these dependencies may even\ncollide or form cycles.\n\n

\n

Since Node.js looks up the realpath of any modules it loads (that is,\nresolves symlinks), and then looks for their dependencies in the\nnode_modules folders as described above, this situation is very simple to\nresolve with the following architecture:\n\n

\n
    \n
  • /usr/lib/node/foo/1.2.3/ - Contents of the foo package, version 1.2.3.
  • \n
  • /usr/lib/node/bar/4.3.2/ - Contents of the bar package that foo\ndepends on.
  • \n
  • /usr/lib/node/foo/1.2.3/node_modules/bar - Symbolic link to\n/usr/lib/node/bar/4.3.2/.
  • \n
  • /usr/lib/node/bar/4.3.2/node_modules/* - Symbolic links to the packages\nthat bar depends on.
  • \n
\n

Thus, even if a cycle is encountered, or if there are dependency\nconflicts, every module will be able to get a version of its dependency\nthat it can use.\n\n

\n

When the code in the foo package does require('bar'), it will get the\nversion that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar.\nThen, when the code in the bar package calls require('quux'), it'll get\nthe version that is symlinked into\n/usr/lib/node/bar/4.3.2/node_modules/quux.\n\n

\n

Furthermore, to make the module lookup process even more optimal, rather\nthan putting packages directly in /usr/lib/node, we could put them in\n/usr/lib/node_modules/<name>/<version>. Then Node.js will not bother\nlooking for missing dependencies in /usr/node_modules or /node_modules.\n\n

\n

In order to make modules available to the Node.js REPL, it might be useful to\nalso add the /usr/lib/node_modules folder to the $NODE_PATH environment\nvariable. Since the module lookups using node_modules folders are all\nrelative, and based on the real path of the files making the calls to\nrequire(), the packages themselves can be anywhere.\n\n

\n" }, { "textRaw": "All Together...", "name": "All Together...", "type": "misc", "desc": "

To get the exact filename that will be loaded when require() is called, use\nthe require.resolve() function.\n\n

\n

Putting together all of the above, here is the high-level algorithm\nin pseudocode of what require.resolve does:\n\n

\n
require(X) from module at path Y\n1. If X is a core module,\n   a. return the core module\n   b. STOP\n2. If X begins with './' or '/' or '../'\n   a. LOAD_AS_FILE(Y + X)\n   b. LOAD_AS_DIRECTORY(Y + X)\n3. LOAD_NODE_MODULES(X, dirname(Y))\n4. THROW "not found"\n\nLOAD_AS_FILE(X)\n1. If X is a file, load X as JavaScript text.  STOP\n2. If X.js is a file, load X.js as JavaScript text.  STOP\n3. If X.json is a file, parse X.json to a JavaScript Object.  STOP\n4. If X.node is a file, load X.node as binary addon.  STOP\n\nLOAD_AS_DIRECTORY(X)\n1. If X/package.json is a file,\n   a. Parse X/package.json, and look for "main" field.\n   b. let M = X + (json main field)\n   c. LOAD_AS_FILE(M)\n2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP\n3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP\n4. If X/index.node is a file, load X/index.node as binary addon.  STOP\n\nLOAD_NODE_MODULES(X, START)\n1. let DIRS=NODE_MODULES_PATHS(START)\n2. for each DIR in DIRS:\n   a. LOAD_AS_FILE(DIR/X)\n   b. LOAD_AS_DIRECTORY(DIR/X)\n\nNODE_MODULES_PATHS(START)\n1. let PARTS = path split(START)\n2. let I = count of PARTS - 1\n3. let DIRS = []\n4. while I >= 0,\n   a. if PARTS[I] = "node_modules" CONTINUE\n   c. DIR = path join(PARTS[0 .. I] + "node_modules")\n   b. DIRS = DIRS + DIR\n   c. let I = I - 1\n5. return DIRS
\n" }, { "textRaw": "Caching", "name": "Caching", "type": "misc", "desc": "

Modules are cached after the first time they are loaded. This means\n(among other things) that every call to require('foo') will get\nexactly the same object returned, if it would resolve to the same file.\n\n

\n

Multiple calls to require('foo') may not cause the module code to be\nexecuted multiple times. This is an important feature. With it,\n"partially done" objects can be returned, thus allowing transitive\ndependencies to be loaded even when they would cause cycles.\n\n

\n

If you want to have a module execute code multiple times, then export a\nfunction, and call that function.\n\n

\n", "miscs": [ { "textRaw": "Module Caching Caveats", "name": "Module Caching Caveats", "type": "misc", "desc": "

Modules are cached based on their resolved filename. Since modules may\nresolve to a different filename based on the location of the calling\nmodule (loading from node_modules folders), it is not a guarantee\nthat require('foo') will always return the exact same object, if it\nwould resolve to different files.\n\n

\n" } ] }, { "textRaw": "Core Modules", "name": "Core Modules", "type": "misc", "desc": "

Node.js has several modules compiled into the binary. These modules are\ndescribed in greater detail elsewhere in this documentation.\n\n

\n

The core modules are defined within Node.js's source and are located in the\nlib/ folder.\n\n

\n

Core modules are always preferentially loaded if their identifier is\npassed to require(). For instance, require('http') will always\nreturn the built in HTTP module, even if there is a file by that name.\n\n

\n" }, { "textRaw": "Cycles", "name": "Cycles", "type": "misc", "desc": "

When there are circular require() calls, a module might not have finished\nexecuting when it is returned.\n\n

\n

Consider this situation:\n\n

\n

a.js:\n\n

\n
console.log('a starting');\nexports.done = false;\nconst b = require('./b.js');\nconsole.log('in a, b.done = %j', b.done);\nexports.done = true;\nconsole.log('a done');
\n

b.js:\n\n

\n
console.log('b starting');\nexports.done = false;\nconst a = require('./a.js');\nconsole.log('in b, a.done = %j', a.done);\nexports.done = true;\nconsole.log('b done');
\n

main.js:\n\n

\n
console.log('main starting');\nconst a = require('./a.js');\nconst b = require('./b.js');\nconsole.log('in main, a.done=%j, b.done=%j', a.done, b.done);
\n

When main.js loads a.js, then a.js in turn loads b.js. At that\npoint, b.js tries to load a.js. In order to prevent an infinite\nloop, an unfinished copy of the a.js exports object is returned to the\nb.js module. b.js then finishes loading, and its exports object is\nprovided to the a.js module.\n\n

\n

By the time main.js has loaded both modules, they're both finished.\nThe output of this program would thus be:\n\n

\n
$ node main.js\nmain starting\na starting\nb starting\nin b, a.done = false\nb done\nin a, b.done = true\na done\nin main, a.done=true, b.done=true
\n

If you have cyclic module dependencies in your program, make sure to\nplan accordingly.\n\n

\n" }, { "textRaw": "File Modules", "name": "File Modules", "type": "misc", "desc": "

If the exact filename is not found, then Node.js will attempt to load the\nrequired filename with the added extensions: .js, .json, and finally\n.node.\n\n

\n

.js files are interpreted as JavaScript text files, and .json files are\nparsed as JSON text files. .node files are interpreted as compiled addon\nmodules loaded with dlopen.\n\n

\n

A required module prefixed with '/' is an absolute path to the file. For\nexample, require('/home/marco/foo.js') will load the file at\n/home/marco/foo.js.\n\n

\n

A required module prefixed with './' is relative to the file calling\nrequire(). That is, circle.js must be in the same directory as foo.js for\nrequire('./circle') to find it.\n\n

\n

Without a leading '/', './', or '../' to indicate a file, the module must\neither be a core module or is loaded from a node_modules folder.\n\n

\n

If the given path does not exist, require() will throw an [Error][] with its\ncode property set to 'MODULE_NOT_FOUND'.\n\n

\n" }, { "textRaw": "Folders as Modules", "name": "Folders as Modules", "type": "misc", "desc": "

It is convenient to organize programs and libraries into self-contained\ndirectories, and then provide a single entry point to that library.\nThere are three ways in which a folder may be passed to require() as\nan argument.\n\n

\n

The first is to create a package.json file in the root of the folder,\nwhich specifies a main module. An example package.json file might\nlook like this:\n\n

\n
{ "name" : "some-library",\n  "main" : "./lib/some-library.js" }
\n

If this was in a folder at ./some-library, then\nrequire('./some-library') would attempt to load\n./some-library/lib/some-library.js.\n\n

\n

This is the extent of Node.js's awareness of package.json files.\n\n

\n

If there is no package.json file present in the directory, then Node.js\nwill attempt to load an index.js or index.node file out of that\ndirectory. For example, if there was no package.json file in the above\nexample, then require('./some-library') would attempt to load:\n\n

\n
    \n
  • ./some-library/index.js
  • \n
  • ./some-library/index.node
  • \n
\n" }, { "textRaw": "Loading from `node_modules` Folders", "name": "Loading from `node_modules` Folders", "type": "misc", "desc": "

If the module identifier passed to require() is not a native module,\nand does not begin with '/', '../', or './', then Node.js starts at the\nparent directory of the current module, and adds /node_modules, and\nattempts to load the module from that location. Node will not append\nnode_modules to a path already ending in node_modules.\n\n

\n

If it is not found there, then it moves to the parent directory, and so\non, until the root of the file system is reached.\n\n

\n

For example, if the file at '/home/ry/projects/foo.js' called\nrequire('bar.js'), then Node.js would look in the following locations, in\nthis order:\n\n

\n
    \n
  • /home/ry/projects/node_modules/bar.js
  • \n
  • /home/ry/node_modules/bar.js
  • \n
  • /home/node_modules/bar.js
  • \n
  • /node_modules/bar.js
  • \n
\n

This allows programs to localize their dependencies, so that they do not\nclash.\n\n

\n

You can require specific files or sub modules distributed with a module by\nincluding a path suffix after the module name. For instance\nrequire('example-module/path/to/file') would resolve path/to/file\nrelative to where example-module is located. The suffixed path follows the\nsame module resolution semantics.\n\n

\n" }, { "textRaw": "Loading from the global folders", "name": "Loading from the global folders", "type": "misc", "desc": "

If the NODE_PATH environment variable is set to a colon-delimited list\nof absolute paths, then Node.js will search those paths for modules if they\nare not found elsewhere. (Note: On Windows, NODE_PATH is delimited by\nsemicolons instead of colons.)\n\n

\n

NODE_PATH was originally created to support loading modules from\nvarying paths before the current [module resolution][] algorithm was frozen.\n\n

\n

NODE_PATH is still supported, but is less necessary now that the Node.js\necosystem has settled on a convention for locating dependent modules.\nSometimes deployments that rely on NODE_PATH show surprising behavior\nwhen people are unaware that NODE_PATH must be set. Sometimes a\nmodule's dependencies change, causing a different version (or even a\ndifferent module) to be loaded as the NODE_PATH is searched.\n\n

\n

Additionally, Node.js will search in the following locations:\n\n

\n
    \n
  • 1: $HOME/.node_modules
  • \n
  • 2: $HOME/.node_libraries
  • \n
  • 3: $PREFIX/lib/node
  • \n
\n

Where $HOME is the user's home directory, and $PREFIX is Node.js's\nconfigured node_prefix.\n\n

\n

These are mostly for historic reasons. You are highly encouraged\nto place your dependencies locally in node_modules folders. They\nwill be loaded faster, and more reliably.\n\n

\n" } ], "vars": [ { "textRaw": "The `module` Object", "name": "module", "type": "var", "desc": "

In each module, the module free variable is a reference to the object\nrepresenting the current module. For convenience, module.exports is\nalso accessible via the exports module-global. module isn't actually\na global but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`children` {Array} ", "name": "children", "desc": "

The module objects required by this one.\n\n

\n" }, { "textRaw": "`exports` {Object} ", "name": "exports", "desc": "

The module.exports object is created by the Module system. Sometimes this is\nnot acceptable; many want their module to be an instance of some class. To do\nthis, assign the desired export object to module.exports. Note that assigning\nthe desired object to exports will simply rebind the local exports variable,\nwhich is probably not what you want to do.\n\n

\n

For example suppose we were making a module called a.js\n\n

\n
const EventEmitter = require('events');\n\nmodule.exports = new EventEmitter();\n\n// Do some work, and after some time emit\n// the 'ready' event from the module itself.\nsetTimeout(() => {\n  module.exports.emit('ready');\n}, 1000);
\n

Then in another file we could do\n\n

\n
const a = require('./a');\na.on('ready', () => {\n  console.log('module a is ready');\n});
\n

Note that assignment to module.exports must be done immediately. It cannot be\ndone in any callbacks. This does not work:\n\n

\n

x.js:\n\n

\n
setTimeout(() => {\n  module.exports = { a: 'hello' };\n}, 0);
\n

y.js:\n\n

\n
const x = require('./x');\nconsole.log(x.a);
\n", "modules": [ { "textRaw": "exports alias", "name": "exports_alias", "desc": "

The exports variable that is available within a module starts as a reference\nto module.exports. As with any variable, if you assign a new value to it, it\nis no longer bound to the previous value.\n\n

\n

To illustrate the behavior, imagine this hypothetical implementation of\nrequire():\n\n

\n
function require(...) {\n  // ...\n  function (module, exports) {\n    // Your module code here\n    exports = some_func;        // re-assigns exports, exports is no longer\n                                // a shortcut, and nothing is exported.\n    module.exports = some_func; // makes your module export 0\n  } (module, module.exports);\n  return module;\n}
\n

As a guideline, if the relationship between exports and module.exports\nseems like magic to you, ignore exports and only use module.exports.\n\n

\n", "type": "module", "displayName": "exports alias" } ] }, { "textRaw": "`filename` {String} ", "name": "filename", "desc": "

The fully resolved filename to the module.\n\n

\n" }, { "textRaw": "`id` {String} ", "name": "id", "desc": "

The identifier for the module. Typically this is the fully resolved\nfilename.\n\n

\n" }, { "textRaw": "`loaded` {Boolean} ", "name": "loaded", "desc": "

Whether or not the module is done loading, or is in the process of\nloading.\n\n

\n" }, { "textRaw": "`parent` {Module Object} ", "name": "parent", "desc": "

The module that first required this one.\n\n

\n" } ], "methods": [ { "textRaw": "module.require(id)", "type": "method", "name": "require", "signatures": [ { "return": { "textRaw": "Return: {Object} `module.exports` from the resolved module ", "name": "return", "type": "Object", "desc": "`module.exports` from the resolved module" }, "params": [ { "textRaw": "`id` {String} ", "name": "id", "type": "String" } ] }, { "params": [ { "name": "id" } ] } ], "desc": "

The module.require method provides a way to load a module as if\nrequire() was called from the original module.\n\n

\n

Note that in order to do this, you must get a reference to the module\nobject. Since require() returns the module.exports, and the module is\ntypically only available within a specific module's code, it must be\nexplicitly exported in order to be used.\n\n

\n" } ] } ], "type": "module", "displayName": "module" }, { "textRaw": "net", "name": "net", "stability": 2, "stabilityText": "Stable", "desc": "

The net module provides you with an asynchronous network wrapper. It contains\nfunctions for creating both servers and clients (called streams). You can include\nthis module with require('net');.\n\n

\n", "classes": [ { "textRaw": "Class: net.Server", "type": "class", "name": "net.Server", "desc": "

This class is used to create a TCP or local server.\n\n

\n

net.Server is an [EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the server closes. Note that if connections exist, this\nevent is not emitted until all connections are ended.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connection'", "type": "event", "name": "connection", "params": [], "desc": "

Emitted when a new connection is made. socket is an instance of\nnet.Socket.\n\n

\n" }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs. The ['close'][] event will be called directly\nfollowing this event. See example in discussion of server.listen.\n\n

\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "desc": "

Emitted when the server has been bound after calling server.listen.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the server\nas reported by the operating system.\nUseful to find which port was assigned when giving getting an OS-assigned address.\nReturns an object with three properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n

Example:\n\n

\n
var server = net.createServer((socket) => {\n  socket.end('goodbye\\n');\n});\n\n// grab a random port.\nserver.listen(() => {\n  address = server.address();\n  console.log('opened server on %j', address);\n});
\n

Don't call server.address() until the 'listening' event has been emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections and keeps existing\nconnections. This function is asynchronous, the server is finally\nclosed when all connections are ended and the server emits a ['close'][] event.\nThe optional callback will be called once the 'close' event occurs. Unlike\nthat event, it will be called with an Error as its only argument if the server\nwas not open when it was closed.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.getConnections(callback)", "type": "method", "name": "getConnections", "desc": "

Asynchronously get the number of concurrent connections on the server. Works\nwhen sockets were sent to forks.\n\n

\n

Callback should take two arguments err and count.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" } ] } ] }, { "textRaw": "server.listen(handle[, backlog][, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`handle` {Object} ", "name": "handle", "type": "Object" }, { "textRaw": "`backlog` {Number} ", "name": "backlog", "type": "Number", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "handle" }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

The handle object can be set to either a server or socket (anything\nwith an underlying _handle member), or a {fd: <n>} object.\n\n

\n

This will cause the server to accept connections on the specified\nhandle, but it is presumed that the file descriptor or handle has\nalready been bound to a port or domain socket.\n\n

\n

Listening on a file descriptor is not supported on Windows.\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted.\nThe last parameter callback will be added as a listener for the\n['listening'][] event.\n\n

\n

The parameter backlog behaves the same as in\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][].\n\n

\n" }, { "textRaw": "server.listen(options[, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`options` {Object} - Required. Supports the following properties: ", "options": [ { "textRaw": "`port` {Number} - Optional. ", "name": "port", "type": "Number", "desc": "Optional." }, { "textRaw": "`host` {String} - Optional. ", "name": "host", "type": "String", "desc": "Optional." }, { "textRaw": "`backlog` {Number} - Optional. ", "name": "backlog", "type": "Number", "desc": "Optional." }, { "textRaw": "`path` {String} - Optional. ", "name": "path", "type": "String", "desc": "Optional." }, { "textRaw": "`exclusive` {Boolean} - Optional. ", "name": "exclusive", "type": "Boolean", "desc": "Optional." } ], "name": "options", "type": "Object", "desc": "Required. Supports the following properties:" }, { "textRaw": "`callback` {Function} - Optional. ", "name": "callback", "type": "Function", "desc": "Optional.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

The port, host, and backlog properties of options, as well as the\noptional callback function, behave as they do on a call to\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][]. Alternatively,\nthe path option can be used to specify a UNIX socket.\n\n

\n

If exclusive is false (default), then cluster workers will use the same\nunderlying handle, allowing connection handling duties to be shared. When\nexclusive is true, the handle is not shared, and attempted port sharing\nresults in an error. An example which listens on an exclusive port is\nshown below.\n\n

\n
server.listen({\n  host: 'localhost',\n  port: 80,\n  exclusive: true\n});
\n" }, { "textRaw": "server.listen(path[, backlog][, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`path` {String} ", "name": "path", "type": "String" }, { "textRaw": "`backlog` {Number} ", "name": "backlog", "type": "Number", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Start a local socket server listening for connections on the given path.\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted. The last parameter callback\nwill be added as a listener for the ['listening'][] event.\n\n

\n

On UNIX, the local domain is usually known as the UNIX domain. The path is a\nfilesystem path name. It is subject to the same naming conventions and\npermissions checks as would be done on file creation, will be visible in the\nfilesystem, and will persist until unlinked.\n\n

\n

On Windows, the local domain is implemented using a named pipe. The path must\nrefer to an entry in \\\\?\\pipe\\ or \\\\.\\pipe\\. Any characters are permitted,\nbut the latter may do some processing of pipe names, such as resolving ..\nsequences. Despite appearances, the pipe name space is flat. Pipes will not\npersist, they are removed when the last reference to them is closed. Do not\nforget JavaScript string escaping requires paths to be specified with\ndouble-backslashes, such as:\n\n

\n
net.createServer().listen(\n    path.join('\\\\\\\\?\\\\pipe', process.cwd(), 'myctl'))
\n

The parameter backlog behaves the same as in\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][].\n\n

\n" }, { "textRaw": "server.listen(port[, hostname][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

Backlog is the maximum length of the queue of pending connections.\nThe actual length will be determined by your OS through sysctl settings such as\ntcp_max_syn_backlog and somaxconn on linux. The default value of this\nparameter is 511 (not 512).\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted. The last parameter callback\nwill be added as a listener for the ['listening'][] event.\n\n

\n

One issue some users run into is getting EADDRINUSE errors. This means that\nanother server is already running on the requested port. One way of handling this\nwould be to wait a second and then try again. This can be done with\n\n

\n
server.on('error', (e) => {\n  if (e.code == 'EADDRINUSE') {\n    console.log('Address in use, retrying...');\n    setTimeout(() => {\n      server.close();\n      server.listen(PORT, HOST);\n    }, 1000);\n  }\n});
\n

(Note: All sockets in Node.js set SO_REUSEADDR already)\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.ref()", "type": "method", "name": "ref", "desc": "

Opposite of unref, calling ref on a previously unrefd server will not\nlet the program exit if it's the only server left (the default behavior). If\nthe server is refd calling ref again will have no effect.\n\n

\n

Returns server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.unref()", "type": "method", "name": "unref", "desc": "

Calling unref on a server will allow the program to exit if this is the only\nactive server in the event system. If the server is already unrefd calling\nunref again will have no effect.\n\n

\n

Returns server.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "server.connections", "name": "connections", "stability": 0, "stabilityText": "Deprecated: Use [`server.getConnections`][] instead.", "desc": "

The number of concurrent connections on the server.\n\n

\n

This becomes null when sending a socket to a child with\n[child_process.fork()][]. To poll forks and get current number of active\nconnections use asynchronous server.getConnections instead.\n\n

\n" }, { "textRaw": "server.maxConnections", "name": "maxConnections", "desc": "

Set this property to reject connections when the server's connection count gets\nhigh.\n\n

\n

It is not recommended to use this option once a socket has been sent to a child\nwith [child_process.fork()][].\n\n

\n" } ] }, { "textRaw": "Class: net.Socket", "type": "class", "name": "net.Socket", "desc": "

This object is an abstraction of a TCP or local socket. net.Socket\ninstances implement a duplex Stream interface. They can be created by the\nuser and used as a client (with [connect()][]) or they can be created by Node.js\nand passed to the user through the 'connection' event of a server.\n\n

\n", "methods": [ { "textRaw": "new net.Socket([options])", "type": "method", "name": "Socket", "desc": "

Construct a new socket object.\n\n

\n

options is an object with the following defaults:\n\n

\n
{ fd: null,\n  allowHalfOpen: false,\n  readable: false,\n  writable: false\n}
\n

fd allows you to specify the existing file descriptor of socket.\nSet readable and/or writable to true to allow reads and/or writes on this\nsocket (NOTE: Works only when fd is passed).\nAbout allowHalfOpen, refer to createServer() and 'end' event.\n\n

\n

net.Socket instances are [EventEmitter][] with the following events:\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "socket.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nsocket as reported by the operating system. Returns an object with\nthree properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.connect(options[, connectListener])", "type": "method", "name": "connect", "desc": "

Opens the connection for a given socket.\n\n

\n

For TCP sockets, options argument should be an object which specifies:\n\n

\n
    \n
  • port: Port the client should connect to (Required).

    \n
  • \n
  • host: Host the client should connect to. Defaults to 'localhost'.

    \n
  • \n
  • localAddress: Local interface to bind to for network connections.

    \n
  • \n
  • localPort: Local port to bind to for network connections.

    \n
  • \n
  • family : Version of IP stack. Defaults to 4.

    \n
  • \n
  • lookup : Custom lookup function. Defaults to dns.lookup.

    \n
  • \n
\n

For local domain sockets, options argument should be an object which\nspecifies:\n\n

\n
    \n
  • path: Path the client should connect to (Required).
  • \n
\n

Normally this method is not needed, as net.createConnection opens the\nsocket. Use this only if you are implementing a custom Socket.\n\n

\n

This function is asynchronous. When the ['connect'][] event is emitted the\nsocket is established. If there is a problem connecting, the 'connect' event\nwill not be emitted, the ['error'][] event will be emitted with the exception.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event.\n\n

\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.connect(path[, connectListener])", "type": "method", "name": "connect", "desc": "

As [socket.connect(options\\[, connectListener\\])][],\nwith options either as either {port: port, host: host} or {path: path}.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.connect(port[, host][, connectListener])", "type": "method", "name": "connect", "desc": "

As [socket.connect(options\\[, connectListener\\])][],\nwith options either as either {port: port, host: host} or {path: path}.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.destroy()", "type": "method", "name": "destroy", "desc": "

Ensures that no more I/O activity happens on this socket. Only necessary in\ncase of errors (parse error or so).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.end([data][, encoding])", "type": "method", "name": "end", "desc": "

Half-closes the socket. i.e., it sends a FIN packet. It is possible the\nserver will still send some data.\n\n

\n

If data is specified, it is equivalent to calling\nsocket.write(data, encoding) followed by socket.end().\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "socket.pause()", "type": "method", "name": "pause", "desc": "

Pauses the reading of data. That is, ['data'][] events will not be emitted.\nUseful to throttle back an upload.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.ref()", "type": "method", "name": "ref", "desc": "

Opposite of unref, calling ref on a previously unrefd socket will not\nlet the program exit if it's the only socket left (the default behavior). If\nthe socket is refd calling ref again will have no effect.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.resume()", "type": "method", "name": "resume", "desc": "

Resumes reading after a call to [pause()][].\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.setEncoding([encoding])", "type": "method", "name": "setEncoding", "desc": "

Set the encoding for the socket as a [Readable Stream][]. See\n[stream.setEncoding()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "socket.setKeepAlive([enable][, initialDelay])", "type": "method", "name": "setKeepAlive", "desc": "

Enable/disable keep-alive functionality, and optionally set the initial\ndelay before the first keepalive probe is sent on an idle socket.\nenable defaults to false.\n\n

\n

Set initialDelay (in milliseconds) to set the delay between the last\ndata packet received and the first keepalive probe. Setting 0 for\ninitialDelay will leave the value unchanged from the default\n(or previous) setting. Defaults to 0.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "enable", "optional": true }, { "name": "initialDelay", "optional": true } ] } ] }, { "textRaw": "socket.setNoDelay([noDelay])", "type": "method", "name": "setNoDelay", "desc": "

Disables the Nagle algorithm. By default TCP connections use the Nagle\nalgorithm, they buffer data before sending it off. Setting true for\nnoDelay will immediately fire off data each time socket.write() is called.\nnoDelay defaults to true.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "noDelay", "optional": true } ] } ] }, { "textRaw": "socket.setTimeout(timeout[, callback])", "type": "method", "name": "setTimeout", "desc": "

Sets the socket to timeout after timeout milliseconds of inactivity on\nthe socket. By default net.Socket do not have a timeout.\n\n

\n

When an idle timeout is triggered the socket will receive a ['timeout'][]\nevent but the connection will not be severed. The user must manually [end()][]\nor [destroy()][] the socket.\n\n

\n

If timeout is 0, then the existing idle timeout is disabled.\n\n

\n

The optional callback parameter will be added as a one time listener for the\n['timeout'][] event.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "timeout" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "socket.unref()", "type": "method", "name": "unref", "desc": "

Calling unref on a socket will allow the program to exit if this is the only\nactive socket in the event system. If the socket is already unrefd calling\nunref again will have no effect.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.write(data[, encoding][, callback])", "type": "method", "name": "write", "desc": "

Sends data on the socket. The second parameter specifies the encoding in the\ncase of a string--it defaults to UTF8 encoding.\n\n

\n

Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n['drain'][] will be emitted when the buffer is again free.\n\n

\n

The optional callback parameter will be executed when the data is finally\nwritten out - this may not be immediately.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] } ], "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "params": [], "desc": "

Emitted once the socket is fully closed. The argument had_error is a boolean\nwhich says if the socket was closed due to a transmission error.\n\n

\n" }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

Emitted when a socket connection is successfully established.\nSee [connect()][].\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Emitted when data is received. The argument data will be a Buffer or\nString. Encoding of data is set by socket.setEncoding().\n(See the [Readable Stream][] section for more information.)\n\n

\n

Note that the data will be lost if there is no listener when a Socket\nemits a 'data' event.\n\n

\n" }, { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

Emitted when the write buffer becomes empty. Can be used to throttle uploads.\n\n

\n

See also: the return values of socket.write()\n\n

\n", "params": [] }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

Emitted when the other end of the socket sends a FIN packet.\n\n

\n

By default (allowHalfOpen == false) the socket will destroy its file\ndescriptor once it has written out its pending write queue. However, by\nsetting allowHalfOpen == true the socket will not automatically end()\nits side allowing the user to write arbitrary amounts of data, with the\ncaveat that the user is required to end() their side now.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs. The 'close' event will be called directly\nfollowing this event.\n\n

\n" }, { "textRaw": "Event: 'lookup'", "type": "event", "name": "lookup", "desc": "

Emitted after resolving the hostname but before connecting.\nNot applicable to UNIX sockets.\n\n

\n
    \n
  • err {Error | Null} The error object. See [dns.lookup()][].
  • \n
  • address {String} The IP address.
  • \n
  • family {String | Null} The address type. See [dns.lookup()][].
  • \n
\n", "params": [] }, { "textRaw": "Event: 'timeout'", "type": "event", "name": "timeout", "desc": "

Emitted if the socket times out from inactivity. This is only to notify that\nthe socket has been idle. The user must manually close the connection.\n\n

\n

See also: [socket.setTimeout()][]\n\n

\n", "params": [] } ], "properties": [ { "textRaw": "socket.bufferSize", "name": "bufferSize", "desc": "

net.Socket has the property that socket.write() always works. This is to\nhelp users get up and running quickly. The computer cannot always keep up\nwith the amount of data that is written to a socket - the network connection\nsimply might be too slow. Node.js will internally queue up the data written to a\nsocket and send it out over the wire when it is possible. (Internally it is\npolling on the socket's file descriptor for being writable).\n\n

\n

The consequence of this internal buffering is that memory may grow. This\nproperty shows the number of characters currently buffered to be written.\n(Number of characters is approximately equal to the number of bytes to be\nwritten, but the buffer may contain strings, and the strings are lazily\nencoded, so the exact number of bytes is not known.)\n\n

\n

Users who experience large or growing bufferSize should attempt to\n"throttle" the data flows in their program with [pause()][] and [resume()][].\n\n

\n" }, { "textRaw": "socket.bytesRead", "name": "bytesRead", "desc": "

The amount of received bytes.\n\n

\n" }, { "textRaw": "socket.bytesWritten", "name": "bytesWritten", "desc": "

The amount of bytes sent.\n\n

\n" }, { "textRaw": "socket.localAddress", "name": "localAddress", "desc": "

The string representation of the local IP address the remote client is\nconnecting on. For example, if you are listening on '0.0.0.0' and the\nclient connects on '192.168.1.1', the value would be '192.168.1.1'.\n\n

\n" }, { "textRaw": "socket.localPort", "name": "localPort", "desc": "

The numeric representation of the local port. For example,\n80 or 21.\n\n

\n" }, { "textRaw": "socket.remoteAddress", "name": "remoteAddress", "desc": "

The string representation of the remote IP address. For example,\n'74.125.127.100' or '2001:4860:a005::68'. Value may be undefined if\nthe socket is destroyed (for example, if the client disconnected).\n\n

\n" }, { "textRaw": "socket.remoteFamily", "name": "remoteFamily", "desc": "

The string representation of the remote IP family. 'IPv4' or 'IPv6'.\n\n

\n" }, { "textRaw": "socket.remotePort", "name": "remotePort", "desc": "

The numeric representation of the remote port. For example,\n80 or 21.\n\n

\n" } ] } ], "methods": [ { "textRaw": "net.connect(options[, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects with the supplied options.\n\n

\n

The options are passed to both the [net.Socket][] constructor and the\n[socket.connect][] method.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n

Here is an example of a client of the previously described echo server:\n\n

\n
const net = require('net');\nconst client = net.connect({port: 8124}, () => { //'connect' listener\n  console.log('connected to server!');\n  client.write('world!\\r\\n');\n});\nclient.on('data', (data) => {\n  console.log(data.toString());\n  client.end();\n});\nclient.on('end', () => {\n  console.log('disconnected from server');\n});
\n

To connect on the socket /tmp/echo.sock the second line would just be\nchanged to\n\n

\n
const client = net.connect({path: '/tmp/echo.sock'});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.connect(path[, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new unix [net.Socket][] and automatically\nconnects to the supplied path.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.connect(port[, host][, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects to the supplied port and host.\n\n

\n

If host is omitted, 'localhost' will be assumed.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(options[, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects with the supplied options.\n\n

\n

The options are passed to both the [net.Socket][] constructor and the\n[socket.connect][] method.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n

Here is an example of a client of the previously described echo server:\n\n

\n
const net = require('net');\nconst client = net.connect({port: 8124},\n    () => { //'connect' listener\n  console.log('connected to server!');\n  client.write('world!\\r\\n');\n});\nclient.on('data', (data) => {\n  console.log(data.toString());\n  client.end();\n});\nclient.on('end', () => {\n  console.log('disconnected from server');\n});
\n

To connect on the socket /tmp/echo.sock the second line would just be\nchanged to\n\n

\n
const client = net.connect({path: '/tmp/echo.sock'});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(path[, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new unix [net.Socket][] and automatically\nconnects to the supplied path.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(port[, host][, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects to the supplied port and host.\n\n

\n

If host is omitted, 'localhost' will be assumed.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createServer([options][, connectionListener])", "type": "method", "name": "createServer", "desc": "

Creates a new server. The connectionListener argument is\nautomatically set as a listener for the ['connection'][] event.\n\n

\n

options is an object with the following defaults:\n\n

\n
{\n  allowHalfOpen: false,\n  pauseOnConnect: false\n}
\n

If allowHalfOpen is true, then the socket won't automatically send a FIN\npacket when the other end of the socket sends a FIN packet. The socket becomes\nnon-readable, but still writable. You should call the [end()][] method explicitly.\nSee ['end'][] event for more information.\n\n

\n

If pauseOnConnect is true, then the socket associated with each incoming\nconnection will be paused, and no data will be read from its handle. This allows\nconnections to be passed between processes without any data being read by the\noriginal process. To begin reading data from a paused socket, call [resume()][].\n\n

\n

Here is an example of an echo server which listens for connections\non port 8124:\n\n

\n
const net = require('net');\nconst server = net.createServer((c) => { //'connection' listener\n  console.log('client connected');\n  c.on('end', () => {\n    console.log('client disconnected');\n  });\n  c.write('hello\\r\\n');\n  c.pipe(c);\n});\nserver.listen(8124, () => { //'listening' listener\n  console.log('server bound');\n});
\n

Test this by using telnet:\n\n

\n
telnet localhost 8124
\n

To listen on the socket /tmp/echo.sock the third line from the last would\njust be changed to\n\n

\n
server.listen('/tmp/echo.sock', () => { //'listening' listener
\n

Use nc to connect to a UNIX domain socket server:\n\n

\n
nc -U /tmp/echo.sock
\n", "signatures": [ { "params": [ { "name": "options", "optional": true }, { "name": "connectionListener", "optional": true } ] } ] }, { "textRaw": "net.isIP(input)", "type": "method", "name": "isIP", "desc": "

Tests if input is an IP address. Returns 0 for invalid strings,\nreturns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.\n\n\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] }, { "textRaw": "net.isIPv4(input)", "type": "method", "name": "isIPv4", "desc": "

Returns true if input is a version 4 IP address, otherwise returns false.\n\n\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] }, { "textRaw": "net.isIPv6(input)", "type": "method", "name": "isIPv6", "desc": "

Returns true if input is a version 6 IP address, otherwise returns false.\n\n

\n

[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])]: #net_server_listen_port_hostname_backlog_callback\n[socket.connect(options\\[, connectListener\\])]: #net_socket_connect_options_connectlistener\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] } ], "type": "module", "displayName": "net" }, { "textRaw": "OS", "name": "os", "stability": 2, "stabilityText": "Stable", "desc": "

Provides a few basic operating-system related utility functions.\n\n

\n

Use require('os') to access this module.\n\n

\n", "properties": [ { "textRaw": "os.EOL", "name": "EOL", "desc": "

A constant defining the appropriate End-of-line marker for the operating\nsystem.\n\n

\n" } ], "methods": [ { "textRaw": "os.arch()", "type": "method", "name": "arch", "desc": "

Returns the operating system CPU architecture. Possible values are 'x64',\n'arm' and 'ia32'. Returns the value of process.arch.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.cpus()", "type": "method", "name": "cpus", "desc": "

Returns an array of objects containing information about each CPU/core\ninstalled: model, speed (in MHz), and times (an object containing the number of\nmilliseconds the CPU/core spent in: user, nice, sys, idle, and irq).\n\n

\n

Example inspection of os.cpus:\n\n

\n
[ { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 252020,\n       nice: 0,\n       sys: 30340,\n       idle: 1070356870,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 306960,\n       nice: 0,\n       sys: 26980,\n       idle: 1071569080,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 248450,\n       nice: 0,\n       sys: 21750,\n       idle: 1070919370,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 256880,\n       nice: 0,\n       sys: 19430,\n       idle: 1070905480,\n       irq: 20 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 511580,\n       nice: 20,\n       sys: 40900,\n       idle: 1070842510,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 291660,\n       nice: 0,\n       sys: 34360,\n       idle: 1070888000,\n       irq: 10 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 308260,\n       nice: 0,\n       sys: 55410,\n       idle: 1071129970,\n       irq: 880 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 266450,\n       nice: 1480,\n       sys: 34920,\n       idle: 1072572010,\n       irq: 30 } } ]
\n

Note that since nice values are UNIX centric in Windows the nice values of\nall processors are always 0.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.endianness()", "type": "method", "name": "endianness", "desc": "

Returns the endianness of the CPU. Possible values are 'BE' for big endian\nor 'LE' for little endian.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.freemem()", "type": "method", "name": "freemem", "desc": "

Returns the amount of free system memory in bytes.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.homedir()", "type": "method", "name": "homedir", "desc": "

Returns the home directory of the current user.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.hostname()", "type": "method", "name": "hostname", "desc": "

Returns the hostname of the operating system.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.loadavg()", "type": "method", "name": "loadavg", "desc": "

Returns an array containing the 1, 5, and 15 minute load averages.\n\n

\n

The load average is a measure of system activity, calculated by the operating\nsystem and expressed as a fractional number. As a rule of thumb, the load\naverage should ideally be less than the number of logical CPUs in the system.\n\n

\n

The load average is a very UNIX-y concept; there is no real equivalent on\nWindows platforms. That is why this function always returns [0, 0, 0] on\nWindows.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.networkInterfaces()", "type": "method", "name": "networkInterfaces", "desc": "

Get a list of network interfaces:\n\n

\n
{ lo:\n   [ { address: '127.0.0.1',\n       netmask: '255.0.0.0',\n       family: 'IPv4',\n       mac: '00:00:00:00:00:00',\n       internal: true },\n     { address: '::1',\n       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',\n       family: 'IPv6',\n       mac: '00:00:00:00:00:00',\n       internal: true } ],\n  eth0:\n   [ { address: '192.168.1.108',\n       netmask: '255.255.255.0',\n       family: 'IPv4',\n       mac: '01:02:03:0a:0b:0c',\n       internal: false },\n     { address: 'fe80::a00:27ff:fe4e:66a1',\n       netmask: 'ffff:ffff:ffff:ffff::',\n       family: 'IPv6',\n       mac: '01:02:03:0a:0b:0c',\n       internal: false } ] }
\n

Note that due to the underlying implementation this will only return network\ninterfaces that have been assigned an address.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.platform()", "type": "method", "name": "platform", "desc": "

Returns the operating system platform. Possible values are 'darwin',\n'freebsd', 'linux', 'sunos' or 'win32'. Returns the value of\nprocess.platform.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.release()", "type": "method", "name": "release", "desc": "

Returns the operating system release.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.tmpdir()", "type": "method", "name": "tmpdir", "desc": "

Returns the operating system's default directory for temporary files.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.totalmem()", "type": "method", "name": "totalmem", "desc": "

Returns the total amount of system memory in bytes.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.type()", "type": "method", "name": "type", "desc": "

Returns the operating system name. For example 'Linux' on Linux, 'Darwin'\non OS X and 'Windows_NT' on Windows.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.uptime()", "type": "method", "name": "uptime", "desc": "

Returns the system uptime in seconds.\n\n

\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "OS" }, { "textRaw": "Path", "name": "path", "stability": 2, "stabilityText": "Stable", "desc": "

This module contains utilities for handling and transforming file\npaths. Almost all these methods perform only string transformations.\nThe file system is not consulted to check whether paths are valid.\n\n

\n

Use require('path') to use this module. The following methods are provided:\n\n

\n", "methods": [ { "textRaw": "path.basename(p[, ext])", "type": "method", "name": "basename", "desc": "

Return the last portion of a path. Similar to the Unix basename command.\n\n

\n

Example:\n\n

\n
path.basename('/foo/bar/baz/asdf/quux.html')\n// returns\n'quux.html'\n\npath.basename('/foo/bar/baz/asdf/quux.html', '.html')\n// returns\n'quux'
\n", "signatures": [ { "params": [ { "name": "p" }, { "name": "ext", "optional": true } ] } ] }, { "textRaw": "path.dirname(p)", "type": "method", "name": "dirname", "desc": "

Return the directory name of a path. Similar to the Unix dirname command.\n\n

\n

Example:\n\n

\n
path.dirname('/foo/bar/baz/asdf/quux')\n// returns\n'/foo/bar/baz/asdf'
\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.extname(p)", "type": "method", "name": "extname", "desc": "

Return the extension of the path, from the last '.' to end of string\nin the last portion of the path. If there is no '.' in the last portion\nof the path or the first character of it is '.', then it returns\nan empty string. Examples:\n\n

\n
path.extname('index.html')\n// returns\n'.html'\n\npath.extname('index.coffee.md')\n// returns\n'.md'\n\npath.extname('index.')\n// returns\n'.'\n\npath.extname('index')\n// returns\n''\n\npath.extname('.index')\n// returns\n''
\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.format(pathObject)", "type": "method", "name": "format", "desc": "

Returns a path string from an object, the opposite of path.parse above.\n\n

\n
path.format({\n    root : "/",\n    dir : "/home/user/dir",\n    base : "file.txt",\n    ext : ".txt",\n    name : "file"\n})\n// returns\n'/home/user/dir/file.txt'
\n", "signatures": [ { "params": [ { "name": "pathObject" } ] } ] }, { "textRaw": "path.isAbsolute(path)", "type": "method", "name": "isAbsolute", "desc": "

Determines whether path is an absolute path. An absolute path will always\nresolve to the same location, regardless of the working directory.\n\n

\n

Posix examples:\n\n

\n
path.isAbsolute('/foo/bar') // true\npath.isAbsolute('/baz/..')  // true\npath.isAbsolute('qux/')     // false\npath.isAbsolute('.')        // false
\n

Windows examples:\n\n

\n
path.isAbsolute('//server')  // true\npath.isAbsolute('C:/foo/..') // true\npath.isAbsolute('bar\\\\baz')  // false\npath.isAbsolute('.')         // false
\n

Note: If the path string passed as parameter is a zero-length string, unlike\n other path module functions, it will be used as-is and false will be\n returned.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "path.join([path1][, path2][, ...])", "type": "method", "name": "join", "desc": "

Join all arguments together and normalize the resulting path.\n\n

\n

Arguments must be strings. In v0.8, non-string arguments were\nsilently ignored. In v0.10 and up, an exception is thrown.\n\n

\n

Example:\n\n

\n
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')\n// returns\n'/foo/bar/baz/asdf'\n\npath.join('foo', {}, 'bar')\n// throws exception\nTypeError: Arguments to path.join must be strings
\n

Note: If the arguments to join have zero-length strings, unlike other path\n module functions, they will be ignored. If the joined path string is a\n zero-length string then '.' will be returned, which represents the\n current working directory.\n\n

\n", "signatures": [ { "params": [ { "name": "path1", "optional": true }, { "name": "path2", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "path.normalize(p)", "type": "method", "name": "normalize", "desc": "

Normalize a string path, taking care of '..' and '.' parts.\n\n

\n

When multiple slashes are found, they're replaced by a single one;\nwhen the path contains a trailing slash, it is preserved.\nOn Windows backslashes are used.\n\n

\n

Example:\n\n

\n
path.normalize('/foo/bar//baz/asdf/quux/..')\n// returns\n'/foo/bar/baz/asdf'
\n

Note: If the path string passed as argument is a zero-length string then '.'\n will be returned, which represents the current working directory.\n\n

\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.parse(pathString)", "type": "method", "name": "parse", "desc": "

Returns an object from a path string.\n\n

\n

An example on *nix:\n\n

\n
path.parse('/home/user/dir/file.txt')\n// returns\n{\n    root : "/",\n    dir : "/home/user/dir",\n    base : "file.txt",\n    ext : ".txt",\n    name : "file"\n}
\n

An example on Windows:\n\n

\n
path.parse('C:\\\\path\\\\dir\\\\index.html')\n// returns\n{\n    root : "C:\\\\",\n    dir : "C:\\\\path\\\\dir",\n    base : "index.html",\n    ext : ".html",\n    name : "index"\n}
\n", "signatures": [ { "params": [ { "name": "pathString" } ] } ] }, { "textRaw": "path.relative(from, to)", "type": "method", "name": "relative", "desc": "

Solve the relative path from from to to.\n\n

\n

At times we have two absolute paths, and we need to derive the relative\npath from one to the other. This is actually the reverse transform of\npath.resolve, which means we see that:\n\n

\n
path.resolve(from, path.relative(from, to)) == path.resolve(to)
\n

Examples:\n\n

\n
path.relative('C:\\\\orandea\\\\test\\\\aaa', 'C:\\\\orandea\\\\impl\\\\bbb')\n// returns\n'..\\\\..\\\\impl\\\\bbb'\n\npath.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')\n// returns\n'../../impl/bbb'
\n

Note: If the arguments to relative have zero-length strings then the current\n working directory will be used instead of the zero-length strings. If\n both the paths are the same then a zero-length string will be returned.\n\n

\n", "signatures": [ { "params": [ { "name": "from" }, { "name": "to" } ] } ] }, { "textRaw": "path.resolve([from ...], to)", "type": "method", "name": "resolve", "desc": "

Resolves to to an absolute path.\n\n

\n

If to isn't already absolute from arguments are prepended in right to left\norder, until an absolute path is found. If after using all from paths still\nno absolute path is found, the current working directory is used as well. The\nresulting path is normalized, and trailing slashes are removed unless the path\ngets resolved to the root directory. Non-string from arguments are ignored.\n\n

\n

Another way to think of it is as a sequence of cd commands in a shell.\n\n

\n
path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')
\n

Is similar to:\n\n

\n
cd foo/bar\ncd /tmp/file/\ncd ..\ncd a/../subfile\npwd
\n

The difference is that the different paths don't need to exist and may also be\nfiles.\n\n

\n

Examples:\n\n

\n
path.resolve('/foo/bar', './baz')\n// returns\n'/foo/bar/baz'\n\npath.resolve('/foo/bar', '/tmp/file/')\n// returns\n'/tmp/file'\n\npath.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')\n// if currently in /home/myself/node, it returns\n'/home/myself/node/wwwroot/static_files/gif/image.gif'
\n

Note: If the arguments to resolve have zero-length strings then the current\n working directory will be used instead of them.\n\n

\n", "signatures": [ { "params": [ { "name": "from ...", "optional": true }, { "name": "to" } ] } ] } ], "properties": [ { "textRaw": "path.delimiter", "name": "delimiter", "desc": "

The platform-specific path delimiter, ; or ':'.\n\n

\n

An example on *nix:\n\n

\n
console.log(process.env.PATH)\n// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'\n\nprocess.env.PATH.split(path.delimiter)\n// returns\n['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
\n

An example on Windows:\n\n

\n
console.log(process.env.PATH)\n// 'C:\\Windows\\system32;C:\\Windows;C:\\Program Files\\node\\'\n\nprocess.env.PATH.split(path.delimiter)\n// returns\n['C:\\\\Windows\\\\system32', 'C:\\\\Windows', 'C:\\\\Program Files\\\\node\\\\']
\n" }, { "textRaw": "path.posix", "name": "posix", "desc": "

Provide access to aforementioned path methods but always interact in a posix\ncompatible way.\n\n

\n" }, { "textRaw": "path.sep", "name": "sep", "desc": "

The platform-specific file separator. '\\\\' or '/'.\n\n

\n

An example on *nix:\n\n

\n
'foo/bar/baz'.split(path.sep)\n// returns\n['foo', 'bar', 'baz']
\n

An example on Windows:\n\n

\n
'foo\\\\bar\\\\baz'.split(path.sep)\n// returns\n['foo', 'bar', 'baz']
\n" }, { "textRaw": "path.win32", "name": "win32", "desc": "

Provide access to aforementioned path methods but always interact in a win32\ncompatible way.\n\n

\n" } ], "type": "module", "displayName": "Path" }, { "textRaw": "punycode", "name": "punycode", "stability": 2, "stabilityText": "Stable", "desc": "

[Punycode.js][] is bundled with Node.js v0.6.2+. Use require('punycode') to\naccess it. (To use it with other Node.js versions, use npm to install the\npunycode module first.)\n\n

\n", "methods": [ { "textRaw": "punycode.decode(string)", "type": "method", "name": "decode", "desc": "

Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols.\n\n

\n
// decode domain name parts\npunycode.decode('maana-pta'); // 'mañana'\npunycode.decode('--dqo34k'); // '☃-⌘'
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "punycode.encode(string)", "type": "method", "name": "encode", "desc": "

Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols.\n\n

\n
// encode domain name parts\npunycode.encode('mañana'); // 'maana-pta'\npunycode.encode('☃-⌘'); // '--dqo34k'
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "punycode.toASCII(domain)", "type": "method", "name": "toASCII", "desc": "

Converts a Unicode string representing a domain name to Punycode. Only the\nnon-ASCII parts of the domain name will be converted, i.e. it doesn't matter if\nyou call it with a domain that's already in ASCII.\n\n

\n
// encode domain names\npunycode.toASCII('mañana.com'); // 'xn--maana-pta.com'\npunycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'
\n", "signatures": [ { "params": [ { "name": "domain" } ] } ] }, { "textRaw": "punycode.toUnicode(domain)", "type": "method", "name": "toUnicode", "desc": "

Converts a Punycode string representing a domain name to Unicode. Only the\nPunycoded parts of the domain name will be converted, i.e. it doesn't matter if\nyou call it on a string that has already been converted to Unicode.\n\n

\n
// decode domain names\npunycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'\npunycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'
\n", "signatures": [ { "params": [ { "name": "domain" } ] } ] } ], "properties": [ { "textRaw": "punycode.ucs2", "name": "ucs2", "modules": [ { "textRaw": "punycode.ucs2.decode(string)", "name": "punycode.ucs2.decode(string)", "desc": "

Creates an array containing the numeric code point values of each Unicode\nsymbol in the string. While [JavaScript uses UCS-2 internally][], this function\nwill convert a pair of surrogate halves (each of which UCS-2 exposes as\nseparate characters) into a single code point, matching UTF-16.\n\n

\n
punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]\n// surrogate pair for U+1D306 tetragram for centre:\npunycode.ucs2.decode('\\uD834\\uDF06'); // [0x1D306]
\n", "type": "module", "displayName": "punycode.ucs2.decode(string)" }, { "textRaw": "punycode.ucs2.encode(codePoints)", "name": "punycode.ucs2.encode(codepoints)", "desc": "

Creates a string based on an array of numeric code point values.\n\n

\n
punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'\npunycode.ucs2.encode([0x1D306]); // '\\uD834\\uDF06'
\n", "type": "module", "displayName": "punycode.ucs2.encode(codePoints)" } ] }, { "textRaw": "punycode.version", "name": "version", "desc": "

A string representing the current Punycode.js version number.\n\n

\n" } ], "type": "module", "displayName": "punycode" }, { "textRaw": "Query String", "name": "querystring", "stability": 2, "stabilityText": "Stable", "desc": "

This module provides utilities for dealing with query strings.\nIt provides the following methods:\n\n

\n", "properties": [ { "textRaw": "querystring.escape", "name": "escape", "desc": "

The escape function used by querystring.stringify,\nprovided so that it could be overridden if necessary.\n\n

\n" }, { "textRaw": "querystring.unescape", "name": "unescape", "desc": "

The unescape function used by querystring.parse,\nprovided so that it could be overridden if necessary.\n\n

\n

It will try to use decodeURIComponent in the first place,\nbut if that fails it falls back to a safer equivalent that\ndoesn't throw on malformed URLs.\n\n

\n" } ], "methods": [ { "textRaw": "querystring.parse(str[, sep][, eq][, options])", "type": "method", "name": "parse", "desc": "

Deserialize a query string to an object.\nOptionally override the default separator ('&') and assignment ('=')\ncharacters.\n\n

\n

Options object may contain maxKeys property (equal to 1000 by default), it'll\nbe used to limit processed keys. Set it to 0 to remove key count limitation.\n\n

\n

Options object may contain decodeURIComponent property (querystring.unescape by default),\nit can be used to decode a non-utf8 encoding string if necessary.\n\n

\n

Example:\n\n

\n
querystring.parse('foo=bar&baz=qux&baz=quux&corge')\n// returns\n{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }\n\n// Suppose gbkDecodeURIComponent function already exists,\n// it can decode `gbk` encoding string\nquerystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null,\n  { decodeURIComponent: gbkDecodeURIComponent })\n// returns\n{ w: '中文', foo: 'bar' }
\n", "signatures": [ { "params": [ { "name": "str" }, { "name": "sep", "optional": true }, { "name": "eq", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "querystring.stringify(obj[, sep][, eq][, options])", "type": "method", "name": "stringify", "desc": "

Serialize an object to a query string.\nOptionally override the default separator ('&') and assignment ('=')\ncharacters.\n\n

\n

Options object may contain encodeURIComponent property (querystring.escape by default),\nit can be used to encode string with non-utf8 encoding if necessary.\n\n

\n

Example:\n\n

\n
querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })\n// returns\n'foo=bar&baz=qux&baz=quux&corge='\n\nquerystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')\n// returns\n'foo:bar;baz:qux'\n\n// Suppose gbkEncodeURIComponent function already exists,\n// it can encode string with `gbk` encoding\nquerystring.stringify({ w: '中文', foo: 'bar' }, null, null,\n  { encodeURIComponent: gbkEncodeURIComponent })\n// returns\n'w=%D6%D0%CE%C4&foo=bar'
\n", "signatures": [ { "params": [ { "name": "obj" }, { "name": "sep", "optional": true }, { "name": "eq", "optional": true }, { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "querystring" }, { "textRaw": "Readline", "name": "readline", "stability": 2, "stabilityText": "Stable", "desc": "

To use this module, do require('readline'). Readline allows reading of a\nstream (such as [process.stdin][]) on a line-by-line basis.\n\n

\n

Note that once you've invoked this module, your Node.js program will not\nterminate until you've closed the interface. Here's how to allow your\nprogram to gracefully exit:\n\n

\n
const readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nrl.question('What do you think of Node.js? ', (answer) => {\n  // TODO: Log the answer in a database\n  console.log('Thank you for your valuable feedback:', answer);\n\n  rl.close();\n});
\n", "classes": [ { "textRaw": "Class: Interface", "type": "class", "name": "Interface", "desc": "

The class that represents a readline interface with an input and output\nstream.\n\n

\n", "methods": [ { "textRaw": "rl.close()", "type": "method", "name": "close", "desc": "

Closes the Interface instance, relinquishing control on the input and\noutput streams. The 'close' event will also be emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.pause()", "type": "method", "name": "pause", "desc": "

Pauses the readline input stream, allowing it to be resumed later if needed.\n\n

\n

Note that this doesn't immediately pause the stream of events. Several events may\nbe emitted after calling pause, including line.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.prompt([preserveCursor])", "type": "method", "name": "prompt", "desc": "

Readies readline for input from the user, putting the current setPrompt\noptions on a new line, giving the user a new spot to write. Set preserveCursor\nto true to prevent the cursor placement being reset to 0.\n\n

\n

This will also resume the input stream used with createInterface if it has\nbeen paused.\n\n

\n

If output is set to null or undefined when calling createInterface, the\nprompt is not written.\n\n

\n", "signatures": [ { "params": [ { "name": "preserveCursor", "optional": true } ] } ] }, { "textRaw": "rl.question(query, callback)", "type": "method", "name": "question", "desc": "

Prepends the prompt with query and invokes callback with the user's\nresponse. Displays the query to the user, and then invokes callback\nwith the user's response after it has been typed.\n\n

\n

This will also resume the input stream used with createInterface if\nit has been paused.\n\n

\n

If output is set to null or undefined when calling createInterface,\nnothing is displayed.\n\n

\n

Example usage:\n\n

\n
interface.question('What is your favorite food?', (answer) => {\n  console.log(`Oh, so your favorite food is ${answer}`);\n});
\n", "signatures": [ { "params": [ { "name": "query" }, { "name": "callback" } ] } ] }, { "textRaw": "rl.resume()", "type": "method", "name": "resume", "desc": "

Resumes the readline input stream.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.setPrompt(prompt)", "type": "method", "name": "setPrompt", "desc": "

Sets the prompt, for example when you run node on the command line, you see\n> , which is Node.js's prompt.\n\n

\n", "signatures": [ { "params": [ { "name": "prompt" } ] } ] }, { "textRaw": "rl.write(data[, key])", "type": "method", "name": "write", "desc": "

Writes data to output stream, unless output is set to null or\nundefined when calling createInterface. key is an object literal to\nrepresent a key sequence; available if the terminal is a TTY.\n\n

\n

This will also resume the input stream if it has been paused.\n\n

\n

Example:\n\n

\n
rl.write('Delete me!');\n// Simulate ctrl+u to delete the line written previously\nrl.write(null, {ctrl: true, name: 'u'});
\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "key", "optional": true } ] } ] } ] } ], "modules": [ { "textRaw": "Events", "name": "events", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () {}\n\n

\n

Emitted when close() is called.\n\n

\n

Also emitted when the input stream receives its 'end' event. The Interface\ninstance should be considered "finished" once this is emitted. For example, when\nthe input stream receives ^D, respectively known as EOT.\n\n

\n

This event is also called if there is no SIGINT event listener present when\nthe input stream receives a ^C, respectively known as SIGINT.\n\n

\n", "params": [] }, { "textRaw": "Event: 'line'", "type": "event", "name": "line", "desc": "

function (line) {}\n\n

\n

Emitted whenever the input stream receives a \\n, usually received when the\nuser hits enter, or return. This is a good hook to listen for user input.\n\n

\n

Example of listening for 'line':\n\n

\n
rl.on('line', (cmd) => {\n  console.log(`You just typed: ${cmd}`);\n});
\n", "params": [] }, { "textRaw": "Event: 'pause'", "type": "event", "name": "pause", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream is paused.\n\n

\n

Also emitted whenever the input stream is not paused and receives the\nSIGCONT event. (See events SIGTSTP and SIGCONT)\n\n

\n

Example of listening for 'pause':\n\n

\n
rl.on('pause', () => {\n  console.log('Readline paused.');\n});
\n", "params": [] }, { "textRaw": "Event: 'resume'", "type": "event", "name": "resume", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream is resumed.\n\n

\n

Example of listening for 'resume':\n\n

\n
rl.on('resume', () => {\n  console.log('Readline resumed.');\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGCONT'", "type": "event", "name": "SIGCONT", "desc": "

function () {}\n\n

\n

This does not work on Windows.\n\n

\n

Emitted whenever the input stream is sent to the background with ^Z,\nrespectively known as SIGTSTP, and then continued with fg(1). This event\nonly emits if the stream was not paused before sending the program to the\nbackground.\n\n

\n

Example of listening for SIGCONT:\n\n

\n
rl.on('SIGCONT', () => {\n  // `prompt` will automatically resume the stream\n  rl.prompt();\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGINT'", "type": "event", "name": "SIGINT", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream receives a ^C, respectively known as\nSIGINT. If there is no SIGINT event listener present when the input\nstream receives a SIGINT, pause will be triggered.\n\n

\n

Example of listening for SIGINT:\n\n

\n
rl.on('SIGINT', () => {\n  rl.question('Are you sure you want to exit?', (answer) => {\n    if (answer.match(/^y(es)?$/i)) rl.pause();\n  });\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGTSTP'", "type": "event", "name": "SIGTSTP", "desc": "

function () {}\n\n

\n

This does not work on Windows.\n\n

\n

Emitted whenever the input stream receives a ^Z, respectively known as\nSIGTSTP. If there is no SIGTSTP event listener present when the input\nstream receives a SIGTSTP, the program will be sent to the background.\n\n

\n

When the program is resumed with fg, the 'pause' and SIGCONT events will be\nemitted. You can use either to resume the stream.\n\n

\n

The 'pause' and SIGCONT events will not be triggered if the stream was paused\nbefore the program was sent to the background.\n\n

\n

Example of listening for SIGTSTP:\n\n

\n
rl.on('SIGTSTP', () => {\n  // This will override SIGTSTP and prevent the program from going to the\n  // background.\n  console.log('Caught SIGTSTP.');\n});
\n

Example: Tiny CLI

\n

Here's an example of how to use all these together to craft a tiny command\nline interface:\n\n

\n
const readline = require('readline');\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nrl.setPrompt('OHAI> ');\nrl.prompt();\n\nrl.on('line', (line) => {\n  switch(line.trim()) {\n    case 'hello':\n      console.log('world!');\n      break;\n    default:\n      console.log('Say what? I might have heard `' + line.trim() + '`');\n      break;\n  }\n  rl.prompt();\n}).on('close', () => {\n  console.log('Have a great day!');\n  process.exit(0);\n});
\n

Example: Read File Stream Line-by-Line

\n

A common case for readline's input option is to pass a filesystem readable\nstream to it. This is how one could craft line-by-line parsing of a file:\n\n

\n
const readline = require('readline');\nconst fs = require('fs');\n\nconst rl = readline.createInterface({\n  input: fs.createReadStream('sample.txt')\n});\n\nrl.on('line', function (line) {\n  console.log('Line from file:', line);\n});
\n", "params": [] } ], "type": "module", "displayName": "Events" } ], "methods": [ { "textRaw": "readline.clearLine(stream, dir)", "type": "method", "name": "clearLine", "desc": "

Clears current line of given TTY stream in a specified direction.\ndir should have one of following values:\n\n

\n
    \n
  • -1 - to the left from cursor
  • \n
  • 1 - to the right from cursor
  • \n
  • 0 - the entire line
  • \n
\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "dir" } ] } ] }, { "textRaw": "readline.clearScreenDown(stream)", "type": "method", "name": "clearScreenDown", "desc": "

Clears the screen from the current position of the cursor down.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" } ] } ] }, { "textRaw": "readline.createInterface(options)", "type": "method", "name": "createInterface", "desc": "

Creates a readline Interface instance. Accepts an options Object that takes\nthe following values:\n\n

\n
    \n
  • input - the readable stream to listen to (Required).

    \n
  • \n
  • output - the writable stream to write readline data to (Optional).

    \n
  • \n
  • completer - an optional function that is used for Tab autocompletion. See\nbelow for an example of using this.

    \n
  • \n
  • terminal - pass true if the input and output streams should be\ntreated like a TTY, and have ANSI/VT100 escape codes written to it.\nDefaults to checking isTTY on the output stream upon instantiation.

    \n
  • \n
  • historySize - maximum number of history lines retained. Defaults to 30.

    \n
  • \n
\n

The completer function is given the current line entered by the user, and\nis supposed to return an Array with 2 entries:\n\n

\n
    \n
  1. An Array with matching entries for the completion.

    \n
  2. \n
  3. The substring that was used for the matching.

    \n
  4. \n
\n

Which ends up looking something like:\n[[substr1, substr2, ...], originalsubstring].\n\n

\n

Example:\n\n

\n
function completer(line) {\n  var completions = '.help .error .exit .quit .q'.split(' ')\n  var hits = completions.filter((c) => { return c.indexOf(line) == 0 })\n  // show all completions if none found\n  return [hits.length ? hits : completions, line]\n}
\n

Also completer can be run in async mode if it accepts two arguments:\n\n

\n
function completer(linePartial, callback) {\n  callback(null, [['123'], linePartial]);\n}
\n

createInterface is commonly used with [process.stdin][] and\n[process.stdout][] in order to accept user input:\n\n

\n
const readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});
\n

Once you have a readline instance, you most commonly listen for the\n'line' event.\n\n

\n

If terminal is true for this instance then the output stream will get\nthe best compatibility if it defines an output.columns property, and fires\na 'resize' event on the output if/when the columns ever change\n([process.stdout][] does this automatically when it is a TTY).\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] }, { "textRaw": "readline.cursorTo(stream, x, y)", "type": "method", "name": "cursorTo", "desc": "

Move cursor to the specified position in a given TTY stream.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "x" }, { "name": "y" } ] } ] }, { "textRaw": "readline.moveCursor(stream, dx, dy)", "type": "method", "name": "moveCursor", "desc": "

Move cursor relative to it's current position in a given TTY stream.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "dx" }, { "name": "dy" } ] } ] } ], "type": "module", "displayName": "Readline" }, { "textRaw": "REPL", "name": "repl", "stability": 2, "stabilityText": "Stable", "desc": "

A Read-Eval-Print-Loop (REPL) is available both as a standalone program and\neasily includable in other programs. The REPL provides a way to interactively\nrun JavaScript and see the results. It can be used for debugging, testing, or\njust trying things out.\n\n

\n

By executing node without any arguments from the command-line you will be\ndropped into the REPL. It has simplistic emacs line-editing.\n\n

\n
mjr:~$ node\nType '.help' for options.\n> a = [ 1, 2, 3];\n[ 1, 2, 3 ]\n> a.forEach(function (v) {\n...   console.log(v);\n...   });\n1\n2\n3
\n

For advanced line-editors, start Node.js with the environmental variable\nNODE_NO_READLINE=1. This will start the main and debugger REPL in canonical\nterminal settings which will allow you to use with rlwrap.\n\n

\n

For example, you could add this to your bashrc file:\n\n

\n
alias node="env NODE_NO_READLINE=1 rlwrap node"
\n", "modules": [ { "textRaw": "Environment Variable Options", "name": "environment_variable_options", "desc": "

The built-in repl (invoked by running node or node -i) may be controlled\nvia the following environment variables:\n\n

\n
    \n
  • NODE_REPL_HISTORY - When a valid path is given, persistent REPL history\nwill be saved to the specified file rather than .node_repl_history in the\nuser's home directory. Setting this value to "" will disable persistent\nREPL history.
  • \n
  • NODE_REPL_HISTORY_SIZE - defaults to 1000. Controls how many lines of\nhistory will be persisted if history is available. Must be a positive number.
  • \n
  • NODE_REPL_MODE - may be any of sloppy, strict, or magic. Defaults\nto magic, which will automatically run "strict mode only" statements in\nstrict mode.
  • \n
\n", "type": "module", "displayName": "Environment Variable Options" }, { "textRaw": "Persistent History", "name": "persistent_history", "desc": "

By default, the REPL will persist history between node REPL sessions by saving\nto a .node_repl_history file in the user's home directory. This can be\ndisabled by setting the environment variable NODE_REPL_HISTORY="".\n\n

\n", "modules": [ { "textRaw": "NODE_REPL_HISTORY_FILE", "name": "node_repl_history_file", "stability": 0, "stabilityText": "Deprecated: Use `NODE_REPL_HISTORY` instead.", "desc": "

Previously in Node.js/io.js v2.x, REPL history was controlled by using a\nNODE_REPL_HISTORY_FILE environment variable, and the history was saved in JSON\nformat. This variable has now been deprecated, and your REPL history will\nautomatically be converted to using plain text. The new file will be saved to\neither your home directory, or a directory defined by the NODE_REPL_HISTORY\nvariable, as documented below.\n\n

\n", "type": "module", "displayName": "NODE_REPL_HISTORY_FILE" } ], "type": "module", "displayName": "Persistent History" } ], "miscs": [ { "textRaw": "REPL Features", "name": "REPL Features", "type": "misc", "desc": "

Inside the REPL, Control+D will exit. Multi-line expressions can be input.\nTab completion is supported for both global and local variables.\n\n

\n

Core modules will be loaded on-demand into the environment. For example,\naccessing fs will require() the fs module as global.fs.\n\n

\n

The special variable _ (underscore) contains the result of the last expression.\n\n

\n
> [ 'a', 'b', 'c' ]\n[ 'a', 'b', 'c' ]\n> _.length\n3\n> _ += 1\n4
\n

The REPL provides access to any variables in the global scope. You can expose\na variable to the REPL explicitly by assigning it to the context object\nassociated with each REPLServer. For example:\n\n

\n
// repl_test.js\nconst repl = require('repl');\nvar msg = 'message';\n\nrepl.start('> ').context.m = msg;
\n

Things in the context object appear as local within the REPL:\n\n

\n
mjr:~$ node repl_test.js\n> m\n'message'
\n

There are a few special REPL commands:\n\n

\n
    \n
  • .break - While inputting a multi-line expression, sometimes you get lost\nor just don't care about completing it. .break will start over.
  • \n
  • .clear - Resets the context object to an empty object and clears any\nmulti-line expression.
  • \n
  • .exit - Close the I/O stream, which will cause the REPL to exit.
  • \n
  • .help - Show this list of special commands.
  • \n
  • .save - Save the current REPL session to a file
    \n

    .save ./file/to/save.js

    \n
    \n
  • \n
  • .load - Load a file into the current REPL session.
    \n

    .load ./file/to/load.js

    \n
    \n
  • \n
\n

The following key combinations in the REPL have these special effects:\n\n

\n
    \n
  • <ctrl>C - Similar to the .break keyword. Terminates the current\ncommand. Press twice on a blank line to forcibly exit.
  • \n
  • <ctrl>D - Similar to the .exit keyword.
  • \n
  • <tab> - Show both global and local(scope) variables
  • \n
\n", "miscs": [ { "textRaw": "Customizing Object displays in the REPL", "name": "customizing_object_displays_in_the_repl", "desc": "

The REPL module internally uses\n[util.inspect()][], when printing values. However, util.inspect delegates the\n call to the object's inspect() function, if it has one. You can read more\n about this delegation [here][].\n\n

\n

For example, if you have defined an inspect() function on an object, like this:\n\n

\n
> var obj = { foo: 'this will not show up in the inspect() output' };\nundefined\n> obj.inspect = function() {\n...   return { bar: 'baz' };\n... };\n[Function]
\n

and try to print obj in REPL, it will invoke the custom inspect() function:\n\n

\n
> obj\n{ bar: 'baz' }
\n", "type": "misc", "displayName": "Customizing Object displays in the REPL" } ] } ], "classes": [ { "textRaw": "Class: REPLServer", "type": "class", "name": "REPLServer", "desc": "

This inherits from [Readline Interface][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "desc": "

function () {}\n\n

\n

Emitted when the user exits the REPL in any of the defined ways. Namely, typing\n.exit at the repl, pressing Ctrl+C twice to signal SIGINT, or pressing Ctrl+D\nto signal 'end' on the input stream.\n\n

\n

Example of listening for exit:\n\n

\n
replServer.on('exit', () => {\n  console.log('Got "exit" event from repl!');\n  process.exit();\n});
\n", "params": [] }, { "textRaw": "Event: 'reset'", "type": "event", "name": "reset", "desc": "

function (context) {}\n\n

\n

Emitted when the REPL's context is reset. This happens when you type .clear.\nIf you start the repl with { useGlobal: true } then this event will never\nbe emitted.\n\n

\n

Example of listening for reset:\n\n

\n
// Extend the initial repl context.\nvar replServer = repl.start({ options ... });\nsomeExtension.extend(r.context);\n\n// When a new context is created extend it as well.\nreplServer.on('reset', (context) => {\n  console.log('repl has a new context');\n  someExtension.extend(context);\n});
\n", "params": [] } ], "methods": [ { "textRaw": "replServer.defineCommand(keyword, cmd)", "type": "method", "name": "defineCommand", "signatures": [ { "params": [ { "textRaw": "`keyword` {String} ", "name": "keyword", "type": "String" }, { "textRaw": "`cmd` {Object|Function} ", "name": "cmd", "type": "Object|Function" } ] }, { "params": [ { "name": "keyword" }, { "name": "cmd" } ] } ], "desc": "

Makes a command available in the REPL. The command is invoked by typing a .\nfollowed by the keyword. The cmd is an object with the following values:\n\n

\n
    \n
  • help - help text to be displayed when .help is entered (Optional).
  • \n
  • action - a function to execute, potentially taking in a string argument,\nwhen the command is invoked, bound to the REPLServer instance (Required).
  • \n
\n

If a function is provided instead of an object for cmd, it is treated as the\naction.\n\n

\n

Example of defining a command:\n\n

\n
// repl_test.js\nconst repl = require('repl');\n\nvar replServer = repl.start();\nreplServer.defineCommand('sayhello', {\n  help: 'Say hello',\n  action: function(name) {\n    this.write(`Hello, ${name}!\\n');\n    this.displayPrompt();\n  }\n});
\n

Example of invoking that command from the REPL:\n\n

\n
> .sayhello Node.js User\nHello, Node.js User!
\n" }, { "textRaw": "replServer.displayPrompt([preserveCursor])", "type": "method", "name": "displayPrompt", "signatures": [ { "params": [ { "textRaw": "`preserveCursor` {Boolean} ", "name": "preserveCursor", "type": "Boolean", "optional": true } ] }, { "params": [ { "name": "preserveCursor", "optional": true } ] } ], "desc": "

Like [readline.prompt][] except also adding indents with ellipses when inside\nblocks. The preserveCursor argument is passed to [readline.prompt][]. This is\nused primarily with defineCommand. It's also used internally to render each\nprompt line.\n\n

\n" } ] } ], "methods": [ { "textRaw": "repl.start(options)", "type": "method", "name": "start", "desc": "

Returns and starts a REPLServer instance, that inherits from\n[Readline Interface][]. Accepts an "options" Object that takes\nthe following values:\n\n

\n
    \n
  • prompt - the prompt and stream for all I/O. Defaults to > .

    \n
  • \n
  • input - the readable stream to listen to. Defaults to process.stdin.

    \n
  • \n
  • output - the writable stream to write readline data to. Defaults to\nprocess.stdout.

    \n
  • \n
  • terminal - pass true if the stream should be treated like a TTY, and\nhave ANSI/VT100 escape codes written to it. Defaults to checking isTTY\non the output stream upon instantiation.

    \n
  • \n
  • eval - function that will be used to eval each given line. Defaults to\nan async wrapper for eval(). See below for an example of a custom eval.

    \n
  • \n
  • useColors - a boolean which specifies whether or not the writer function\nshould output colors. If a different writer function is set then this does\nnothing. Defaults to the repl's terminal value.

    \n
  • \n
  • useGlobal - if set to true, then the repl will use the global object,\ninstead of running scripts in a separate context. Defaults to false.

    \n
  • \n
  • ignoreUndefined - if set to true, then the repl will not output the\nreturn value of command if it's undefined. Defaults to false.

    \n
  • \n
  • writer - the function to invoke for each command that gets evaluated which\nreturns the formatting (including coloring) to display. Defaults to\nutil.inspect.

    \n
  • \n
  • replMode - controls whether the repl runs all commands in strict mode,\ndefault mode, or a hybrid mode ("magic" mode.) Acceptable values are:

    \n
      \n
    • repl.REPL_MODE_SLOPPY - run commands in sloppy mode.
    • \n
    • repl.REPL_MODE_STRICT - run commands in strict mode. This is equivalent to\nprefacing every repl statement with 'use strict'.
    • \n
    • repl.REPL_MODE_MAGIC - attempt to run commands in default mode. If they\nfail to parse, re-try in strict mode.
    • \n
    \n
  • \n
\n

You can use your own eval function if it has following signature:\n\n

\n
function eval(cmd, context, filename, callback) {\n  callback(null, result);\n}
\n

On tab completion - eval will be called with .scope as an input string. It\nis expected to return an array of scope names to be used for the auto-completion.\n\n

\n

Multiple REPLs may be started against the same running instance of Node.js. Each\nwill share the same global object but will have unique I/O.\n\n

\n

Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:\n\n

\n
const net = require('net');\nconst repl = require('repl');\nvar connections = 0;\n\nrepl.start({\n  prompt: 'Node.js via stdin> ',\n  input: process.stdin,\n  output: process.stdout\n});\n\nnet.createServer((socket) => {\n  connections += 1;\n  repl.start({\n    prompt: 'Node.js via Unix socket> ',\n    input: socket,\n    output: socket\n  }).on('exit', () => {\n    socket.end();\n  })\n}).listen('/tmp/node-repl-sock');\n\nnet.createServer((socket) => {\n  connections += 1;\n  repl.start({\n    prompt: 'Node.js via TCP socket> ',\n    input: socket,\n    output: socket\n  }).on('exit', () => {\n    socket.end();\n  });\n}).listen(5001);
\n

Running this program from the command line will start a REPL on stdin. Other\nREPL clients may connect through the Unix socket or TCP socket. telnet is useful\nfor connecting to TCP sockets, and socat can be used to connect to both Unix and\nTCP sockets.\n\n

\n

By starting a REPL from a Unix socket-based server instead of stdin, you can\nconnect to a long-running Node.js process without restarting it.\n\n

\n

For an example of running a "full-featured" (terminal) REPL over\na net.Server and net.Socket instance, see: https://gist.github.com/2209310\n\n

\n

For an example of running a REPL instance over curl(1),\nsee: https://gist.github.com/2053342\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] } ], "type": "module", "displayName": "REPL" }, { "textRaw": "Stream", "name": "stream", "stability": 2, "stabilityText": "Stable", "desc": "

A stream is an abstract interface implemented by various objects in\nNode.js. For example a [request to an HTTP server][] is a stream, as is\n[stdout][]. Streams are readable, writable, or both. All streams are\ninstances of [EventEmitter][].\n\n

\n

You can load the Stream base classes by doing require('stream').\nThere are base classes provided for [Readable][] streams, [Writable][]\nstreams, [Duplex][] streams, and [Transform][] streams.\n\n

\n

This document is split up into 3 sections:\n\n

\n
    \n
  1. The first section explains the parts of the API that you need to be\naware of to use streams in your programs.
  2. \n
  3. The second section explains the parts of the API that you need to\nuse if you implement your own custom streams yourself. The API is\ndesigned to make this easy for you to do.
  4. \n
  5. The third section goes into more depth about how streams work,\nincluding some of the internal mechanisms and functions that you\nshould probably not modify unless you definitely know what you are\ndoing.
  6. \n
\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

Duplex streams are streams that implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Duplex streams include:\n\n

\n
    \n
  • [tcp sockets][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

The Readable stream interface is the abstraction for a source of\ndata that you are reading from. In other words, data comes out of a\nReadable stream.\n\n

\n

A Readable stream will not start emitting data until you indicate that\nyou are ready to receive it.\n\n

\n

Readable streams have two "modes": a flowing mode and a paused\nmode. When in flowing mode, data is read from the underlying system\nand provided to your program as fast as possible. In paused mode, you\nmust explicitly call stream.read() to get chunks of data out.\nStreams start out in paused mode.\n\n

\n

Note: If no data event handlers are attached, and there are no\n[pipe()][] destinations, and the stream is switched into flowing\nmode, then data will be lost.\n\n

\n

You can switch to flowing mode by doing any of the following:\n\n

\n
    \n
  • Adding a ['data'][] event handler to listen for data.
  • \n
  • Calling the [resume()][] method to explicitly open the flow.
  • \n
  • Calling the [pipe()][] method to send the data to a [Writable][].
  • \n
\n

You can switch back to paused mode by doing either of the following:\n\n

\n
    \n
  • If there are no pipe destinations, by calling the [pause()][]\nmethod.
  • \n
  • If there are pipe destinations, by removing any ['data'][] event\nhandlers, and removing all pipe destinations by calling the\n[unpipe()][] method.
  • \n
\n

Note that, for backwards compatibility reasons, removing 'data'\nevent handlers will not automatically pause the stream. Also, if\nthere are piped destinations, then calling pause() will not\nguarantee that the stream will remain paused once those\ndestinations drain and ask for more data.\n\n

\n

Examples of readable streams include:\n\n

\n
    \n
  • [http responses, on the client][]
  • \n
  • [http requests, on the server][]
  • \n
  • [fs read streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdout and stderr][]
  • \n
  • [process.stdin][]
  • \n
\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the stream and any of its underlying resources (a file\ndescriptor, for example) have been closed. The event indicates that\nno more events will be emitted, and no further computation will occur.\n\n

\n

Not all streams will emit the 'close' event.\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Attaching a 'data' event listener to a stream that has not been\nexplicitly paused will switch the stream into flowing mode. Data will\nthen be passed as soon as it is available.\n\n

\n

If you just want to get all the data out of the stream as fast as\npossible, this is the best way to do so.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});
\n" }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

This event fires when there will be no more data to read.\n\n

\n

Note that the 'end' event will not fire unless the data is\ncompletely consumed. This can be done by switching into flowing mode,\nor by calling read() repeatedly until you get to the end.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});\nreadable.on('end', () => {\n  console.log('there will be no more data.');\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error receiving data.\n\n

\n" }, { "textRaw": "Event: 'readable'", "type": "event", "name": "readable", "desc": "

When a chunk of data can be read from the stream, it will emit a\n'readable' event.\n\n

\n

In some cases, listening for a 'readable' event will cause some data\nto be read into the internal buffer from the underlying system, if it\nhadn't already.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  // there is some data to read now\n});
\n

Once the internal buffer is drained, a 'readable' event will fire\nagain when more data is available.\n\n

\n

The 'readable' event is not emitted in the "flowing" mode with the\nsole exception of the last one, on end-of-stream.\n\n

\n

The 'readable' event indicates that the stream has new information:\neither new data is available or the end of the stream has been reached.\nIn the former case, .read() will return that data. In the latter case,\n.read() will return null. For instance, in the following example, foo.txt\nis an empty file:\n\n

\n
const fs = require('fs');\nvar rr = fs.createReadStream('foo.txt');\nrr.on('readable', () => {\n  console.log('readable:', rr.read());\n});\nrr.on('end', () => {\n  console.log('end');\n});
\n

The output of running this script is:\n\n

\n
bash-3.2$ node test.js\nreadable: null\nend
\n", "params": [] } ], "methods": [ { "textRaw": "readable.isPaused()", "type": "method", "name": "isPaused", "signatures": [ { "return": { "textRaw": "Return: `Boolean` ", "name": "return", "desc": "`Boolean`" }, "params": [] }, { "params": [] } ], "desc": "

This method returns whether or not the readable has been explicitly\npaused by client code (using readable.pause() without a corresponding\nreadable.resume()).\n\n

\n
var readable = new stream.Readable\n\nreadable.isPaused() // === false\nreadable.pause()\nreadable.isPaused() // === true\nreadable.resume()\nreadable.isPaused() // === false
\n" }, { "textRaw": "readable.pause()", "type": "method", "name": "pause", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause a stream in flowing mode to stop emitting\n'data' events, switching out of flowing mode. Any data that becomes\navailable will remain in the internal buffer.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n  readable.pause();\n  console.log('there will be no more data for 1 second');\n  setTimeout(() => {\n    console.log('now data will start flowing again');\n    readable.resume();\n  }, 1000);\n});
\n" }, { "textRaw": "readable.pipe(destination[, options])", "type": "method", "name": "pipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} The destination for writing data ", "name": "destination", "type": "[Writable][] Stream", "desc": "The destination for writing data" }, { "textRaw": "`options` {Object} Pipe options ", "options": [ { "textRaw": "`end` {Boolean} End the writer when the reader ends. Default = `true` ", "name": "end", "type": "Boolean", "desc": "End the writer when the reader ends. Default = `true`" } ], "name": "options", "type": "Object", "desc": "Pipe options", "optional": true } ] }, { "params": [ { "name": "destination" }, { "name": "options", "optional": true } ] } ], "desc": "

This method pulls all the data out of a readable stream, and writes it\nto the supplied destination, automatically managing the flow so that\nthe destination is not overwhelmed by a fast readable stream.\n\n

\n

Multiple destinations can be piped to safely.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt'\nreadable.pipe(writable);
\n

This function returns the destination stream, so you can set up pipe\nchains like so:\n\n

\n
var r = fs.createReadStream('file.txt');\nvar z = zlib.createGzip();\nvar w = fs.createWriteStream('file.txt.gz');\nr.pipe(z).pipe(w);
\n

For example, emulating the Unix cat command:\n\n

\n
process.stdin.pipe(process.stdout);
\n

By default [end()][] is called on the destination when the source stream\nemits end, so that destination is no longer writable. Pass { end:\nfalse } as options to keep the destination stream open.\n\n

\n

This keeps writer open so that "Goodbye" can be written at the\nend.\n\n

\n
reader.pipe(writer, { end: false });\nreader.on('end', () => {\n  writer.end('Goodbye\\n');\n});
\n

Note that process.stderr and process.stdout are never closed until\nthe process exits, regardless of the specified options.\n\n

\n" }, { "textRaw": "readable.read([size])", "type": "method", "name": "read", "signatures": [ { "return": { "textRaw": "Return {String | Buffer | null} ", "name": "return", "type": "String | Buffer | null" }, "params": [ { "textRaw": "`size` {Number} Optional argument to specify how much data to read. ", "name": "size", "type": "Number", "desc": "Optional argument to specify how much data to read.", "optional": true } ] }, { "params": [ { "name": "size", "optional": true } ] } ], "desc": "

The read() method pulls some data out of the internal buffer and\nreturns it. If there is no data available, then it will return\nnull.\n\n

\n

If you pass in a size argument, then it will return that many\nbytes. If size bytes are not available, then it will return null,\nunless we've ended, in which case it will return the data remaining\nin the buffer.\n\n

\n

If you do not specify a size argument, then it will return all the\ndata in the internal buffer.\n\n

\n

This method should only be called in paused mode. In flowing mode,\nthis method is called automatically until the internal buffer is\ndrained.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  var chunk;\n  while (null !== (chunk = readable.read())) {\n    console.log('got %d bytes of data', chunk.length);\n  }\n});
\n

If this method returns a data chunk, then it will also trigger the\nemission of a ['data'][] event.\n\n

\n

Note that calling readable.read([size]) after the 'end' event has been\ntriggered will return null. No runtime error will be raised.\n\n

\n" }, { "textRaw": "readable.resume()", "type": "method", "name": "resume", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause the readable stream to resume emitting data\nevents.\n\n

\n

This method will switch the stream into flowing mode. If you do not\nwant to consume the data from a stream, but you do want to get to\nits 'end' event, you can call [readable.resume()][] to open the flow of\ndata.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.resume();\nreadable.on('end', () => {\n  console.log('got to the end, but did not read anything');\n});
\n" }, { "textRaw": "readable.setEncoding(encoding)", "type": "method", "name": "setEncoding", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [ { "textRaw": "`encoding` {String} The encoding to use. ", "name": "encoding", "type": "String", "desc": "The encoding to use." } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Call this function to cause the stream to return strings of the\nspecified encoding instead of Buffer objects. For example, if you do\nreadable.setEncoding('utf8'), then the output data will be\ninterpreted as UTF-8 data, and returned as strings. If you do\nreadable.setEncoding('hex'), then the data will be encoded in\nhexadecimal string format.\n\n

\n

This properly handles multi-byte characters that would otherwise be\npotentially mangled if you simply pulled the Buffers directly and\ncalled buf.toString(encoding) on them. If you want to read the data\nas strings, always use this method.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.setEncoding('utf8');\nreadable.on('data', (chunk) => {\n  assert.equal(typeof chunk, 'string');\n  console.log('got %d characters of string data', chunk.length);\n});
\n" }, { "textRaw": "readable.unpipe([destination])", "type": "method", "name": "unpipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} Optional specific stream to unpipe ", "name": "destination", "type": "[Writable][] Stream", "desc": "Optional specific stream to unpipe", "optional": true } ] }, { "params": [ { "name": "destination", "optional": true } ] } ], "desc": "

This method will remove the hooks set up for a previous pipe() call.\n\n

\n

If the destination is not specified, then all pipes are removed.\n\n

\n

If the destination is specified, but no pipe is set up for it, then\nthis is a no-op.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt',\n// but only for the first second\nreadable.pipe(writable);\nsetTimeout(() => {\n  console.log('stop writing to file.txt');\n  readable.unpipe(writable);\n  console.log('manually close the file stream');\n  writable.end();\n}, 1000);
\n" }, { "textRaw": "readable.unshift(chunk)", "type": "method", "name": "unshift", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} Chunk of data to unshift onto the read queue ", "name": "chunk", "type": "Buffer | String", "desc": "Chunk of data to unshift onto the read queue" } ] }, { "params": [ { "name": "chunk" } ] } ], "desc": "

This is useful in certain cases where a stream is being consumed by a\nparser, which needs to "un-consume" some data that it has\noptimistically pulled out of the source, so that the stream can be\npassed on to some other party.\n\n

\n

Note that stream.unshift(chunk) cannot be called after the 'end' event\nhas been triggered; a runtime error will be raised.\n\n

\n

If you find that you must often call stream.unshift(chunk) in your\nprograms, consider implementing a [Transform][] stream instead. (See API\nfor Stream Implementors, below.)\n\n

\n
// Pull off a header delimited by \\n\\n\n// use unshift() if we get too much\n// Call the callback with (error, header, stream)\nconst StringDecoder = require('string_decoder').StringDecoder;\nfunction parseHeader(stream, callback) {\n  stream.on('error', callback);\n  stream.on('readable', onReadable);\n  var decoder = new StringDecoder('utf8');\n  var header = '';\n  function onReadable() {\n    var chunk;\n    while (null !== (chunk = stream.read())) {\n      var str = decoder.write(chunk);\n      if (str.match(/\\n\\n/)) {\n        // found the header boundary\n        var split = str.split(/\\n\\n/);\n        header += split.shift();\n        var remaining = split.join('\\n\\n');\n        var buf = new Buffer(remaining, 'utf8');\n        if (buf.length)\n          stream.unshift(buf);\n        stream.removeListener('error', callback);\n        stream.removeListener('readable', onReadable);\n        // now the body of the message can be read from the stream.\n        callback(null, header, stream);\n      } else {\n        // still reading the header.\n        header += str;\n      }\n    }\n  }\n}
\n

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not\nend the reading process by resetting the internal reading state of the\nstream. This can cause unexpected results if unshift is called during a\nread (i.e. from within a _read implementation on a custom stream). Following\nthe call to unshift with an immediate stream.push('') will reset the\nreading state appropriately, however it is best to simply avoid calling\nunshift while in the process of performing a read.\n\n

\n" }, { "textRaw": "readable.wrap(stream)", "type": "method", "name": "wrap", "signatures": [ { "params": [ { "textRaw": "`stream` {Stream} An \"old style\" readable stream ", "name": "stream", "type": "Stream", "desc": "An \"old style\" readable stream" } ] }, { "params": [ { "name": "stream" } ] } ], "desc": "

Versions of Node.js prior to v0.10 had streams that did not implement the\nentire Streams API as it is today. (See "Compatibility" below for\nmore information.)\n\n

\n

If you are using an older Node.js library that emits 'data' events and\nhas a [pause()][] method that is advisory only, then you can use the\nwrap() method to create a [Readable][] stream that uses the old stream\nas its data source.\n\n

\n

You will very rarely ever need to call this function, but it exists\nas a convenience for interacting with old Node.js programs and libraries.\n\n

\n

For example:\n\n

\n
const OldReader = require('./old-api-module.js').OldReader;\nconst Readable = require('stream').Readable;\nconst oreader = new OldReader;\nconst myReader = new Readable().wrap(oreader);\n\nmyReader.on('readable', () => {\n  myReader.read(); // etc.\n});
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

Transform streams are [Duplex][] streams where the output is in some way\ncomputed from the input. They implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Transform streams include:\n\n

\n
    \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

The Writable stream interface is an abstraction for a destination\nthat you are writing data to.\n\n

\n

Examples of writable streams include:\n\n

\n
    \n
  • [http requests, on the client][]
  • \n
  • [http responses, on the server][]
  • \n
  • [fs write streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdin][]
  • \n
  • [process.stdout][], [process.stderr][]
  • \n
\n", "events": [ { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

If a [writable.write(chunk)][] call returns false, then the 'drain'\nevent will indicate when it is appropriate to begin writing more data\nto the stream.\n\n

\n
// Write the data to the supplied writable stream one million times.\n// Be attentive to back-pressure.\nfunction writeOneMillionTimes(writer, data, encoding, callback) {\n  var i = 1000000;\n  write();\n  function write() {\n    var ok = true;\n    do {\n      i -= 1;\n      if (i === 0) {\n        // last time!\n        writer.write(data, encoding, callback);\n      } else {\n        // see if we should continue, or wait\n        // don't pass the callback, because we're not done yet.\n        ok = writer.write(data, encoding);\n      }\n    } while (i > 0 && ok);\n    if (i > 0) {\n      // had to stop early!\n      // write some more once it drains\n      writer.once('drain', write);\n    }\n  }\n}
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error when writing or piping data.\n\n

\n" }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

When the [end()][] method has been called, and all data has been flushed\nto the underlying system, this event is emitted.\n\n

\n
var writer = getWritableStreamSomehow();\nfor (var i = 0; i < 100; i ++) {\n  writer.write('hello, #${i}!\\n');\n}\nwriter.end('this is the end\\n');\nwriter.on('finish', () => {\n  console.error('all writes are now complete.');\n});
\n", "params": [] }, { "textRaw": "Event: 'pipe'", "type": "event", "name": "pipe", "params": [], "desc": "

This is emitted whenever the pipe() method is called on a readable\nstream, adding this writable to its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('pipe', (src) => {\n  console.error('something is piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);
\n" }, { "textRaw": "Event: 'unpipe'", "type": "event", "name": "unpipe", "params": [], "desc": "

This is emitted whenever the [unpipe()][] method is called on a\nreadable stream, removing this writable from its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('unpipe', (src) => {\n  console.error('something has stopped piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);\nreader.unpipe(writer);
\n" } ], "methods": [ { "textRaw": "writable.cork()", "type": "method", "name": "cork", "desc": "

Forces buffering of all writes.\n\n

\n

Buffered data will be flushed either at .uncork() or at .end() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.end([chunk][, encoding][, callback])", "type": "method", "name": "end", "signatures": [ { "params": [ { "textRaw": "`chunk` {String | Buffer} Optional data to write ", "name": "chunk", "type": "String | Buffer", "desc": "Optional data to write", "optional": true }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Optional callback for when the stream is finished ", "name": "callback", "type": "Function", "desc": "Optional callback for when the stream is finished", "optional": true } ] }, { "params": [ { "name": "chunk", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Call this method when no more data will be written to the stream. If\nsupplied, the callback is attached as a listener on the 'finish' event.\n\n

\n

Calling [write()][] after calling [end()][] will raise an error.\n\n

\n
// write 'hello, ' and then end with 'world!'\nvar file = fs.createWriteStream('example.txt');\nfile.write('hello, ');\nfile.end('world!');\n// writing more now is not allowed!
\n" }, { "textRaw": "writable.setDefaultEncoding(encoding)", "type": "method", "name": "setDefaultEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The new default encoding ", "name": "encoding", "type": "String", "desc": "The new default encoding" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Sets the default encoding for a writable stream.\n\n

\n" }, { "textRaw": "writable.uncork()", "type": "method", "name": "uncork", "desc": "

Flush all data, buffered since .cork() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "signatures": [ { "return": { "textRaw": "Returns: {Boolean} True if the data was handled completely. ", "name": "return", "type": "Boolean", "desc": "True if the data was handled completely." }, "params": [ { "textRaw": "`chunk` {String | Buffer} The data to write ", "name": "chunk", "type": "String | Buffer", "desc": "The data to write" }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Callback for when this chunk of data is flushed ", "name": "callback", "type": "Function", "desc": "Callback for when this chunk of data is flushed", "optional": true } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This method writes some data to the underlying system, and calls the\nsupplied callback once the data has been fully handled.\n\n

\n

The return value indicates if you should continue writing right now.\nIf the data had to be buffered internally, then it will return\nfalse. Otherwise, it will return true.\n\n

\n

This return value is strictly advisory. You MAY continue to write,\neven if it returns false. However, writes will be buffered in\nmemory, so it is best not to do this excessively. Instead, wait for\nthe 'drain' event before writing more data.\n\n\n

\n" } ] } ], "miscs": [ { "textRaw": "API for Stream Consumers", "name": "API for Stream Consumers", "type": "misc", "desc": "

Streams can be either [Readable][], [Writable][], or both ([Duplex][]).\n\n

\n

All streams are EventEmitters, but they also have other custom methods\nand properties depending on whether they are Readable, Writable, or\nDuplex.\n\n

\n

If a stream is both Readable and Writable, then it implements all of\nthe methods and events below. So, a [Duplex][] or [Transform][] stream is\nfully described by this API, though their implementation may be\nsomewhat different.\n\n

\n

It is not necessary to implement Stream interfaces in order to consume\nstreams in your programs. If you are implementing streaming\ninterfaces in your own program, please also refer to\n[API for Stream Implementors][] below.\n\n

\n

Almost all Node.js programs, no matter how simple, use Streams in some\nway. Here is an example of using Streams in an Node.js program:\n\n

\n
const http = require('http');\n\nvar server = http.createServer( (req, res) => {\n  // req is an http.IncomingMessage, which is a Readable Stream\n  // res is an http.ServerResponse, which is a Writable Stream\n\n  var body = '';\n  // we want to get the data as utf8 strings\n  // If you don't set an encoding, then you'll get Buffer objects\n  req.setEncoding('utf8');\n\n  // Readable streams emit 'data' events once a listener is added\n  req.on('data', (chunk) => {\n    body += chunk;\n  });\n\n  // the end event tells you that you have entire body\n  req.on('end', () => {\n    try {\n      var data = JSON.parse(body);\n    } catch (er) {\n      // uh oh!  bad json!\n      res.statusCode = 400;\n      return res.end(`error: ${er.message}`);\n    }\n\n    // write back something interesting to the user:\n    res.write(typeof data);\n    res.end();\n  });\n});\n\nserver.listen(1337);\n\n// $ curl localhost:1337 -d '{}'\n// object\n// $ curl localhost:1337 -d '"foo"'\n// string\n// $ curl localhost:1337 -d 'not json'\n// error: Unexpected token o
\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

Duplex streams are streams that implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Duplex streams include:\n\n

\n
    \n
  • [tcp sockets][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

The Readable stream interface is the abstraction for a source of\ndata that you are reading from. In other words, data comes out of a\nReadable stream.\n\n

\n

A Readable stream will not start emitting data until you indicate that\nyou are ready to receive it.\n\n

\n

Readable streams have two "modes": a flowing mode and a paused\nmode. When in flowing mode, data is read from the underlying system\nand provided to your program as fast as possible. In paused mode, you\nmust explicitly call stream.read() to get chunks of data out.\nStreams start out in paused mode.\n\n

\n

Note: If no data event handlers are attached, and there are no\n[pipe()][] destinations, and the stream is switched into flowing\nmode, then data will be lost.\n\n

\n

You can switch to flowing mode by doing any of the following:\n\n

\n
    \n
  • Adding a ['data'][] event handler to listen for data.
  • \n
  • Calling the [resume()][] method to explicitly open the flow.
  • \n
  • Calling the [pipe()][] method to send the data to a [Writable][].
  • \n
\n

You can switch back to paused mode by doing either of the following:\n\n

\n
    \n
  • If there are no pipe destinations, by calling the [pause()][]\nmethod.
  • \n
  • If there are pipe destinations, by removing any ['data'][] event\nhandlers, and removing all pipe destinations by calling the\n[unpipe()][] method.
  • \n
\n

Note that, for backwards compatibility reasons, removing 'data'\nevent handlers will not automatically pause the stream. Also, if\nthere are piped destinations, then calling pause() will not\nguarantee that the stream will remain paused once those\ndestinations drain and ask for more data.\n\n

\n

Examples of readable streams include:\n\n

\n
    \n
  • [http responses, on the client][]
  • \n
  • [http requests, on the server][]
  • \n
  • [fs read streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdout and stderr][]
  • \n
  • [process.stdin][]
  • \n
\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the stream and any of its underlying resources (a file\ndescriptor, for example) have been closed. The event indicates that\nno more events will be emitted, and no further computation will occur.\n\n

\n

Not all streams will emit the 'close' event.\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Attaching a 'data' event listener to a stream that has not been\nexplicitly paused will switch the stream into flowing mode. Data will\nthen be passed as soon as it is available.\n\n

\n

If you just want to get all the data out of the stream as fast as\npossible, this is the best way to do so.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});
\n" }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

This event fires when there will be no more data to read.\n\n

\n

Note that the 'end' event will not fire unless the data is\ncompletely consumed. This can be done by switching into flowing mode,\nor by calling read() repeatedly until you get to the end.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});\nreadable.on('end', () => {\n  console.log('there will be no more data.');\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error receiving data.\n\n

\n" }, { "textRaw": "Event: 'readable'", "type": "event", "name": "readable", "desc": "

When a chunk of data can be read from the stream, it will emit a\n'readable' event.\n\n

\n

In some cases, listening for a 'readable' event will cause some data\nto be read into the internal buffer from the underlying system, if it\nhadn't already.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  // there is some data to read now\n});
\n

Once the internal buffer is drained, a 'readable' event will fire\nagain when more data is available.\n\n

\n

The 'readable' event is not emitted in the "flowing" mode with the\nsole exception of the last one, on end-of-stream.\n\n

\n

The 'readable' event indicates that the stream has new information:\neither new data is available or the end of the stream has been reached.\nIn the former case, .read() will return that data. In the latter case,\n.read() will return null. For instance, in the following example, foo.txt\nis an empty file:\n\n

\n
const fs = require('fs');\nvar rr = fs.createReadStream('foo.txt');\nrr.on('readable', () => {\n  console.log('readable:', rr.read());\n});\nrr.on('end', () => {\n  console.log('end');\n});
\n

The output of running this script is:\n\n

\n
bash-3.2$ node test.js\nreadable: null\nend
\n", "params": [] } ], "methods": [ { "textRaw": "readable.isPaused()", "type": "method", "name": "isPaused", "signatures": [ { "return": { "textRaw": "Return: `Boolean` ", "name": "return", "desc": "`Boolean`" }, "params": [] }, { "params": [] } ], "desc": "

This method returns whether or not the readable has been explicitly\npaused by client code (using readable.pause() without a corresponding\nreadable.resume()).\n\n

\n
var readable = new stream.Readable\n\nreadable.isPaused() // === false\nreadable.pause()\nreadable.isPaused() // === true\nreadable.resume()\nreadable.isPaused() // === false
\n" }, { "textRaw": "readable.pause()", "type": "method", "name": "pause", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause a stream in flowing mode to stop emitting\n'data' events, switching out of flowing mode. Any data that becomes\navailable will remain in the internal buffer.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n  readable.pause();\n  console.log('there will be no more data for 1 second');\n  setTimeout(() => {\n    console.log('now data will start flowing again');\n    readable.resume();\n  }, 1000);\n});
\n" }, { "textRaw": "readable.pipe(destination[, options])", "type": "method", "name": "pipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} The destination for writing data ", "name": "destination", "type": "[Writable][] Stream", "desc": "The destination for writing data" }, { "textRaw": "`options` {Object} Pipe options ", "options": [ { "textRaw": "`end` {Boolean} End the writer when the reader ends. Default = `true` ", "name": "end", "type": "Boolean", "desc": "End the writer when the reader ends. Default = `true`" } ], "name": "options", "type": "Object", "desc": "Pipe options", "optional": true } ] }, { "params": [ { "name": "destination" }, { "name": "options", "optional": true } ] } ], "desc": "

This method pulls all the data out of a readable stream, and writes it\nto the supplied destination, automatically managing the flow so that\nthe destination is not overwhelmed by a fast readable stream.\n\n

\n

Multiple destinations can be piped to safely.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt'\nreadable.pipe(writable);
\n

This function returns the destination stream, so you can set up pipe\nchains like so:\n\n

\n
var r = fs.createReadStream('file.txt');\nvar z = zlib.createGzip();\nvar w = fs.createWriteStream('file.txt.gz');\nr.pipe(z).pipe(w);
\n

For example, emulating the Unix cat command:\n\n

\n
process.stdin.pipe(process.stdout);
\n

By default [end()][] is called on the destination when the source stream\nemits end, so that destination is no longer writable. Pass { end:\nfalse } as options to keep the destination stream open.\n\n

\n

This keeps writer open so that "Goodbye" can be written at the\nend.\n\n

\n
reader.pipe(writer, { end: false });\nreader.on('end', () => {\n  writer.end('Goodbye\\n');\n});
\n

Note that process.stderr and process.stdout are never closed until\nthe process exits, regardless of the specified options.\n\n

\n" }, { "textRaw": "readable.read([size])", "type": "method", "name": "read", "signatures": [ { "return": { "textRaw": "Return {String | Buffer | null} ", "name": "return", "type": "String | Buffer | null" }, "params": [ { "textRaw": "`size` {Number} Optional argument to specify how much data to read. ", "name": "size", "type": "Number", "desc": "Optional argument to specify how much data to read.", "optional": true } ] }, { "params": [ { "name": "size", "optional": true } ] } ], "desc": "

The read() method pulls some data out of the internal buffer and\nreturns it. If there is no data available, then it will return\nnull.\n\n

\n

If you pass in a size argument, then it will return that many\nbytes. If size bytes are not available, then it will return null,\nunless we've ended, in which case it will return the data remaining\nin the buffer.\n\n

\n

If you do not specify a size argument, then it will return all the\ndata in the internal buffer.\n\n

\n

This method should only be called in paused mode. In flowing mode,\nthis method is called automatically until the internal buffer is\ndrained.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  var chunk;\n  while (null !== (chunk = readable.read())) {\n    console.log('got %d bytes of data', chunk.length);\n  }\n});
\n

If this method returns a data chunk, then it will also trigger the\nemission of a ['data'][] event.\n\n

\n

Note that calling readable.read([size]) after the 'end' event has been\ntriggered will return null. No runtime error will be raised.\n\n

\n" }, { "textRaw": "readable.resume()", "type": "method", "name": "resume", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause the readable stream to resume emitting data\nevents.\n\n

\n

This method will switch the stream into flowing mode. If you do not\nwant to consume the data from a stream, but you do want to get to\nits 'end' event, you can call [readable.resume()][] to open the flow of\ndata.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.resume();\nreadable.on('end', () => {\n  console.log('got to the end, but did not read anything');\n});
\n" }, { "textRaw": "readable.setEncoding(encoding)", "type": "method", "name": "setEncoding", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [ { "textRaw": "`encoding` {String} The encoding to use. ", "name": "encoding", "type": "String", "desc": "The encoding to use." } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Call this function to cause the stream to return strings of the\nspecified encoding instead of Buffer objects. For example, if you do\nreadable.setEncoding('utf8'), then the output data will be\ninterpreted as UTF-8 data, and returned as strings. If you do\nreadable.setEncoding('hex'), then the data will be encoded in\nhexadecimal string format.\n\n

\n

This properly handles multi-byte characters that would otherwise be\npotentially mangled if you simply pulled the Buffers directly and\ncalled buf.toString(encoding) on them. If you want to read the data\nas strings, always use this method.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.setEncoding('utf8');\nreadable.on('data', (chunk) => {\n  assert.equal(typeof chunk, 'string');\n  console.log('got %d characters of string data', chunk.length);\n});
\n" }, { "textRaw": "readable.unpipe([destination])", "type": "method", "name": "unpipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} Optional specific stream to unpipe ", "name": "destination", "type": "[Writable][] Stream", "desc": "Optional specific stream to unpipe", "optional": true } ] }, { "params": [ { "name": "destination", "optional": true } ] } ], "desc": "

This method will remove the hooks set up for a previous pipe() call.\n\n

\n

If the destination is not specified, then all pipes are removed.\n\n

\n

If the destination is specified, but no pipe is set up for it, then\nthis is a no-op.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt',\n// but only for the first second\nreadable.pipe(writable);\nsetTimeout(() => {\n  console.log('stop writing to file.txt');\n  readable.unpipe(writable);\n  console.log('manually close the file stream');\n  writable.end();\n}, 1000);
\n" }, { "textRaw": "readable.unshift(chunk)", "type": "method", "name": "unshift", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} Chunk of data to unshift onto the read queue ", "name": "chunk", "type": "Buffer | String", "desc": "Chunk of data to unshift onto the read queue" } ] }, { "params": [ { "name": "chunk" } ] } ], "desc": "

This is useful in certain cases where a stream is being consumed by a\nparser, which needs to "un-consume" some data that it has\noptimistically pulled out of the source, so that the stream can be\npassed on to some other party.\n\n

\n

Note that stream.unshift(chunk) cannot be called after the 'end' event\nhas been triggered; a runtime error will be raised.\n\n

\n

If you find that you must often call stream.unshift(chunk) in your\nprograms, consider implementing a [Transform][] stream instead. (See API\nfor Stream Implementors, below.)\n\n

\n
// Pull off a header delimited by \\n\\n\n// use unshift() if we get too much\n// Call the callback with (error, header, stream)\nconst StringDecoder = require('string_decoder').StringDecoder;\nfunction parseHeader(stream, callback) {\n  stream.on('error', callback);\n  stream.on('readable', onReadable);\n  var decoder = new StringDecoder('utf8');\n  var header = '';\n  function onReadable() {\n    var chunk;\n    while (null !== (chunk = stream.read())) {\n      var str = decoder.write(chunk);\n      if (str.match(/\\n\\n/)) {\n        // found the header boundary\n        var split = str.split(/\\n\\n/);\n        header += split.shift();\n        var remaining = split.join('\\n\\n');\n        var buf = new Buffer(remaining, 'utf8');\n        if (buf.length)\n          stream.unshift(buf);\n        stream.removeListener('error', callback);\n        stream.removeListener('readable', onReadable);\n        // now the body of the message can be read from the stream.\n        callback(null, header, stream);\n      } else {\n        // still reading the header.\n        header += str;\n      }\n    }\n  }\n}
\n

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not\nend the reading process by resetting the internal reading state of the\nstream. This can cause unexpected results if unshift is called during a\nread (i.e. from within a _read implementation on a custom stream). Following\nthe call to unshift with an immediate stream.push('') will reset the\nreading state appropriately, however it is best to simply avoid calling\nunshift while in the process of performing a read.\n\n

\n" }, { "textRaw": "readable.wrap(stream)", "type": "method", "name": "wrap", "signatures": [ { "params": [ { "textRaw": "`stream` {Stream} An \"old style\" readable stream ", "name": "stream", "type": "Stream", "desc": "An \"old style\" readable stream" } ] }, { "params": [ { "name": "stream" } ] } ], "desc": "

Versions of Node.js prior to v0.10 had streams that did not implement the\nentire Streams API as it is today. (See "Compatibility" below for\nmore information.)\n\n

\n

If you are using an older Node.js library that emits 'data' events and\nhas a [pause()][] method that is advisory only, then you can use the\nwrap() method to create a [Readable][] stream that uses the old stream\nas its data source.\n\n

\n

You will very rarely ever need to call this function, but it exists\nas a convenience for interacting with old Node.js programs and libraries.\n\n

\n

For example:\n\n

\n
const OldReader = require('./old-api-module.js').OldReader;\nconst Readable = require('stream').Readable;\nconst oreader = new OldReader;\nconst myReader = new Readable().wrap(oreader);\n\nmyReader.on('readable', () => {\n  myReader.read(); // etc.\n});
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

Transform streams are [Duplex][] streams where the output is in some way\ncomputed from the input. They implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Transform streams include:\n\n

\n
    \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

The Writable stream interface is an abstraction for a destination\nthat you are writing data to.\n\n

\n

Examples of writable streams include:\n\n

\n
    \n
  • [http requests, on the client][]
  • \n
  • [http responses, on the server][]
  • \n
  • [fs write streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdin][]
  • \n
  • [process.stdout][], [process.stderr][]
  • \n
\n", "events": [ { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

If a [writable.write(chunk)][] call returns false, then the 'drain'\nevent will indicate when it is appropriate to begin writing more data\nto the stream.\n\n

\n
// Write the data to the supplied writable stream one million times.\n// Be attentive to back-pressure.\nfunction writeOneMillionTimes(writer, data, encoding, callback) {\n  var i = 1000000;\n  write();\n  function write() {\n    var ok = true;\n    do {\n      i -= 1;\n      if (i === 0) {\n        // last time!\n        writer.write(data, encoding, callback);\n      } else {\n        // see if we should continue, or wait\n        // don't pass the callback, because we're not done yet.\n        ok = writer.write(data, encoding);\n      }\n    } while (i > 0 && ok);\n    if (i > 0) {\n      // had to stop early!\n      // write some more once it drains\n      writer.once('drain', write);\n    }\n  }\n}
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error when writing or piping data.\n\n

\n" }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

When the [end()][] method has been called, and all data has been flushed\nto the underlying system, this event is emitted.\n\n

\n
var writer = getWritableStreamSomehow();\nfor (var i = 0; i < 100; i ++) {\n  writer.write('hello, #${i}!\\n');\n}\nwriter.end('this is the end\\n');\nwriter.on('finish', () => {\n  console.error('all writes are now complete.');\n});
\n", "params": [] }, { "textRaw": "Event: 'pipe'", "type": "event", "name": "pipe", "params": [], "desc": "

This is emitted whenever the pipe() method is called on a readable\nstream, adding this writable to its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('pipe', (src) => {\n  console.error('something is piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);
\n" }, { "textRaw": "Event: 'unpipe'", "type": "event", "name": "unpipe", "params": [], "desc": "

This is emitted whenever the [unpipe()][] method is called on a\nreadable stream, removing this writable from its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('unpipe', (src) => {\n  console.error('something has stopped piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);\nreader.unpipe(writer);
\n" } ], "methods": [ { "textRaw": "writable.cork()", "type": "method", "name": "cork", "desc": "

Forces buffering of all writes.\n\n

\n

Buffered data will be flushed either at .uncork() or at .end() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.end([chunk][, encoding][, callback])", "type": "method", "name": "end", "signatures": [ { "params": [ { "textRaw": "`chunk` {String | Buffer} Optional data to write ", "name": "chunk", "type": "String | Buffer", "desc": "Optional data to write", "optional": true }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Optional callback for when the stream is finished ", "name": "callback", "type": "Function", "desc": "Optional callback for when the stream is finished", "optional": true } ] }, { "params": [ { "name": "chunk", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Call this method when no more data will be written to the stream. If\nsupplied, the callback is attached as a listener on the 'finish' event.\n\n

\n

Calling [write()][] after calling [end()][] will raise an error.\n\n

\n
// write 'hello, ' and then end with 'world!'\nvar file = fs.createWriteStream('example.txt');\nfile.write('hello, ');\nfile.end('world!');\n// writing more now is not allowed!
\n" }, { "textRaw": "writable.setDefaultEncoding(encoding)", "type": "method", "name": "setDefaultEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The new default encoding ", "name": "encoding", "type": "String", "desc": "The new default encoding" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Sets the default encoding for a writable stream.\n\n

\n" }, { "textRaw": "writable.uncork()", "type": "method", "name": "uncork", "desc": "

Flush all data, buffered since .cork() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "signatures": [ { "return": { "textRaw": "Returns: {Boolean} True if the data was handled completely. ", "name": "return", "type": "Boolean", "desc": "True if the data was handled completely." }, "params": [ { "textRaw": "`chunk` {String | Buffer} The data to write ", "name": "chunk", "type": "String | Buffer", "desc": "The data to write" }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Callback for when this chunk of data is flushed ", "name": "callback", "type": "Function", "desc": "Callback for when this chunk of data is flushed", "optional": true } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This method writes some data to the underlying system, and calls the\nsupplied callback once the data has been fully handled.\n\n

\n

The return value indicates if you should continue writing right now.\nIf the data had to be buffered internally, then it will return\nfalse. Otherwise, it will return true.\n\n

\n

This return value is strictly advisory. You MAY continue to write,\neven if it returns false. However, writes will be buffered in\nmemory, so it is best not to do this excessively. Instead, wait for\nthe 'drain' event before writing more data.\n\n\n

\n" } ] } ] }, { "textRaw": "API for Stream Implementors", "name": "API for Stream Implementors", "type": "misc", "desc": "

To implement any sort of stream, the pattern is the same:\n\n

\n
    \n
  1. Extend the appropriate parent class in your own subclass. (The\n[util.inherits][] method is particularly helpful for this.)
  2. \n
  3. Call the appropriate parent class constructor in your constructor,\nto be sure that the internal mechanisms are set up properly.
  4. \n
  5. Implement one or more specific methods, as detailed below.
  6. \n
\n

The class to extend and the method(s) to implement depend on the sort\nof stream class you are writing:\n\n

\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n

Use-case

\n
\n

Class

\n
\n

Method(s) to implement

\n
\n

Reading only

\n
\n

Readable

\n
\n

[_read][]

\n
\n

Writing only

\n
\n

Writable

\n
\n

[_write][], [_writev][]

\n
\n

Reading and writing

\n
\n

Duplex

\n
\n

[_read][], [_write][], [_writev][]

\n
\n

Operate on written data, then read the result

\n
\n

Transform

\n
\n

[_transform][], [_flush][]

\n
\n\n

In your implementation code, it is very important to never call the\nmethods described in [API for Stream Consumers][] above. Otherwise, you\ncan potentially cause adverse side effects in programs that consume\nyour streaming interfaces.\n\n

\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

A "duplex" stream is one that is both Readable and Writable, such as a\nTCP socket connection.\n\n

\n

Note that stream.Duplex is an abstract class designed to be extended\nwith an underlying implementation of the _read(size) and\n[_write(chunk, encoding, callback)][] methods as you would with a\nReadable or Writable stream class.\n\n

\n

Since JavaScript doesn't have multiple prototypal inheritance, this\nclass prototypally inherits from Readable, and then parasitically from\nWritable. It is thus up to the user to implement both the lowlevel\n_read(n) method as well as the lowlevel\n[_write(chunk, encoding, callback)][] method on extension duplex classes.\n\n

\n", "methods": [ { "textRaw": "new stream.Duplex(options)", "type": "method", "name": "Duplex", "signatures": [ { "params": [ { "textRaw": "`options` {Object} Passed to both Writable and Readable constructors. Also has the following fields: ", "options": [ { "textRaw": "`allowHalfOpen` {Boolean} Default=true. If set to `false`, then the stream will automatically end the readable side when the writable side ends and vice versa. ", "name": "allowHalfOpen", "type": "Boolean", "desc": "Default=true. If set to `false`, then the stream will automatically end the readable side when the writable side ends and vice versa." }, { "textRaw": "`readableObjectMode` {Boolean} Default=false. Sets `objectMode` for readable side of the stream. Has no effect if `objectMode` is `true`. ", "name": "readableObjectMode", "type": "Boolean", "desc": "Default=false. Sets `objectMode` for readable side of the stream. Has no effect if `objectMode` is `true`." }, { "textRaw": "`writableObjectMode` {Boolean} Default=false. Sets `objectMode` for writable side of the stream. Has no effect if `objectMode` is `true`. ", "name": "writableObjectMode", "type": "Boolean", "desc": "Default=false. Sets `objectMode` for writable side of the stream. Has no effect if `objectMode` is `true`." } ], "name": "options", "type": "Object", "desc": "Passed to both Writable and Readable constructors. Also has the following fields:" } ] }, { "params": [ { "name": "options" } ] } ], "desc": "

In classes that extend the Duplex class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" } ] }, { "textRaw": "Class: stream.PassThrough", "type": "class", "name": "stream.PassThrough", "desc": "

This is a trivial implementation of a [Transform][] stream that simply\npasses the input bytes across to the output. Its purpose is mainly\nfor examples and testing, but there are occasionally use cases where\nit can come in handy as a building block for novel sorts of streams.\n\n

\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

stream.Readable is an abstract class designed to be extended with an\nunderlying implementation of the [_read(size)][] method.\n\n

\n

Please see above under [API for Stream Consumers][] for how to consume\nstreams in your programs. What follows is an explanation of how to\nimplement Readable streams in your programs.\n\n

\n", "methods": [ { "textRaw": "new stream.Readable([options])", "type": "method", "name": "Readable", "signatures": [ { "params": [ { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`highWaterMark` {Number} The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for `objectMode` streams ", "name": "highWaterMark", "type": "Number", "desc": "The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for `objectMode` streams" }, { "textRaw": "`encoding` {String} If specified, then buffers will be decoded to strings using the specified encoding. Default=null ", "name": "encoding", "type": "String", "desc": "If specified, then buffers will be decoded to strings using the specified encoding. Default=null" }, { "textRaw": "`objectMode` {Boolean} Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false ", "name": "objectMode", "type": "Boolean", "desc": "Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Readable class, make sure to call the\nReadable constructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "readable.\\_read(size)", "type": "method", "name": "\\_read", "signatures": [ { "params": [ { "textRaw": "`size` {Number} Number of bytes to read asynchronously ", "name": "size", "type": "Number", "desc": "Number of bytes to read asynchronously" } ] }, { "params": [ { "name": "size" } ] } ], "desc": "

Note: Implement this method, but do NOT call it directly.\n\n

\n

This method is prefixed with an underscore because it is internal to the\nclass that defines it and should only be called by the internal Readable\nclass methods. All Readable stream implementations must provide a _read\nmethod to fetch data from the underlying resource.\n\n

\n

When _read is called, if data is available from the resource, _read should\nstart pushing that data into the read queue by calling this.push(dataChunk).\n_read should continue reading from the resource and pushing data until push\nreturns false, at which point it should stop reading from the resource. Only\nwhen _read is called again after it has stopped should it start reading\nmore data from the resource and pushing that data onto the queue.\n\n

\n

Note: once the _read() method is called, it will not be called again until\nthe push method is called.\n\n

\n

The size argument is advisory. Implementations where a "read" is a\nsingle call that returns data can use this to know how much data to\nfetch. Implementations where that is not relevant, such as TCP or\nTLS, may ignore this argument, and simply provide data whenever it\nbecomes available. There is no need, for example to "wait" until\nsize bytes are available before calling [stream.push(chunk)][].\n\n

\n" } ], "examples": [ { "textRaw": "readable.push(chunk[, encoding])", "type": "example", "name": "push", "signatures": [ { "return": { "textRaw": "return {Boolean} Whether or not more pushes should be performed ", "name": "return", "type": "Boolean", "desc": "Whether or not more pushes should be performed" }, "params": [ { "textRaw": "`chunk` {Buffer | null | String} Chunk of data to push into the read queue ", "name": "chunk", "type": "Buffer | null | String", "desc": "Chunk of data to push into the read queue" }, { "textRaw": "`encoding` {String} Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'` ", "name": "encoding", "type": "String", "desc": "Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'`", "optional": true } ] } ], "desc": "

Note: This method should be called by Readable implementors, NOT\nby consumers of Readable streams.\n\n

\n

If a value other than null is passed, The push() method adds a chunk of data\ninto the queue for subsequent stream processors to consume. If null is\npassed, it signals the end of the stream (EOF), after which no more data\ncan be written.\n\n

\n

The data added with push can be pulled out by calling the read() method\nwhen the 'readable' event fires.\n\n

\n

This API is designed to be as flexible as possible. For example,\nyou may be wrapping a lower-level source which has some sort of\npause/resume mechanism, and a data callback. In those cases, you\ncould wrap the low-level source object by doing something like this:\n\n

\n
// source is an object with readStop() and readStart() methods,\n// and an `ondata` member that gets called when it has data, and\n// an `onend` member that gets called when the data is over.\n\nutil.inherits(SourceWrapper, Readable);\n\nfunction SourceWrapper(options) {\n  Readable.call(this, options);\n\n  this._source = getLowlevelSourceObject();\n  var self = this;\n\n  // Every time there's data, we push it into the internal buffer.\n  this._source.ondata = function(chunk) {\n    // if push() returns false, then we need to stop reading from source\n    if (!self.push(chunk))\n      self._source.readStop();\n  };\n\n  // When the source ends, we push the EOF-signaling `null` chunk\n  this._source.onend = function() {\n    self.push(null);\n  };\n}\n\n// _read will be called when the stream wants to pull more data in\n// the advisory size argument is ignored in this case.\nSourceWrapper.prototype._read = function(size) {\n  this._source.readStart();\n};
\n

Example: A Counting Stream

\n

This is a basic example of a Readable stream. It emits the numerals\nfrom 1 to 1,000,000 in ascending order, and then ends.\n\n

\n
const Readable = require('stream').Readable;\nconst util = require('util');\nutil.inherits(Counter, Readable);\n\nfunction Counter(opt) {\n  Readable.call(this, opt);\n  this._max = 1000000;\n  this._index = 1;\n}\n\nCounter.prototype._read = function() {\n  var i = this._index++;\n  if (i > this._max)\n    this.push(null);\n  else {\n    var str = '' + i;\n    var buf = new Buffer(str, 'ascii');\n    this.push(buf);\n  }\n};
\n

Example: SimpleProtocol v1 (Sub-optimal)

\n

This is similar to the parseHeader function described above, but\nimplemented as a custom stream. Also, note that this implementation\ndoes not convert the incoming data to a string.\n\n

\n

However, this would be better implemented as a [Transform][] stream. See\nbelow for a better implementation.\n\n

\n
// A parser for a simple data protocol.\n// The "header" is a JSON object, followed by 2 \\n characters, and\n// then a message body.\n//\n// NOTE: This can be done more simply as a Transform stream!\n// Using Readable directly for this is sub-optimal.  See the\n// alternative example below under the Transform section.\n\nconst Readable = require('stream').Readable;\nconst util = require('util');\n\nutil.inherits(SimpleProtocol, Readable);\n\nfunction SimpleProtocol(source, options) {\n  if (!(this instanceof SimpleProtocol))\n    return new SimpleProtocol(source, options);\n\n  Readable.call(this, options);\n  this._inBody = false;\n  this._sawFirstCr = false;\n\n  // source is a readable stream, such as a socket or file\n  this._source = source;\n\n  var self = this;\n  source.on('end', () => {\n    self.push(null);\n  });\n\n  // give it a kick whenever the source is readable\n  // read(0) will not consume any bytes\n  source.on('readable', () => {\n    self.read(0);\n  });\n\n  this._rawHeader = [];\n  this.header = null;\n}\n\nSimpleProtocol.prototype._read = function(n) {\n  if (!this._inBody) {\n    var chunk = this._source.read();\n\n    // if the source doesn't have data, we don't have data yet.\n    if (chunk === null)\n      return this.push('');\n\n    // check if the chunk has a \\n\\n\n    var split = -1;\n    for (var i = 0; i < chunk.length; i++) {\n      if (chunk[i] === 10) { // '\\n'\n        if (this._sawFirstCr) {\n          split = i;\n          break;\n        } else {\n          this._sawFirstCr = true;\n        }\n      } else {\n        this._sawFirstCr = false;\n      }\n    }\n\n    if (split === -1) {\n      // still waiting for the \\n\\n\n      // stash the chunk, and try again.\n      this._rawHeader.push(chunk);\n      this.push('');\n    } else {\n      this._inBody = true;\n      var h = chunk.slice(0, split);\n      this._rawHeader.push(h);\n      var header = Buffer.concat(this._rawHeader).toString();\n      try {\n        this.header = JSON.parse(header);\n      } catch (er) {\n        this.emit('error', new Error('invalid simple protocol data'));\n        return;\n      }\n      // now, because we got some extra data, unshift the rest\n      // back into the read queue so that our consumer will see it.\n      var b = chunk.slice(split);\n      this.unshift(b);\n      // calling unshift by itself does not reset the reading state\n      // of the stream; since we're inside _read, doing an additional\n      // push('') will reset the state appropriately.\n      this.push('');\n\n      // and let them know that we are done parsing the header.\n      this.emit('header', this.header);\n    }\n  } else {\n    // from there on, just provide the data to our consumer.\n    // careful not to push(null), since that would indicate EOF.\n    var chunk = this._source.read();\n    if (chunk) this.push(chunk);\n  }\n};\n\n// Usage:\n// var parser = new SimpleProtocol(source);\n// Now parser is a readable stream that will emit 'header'\n// with the parsed header data.
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

A "transform" stream is a duplex stream where the output is causally\nconnected in some way to the input, such as a [zlib][] stream or a\n[crypto][] stream.\n\n

\n

There is no requirement that the output be the same size as the input,\nthe same number of chunks, or arrive at the same time. For example, a\nHash stream will only ever have a single chunk of output which is\nprovided when the input is ended. A zlib stream will produce output\nthat is either much smaller or much larger than its input.\n\n

\n

Rather than implement the [_read()][] and [_write()][] methods, Transform\nclasses must implement the _transform() method, and may optionally\nalso implement the _flush() method. (See below.)\n\n

\n", "methods": [ { "textRaw": "new stream.Transform([options])", "type": "method", "name": "Transform", "signatures": [ { "params": [ { "textRaw": "`options` {Object} Passed to both Writable and Readable constructors. ", "name": "options", "type": "Object", "desc": "Passed to both Writable and Readable constructors.", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Transform class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "transform.\\_flush(callback)", "type": "method", "name": "\\_flush", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done flushing any remaining data. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done flushing any remaining data." } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It MAY be implemented\nby child classes, and if so, will be called by the internal Transform\nclass methods only.\n\n

\n

In some cases, your transform operation may need to emit a bit more\ndata at the end of the stream. For example, a Zlib compression\nstream will store up some internal state so that it can optimally\ncompress the output. At the end, however, it needs to do the best it\ncan with what is left, so that the data will be complete.\n\n

\n

In those cases, you can implement a _flush method, which will be\ncalled at the very end, after all the written data is consumed, but\nbefore emitting end to signal the end of the readable side. Just\nlike with _transform, call transform.push(chunk) zero or more\ntimes, as appropriate, and call callback when the flush operation is\ncomplete.\n\n

\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n" }, { "textRaw": "transform.\\_transform(chunk, encoding, callback)", "type": "method", "name": "\\_transform", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. ", "name": "chunk", "type": "Buffer | String", "desc": "The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`." }, { "textRaw": "`encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. ", "name": "encoding", "type": "String", "desc": "If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument and data) when you are done processing the supplied chunk. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument and data) when you are done processing the supplied chunk." } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding" }, { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It should be\nimplemented by child classes, and called by the internal Transform\nclass methods only.\n\n

\n

All Transform stream implementations must provide a _transform\nmethod to accept input and produce output.\n\n

\n

_transform should do whatever has to be done in this specific\nTransform class, to handle the bytes being written, and pass them off\nto the readable portion of the interface. Do asynchronous I/O,\nprocess things, and so on.\n\n

\n

Call transform.push(outputChunk) 0 or more times to generate output\nfrom this input chunk, depending on how much data you want to output\nas a result of this chunk.\n\n

\n

Call the callback function only when the current chunk is completely\nconsumed. Note that there may or may not be output as a result of any\nparticular input chunk. If you supply a second argument to the callback\nit will be passed to the push method. In other words the following are\nequivalent:\n\n

\n
transform.prototype._transform = function (data, encoding, callback) {\n  this.push(data);\n  callback();\n};\n\ntransform.prototype._transform = function (data, encoding, callback) {\n  callback(null, data);\n};
\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n

Example: SimpleProtocol parser v2

\n

The example above of a simple protocol parser can be implemented\nsimply by using the higher level [Transform][] stream class, similar to\nthe parseHeader and SimpleProtocol v1 examples above.\n\n

\n

In this example, rather than providing the input as an argument, it\nwould be piped into the parser, which is a more idiomatic Node.js stream\napproach.\n\n

\n
const util = require('util');\nconst Transform = require('stream').Transform;\nutil.inherits(SimpleProtocol, Transform);\n\nfunction SimpleProtocol(options) {\n  if (!(this instanceof SimpleProtocol))\n    return new SimpleProtocol(options);\n\n  Transform.call(this, options);\n  this._inBody = false;\n  this._sawFirstCr = false;\n  this._rawHeader = [];\n  this.header = null;\n}\n\nSimpleProtocol.prototype._transform = function(chunk, encoding, done) {\n  if (!this._inBody) {\n    // check if the chunk has a \\n\\n\n    var split = -1;\n    for (var i = 0; i < chunk.length; i++) {\n      if (chunk[i] === 10) { // '\\n'\n        if (this._sawFirstCr) {\n          split = i;\n          break;\n        } else {\n          this._sawFirstCr = true;\n        }\n      } else {\n        this._sawFirstCr = false;\n      }\n    }\n\n    if (split === -1) {\n      // still waiting for the \\n\\n\n      // stash the chunk, and try again.\n      this._rawHeader.push(chunk);\n    } else {\n      this._inBody = true;\n      var h = chunk.slice(0, split);\n      this._rawHeader.push(h);\n      var header = Buffer.concat(this._rawHeader).toString();\n      try {\n        this.header = JSON.parse(header);\n      } catch (er) {\n        this.emit('error', new Error('invalid simple protocol data'));\n        return;\n      }\n      // and let them know that we are done parsing the header.\n      this.emit('header', this.header);\n\n      // now, because we got some extra data, emit this first.\n      this.push(chunk.slice(split));\n    }\n  } else {\n    // from there on, just provide the data to our consumer as-is.\n    this.push(chunk);\n  }\n  done();\n};\n\n// Usage:\n// var parser = new SimpleProtocol();\n// source.pipe(parser)\n// Now parser is a readable stream that will emit 'header'\n// with the parsed header data.
\n" } ], "modules": [ { "textRaw": "Events: 'finish' and 'end'", "name": "events:_'finish'_and_'end'", "desc": "

The ['finish'][] and ['end'][] events are from the parent Writable\nand Readable classes respectively. The 'finish' event is fired after\n.end() is called and all chunks have been processed by _transform,\nend is fired after all data has been output which is after the callback\nin _flush has been called.\n\n

\n", "type": "module", "displayName": "Events: 'finish' and 'end'" } ] }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

stream.Writable is an abstract class designed to be extended with an\nunderlying implementation of the [_write(chunk, encoding, callback)][] method.\n\n

\n

Please see above under [API for Stream Consumers][] for how to consume\nwritable streams in your programs. What follows is an explanation of\nhow to implement Writable streams in your programs.\n\n

\n", "methods": [ { "textRaw": "new stream.Writable([options])", "type": "method", "name": "Writable", "signatures": [ { "params": [ { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`highWaterMark` {Number} Buffer level when [`write()`][] starts returning false. Default=16kb, or 16 for `objectMode` streams ", "name": "highWaterMark", "type": "Number", "desc": "Buffer level when [`write()`][] starts returning false. Default=16kb, or 16 for `objectMode` streams" }, { "textRaw": "`decodeStrings` {Boolean} Whether or not to decode strings into Buffers before passing them to [`_write()`][]. Default=true ", "name": "decodeStrings", "type": "Boolean", "desc": "Whether or not to decode strings into Buffers before passing them to [`_write()`][]. Default=true" }, { "textRaw": "`objectMode` {Boolean} Whether or not the `write(anyObj)` is a valid operation. If set you can write arbitrary data instead of only `Buffer` / `String` data. Default=false ", "name": "objectMode", "type": "Boolean", "desc": "Whether or not the `write(anyObj)` is a valid operation. If set you can write arbitrary data instead of only `Buffer` / `String` data. Default=false" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Writable class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "writable.\\_write(chunk, encoding, callback)", "type": "method", "name": "\\_write", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. ", "name": "chunk", "type": "Buffer | String", "desc": "The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`." }, { "textRaw": "`encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. ", "name": "encoding", "type": "String", "desc": "If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunk. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done processing the supplied chunk." } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding" }, { "name": "callback" } ] } ], "desc": "

All Writable stream implementations must provide a [_write()][]\nmethod to send data to the underlying resource.\n\n

\n

Note: This function MUST NOT be called directly. It should be\nimplemented by child classes, and called by the internal Writable\nclass methods only.\n\n

\n

Call the callback using the standard callback(error) pattern to\nsignal that the write completed successfully or with an error.\n\n

\n

If the decodeStrings flag is set in the constructor options, then\nchunk may be a string rather than a Buffer, and encoding will\nindicate the sort of string that it is. This is to support\nimplementations that have an optimized handling for certain string\ndata encodings. If you do not explicitly set the decodeStrings\noption to false, then you can safely ignore the encoding argument,\nand assume that chunk will always be a Buffer.\n\n

\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n" }, { "textRaw": "writable.\\_writev(chunks, callback)", "type": "method", "name": "\\_writev", "signatures": [ { "params": [ { "textRaw": "`chunks` {Array} The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`. ", "name": "chunks", "type": "Array", "desc": "The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunks. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done processing the supplied chunks." } ] }, { "params": [ { "name": "chunks" }, { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It may be\nimplemented by child classes, and called by the internal Writable\nclass methods only.\n\n

\n

This function is completely optional to implement. In most cases it is\nunnecessary. If implemented, it will be called with all the chunks\nthat are buffered in the write queue.\n\n\n

\n" } ] } ] }, { "textRaw": "Simplified Constructor API", "name": "Simplified Constructor API", "type": "misc", "desc": "

In simple cases there is now the added benefit of being able to construct a stream without inheritance.\n\n

\n

This can be done by passing the appropriate methods as constructor options:\n\n

\n

Examples:\n\n

\n", "miscs": [ { "textRaw": "Duplex", "name": "duplex", "desc": "
var duplex = new stream.Duplex({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  },\n  write: function(chunk, encoding, next) {\n    // sets this._write under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});\n\n// or\n\nvar duplex = new stream.Duplex({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  },\n  writev: function(chunks, next) {\n    // sets this._writev under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});
\n", "type": "misc", "displayName": "Duplex" }, { "textRaw": "Readable", "name": "readable", "desc": "
var readable = new stream.Readable({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  }\n});
\n", "type": "misc", "displayName": "Readable" }, { "textRaw": "Transform", "name": "transform", "desc": "
var transform = new stream.Transform({\n  transform: function(chunk, encoding, next) {\n    // sets this._transform under the hood\n\n    // generate output as many times as needed\n    // this.push(chunk);\n\n    // call when the current chunk is consumed\n    next();\n  },\n  flush: function(done) {\n    // sets this._flush under the hood\n\n    // generate output as many times as needed\n    // this.push(chunk);\n\n    done();\n  }\n});
\n", "type": "misc", "displayName": "Transform" }, { "textRaw": "Writable", "name": "writable", "desc": "
var writable = new stream.Writable({\n  write: function(chunk, encoding, next) {\n    // sets this._write under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});\n\n// or\n\nvar writable = new stream.Writable({\n  writev: function(chunks, next) {\n    // sets this._writev under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});
\n", "type": "misc", "displayName": "Writable" } ] }, { "textRaw": "Streams: Under the Hood", "name": "Streams: Under the Hood", "type": "misc", "miscs": [ { "textRaw": "Buffering", "name": "Buffering", "type": "misc", "desc": "

Both Writable and Readable streams will buffer data on an internal\nobject which can be retrieved from _writableState.getBuffer() or\n_readableState.buffer, respectively.\n\n

\n

The amount of data that will potentially be buffered depends on the\nhighWaterMark option which is passed into the constructor.\n\n

\n

Buffering in Readable streams happens when the implementation calls\n[stream.push(chunk)][]. If the consumer of the Stream does not call\nstream.read(), then the data will sit in the internal queue until it\nis consumed.\n\n

\n

Buffering in Writable streams happens when the user calls\n[stream.write(chunk)][] repeatedly, even when write() returns false.\n\n

\n

The purpose of streams, especially with the pipe() method, is to\nlimit the buffering of data to acceptable levels, so that sources and\ndestinations of varying speed will not overwhelm the available memory.\n\n

\n" }, { "textRaw": "Compatibility with Older Node.js Versions", "name": "Compatibility with Older Node.js Versions", "type": "misc", "desc": "

In versions of Node.js prior to v0.10, the Readable stream interface was\nsimpler, but also less powerful and less useful.\n\n

\n
    \n
  • Rather than waiting for you to call the read() method, 'data'\nevents would start emitting immediately. If you needed to do some\nI/O to decide how to handle data, then you had to store the chunks\nin some kind of buffer so that they would not be lost.
  • \n
  • The [pause()][] method was advisory, rather than guaranteed. This\nmeant that you still had to be prepared to receive 'data' events\neven when the stream was in a paused state.
  • \n
\n

In Node.js v0.10, the Readable class described below was added.\nFor backwards compatibility with older Node.js programs, Readable streams\nswitch into "flowing mode" when a 'data' event handler is added, or\nwhen the [resume()][] method is called. The effect is that, even if\nyou are not using the new read() method and 'readable' event, you\nno longer have to worry about losing 'data' chunks.\n\n

\n

Most programs will continue to function normally. However, this\nintroduces an edge case in the following conditions:\n\n

\n
    \n
  • No ['data'][] event handler is added.
  • \n
  • The [resume()][] method is never called.
  • \n
  • The stream is not piped to any writable destination.
  • \n
\n

For example, consider the following code:\n\n

\n
// WARNING!  BROKEN!\nnet.createServer((socket) => {\n\n  // we add an 'end' method, but never consume the data\n  socket.on('end', () => {\n    // It will never get here.\n    socket.end('I got your message (but didnt read it)\\n');\n  });\n\n}).listen(1337);
\n

In versions of Node.js prior to v0.10, the incoming message data would be\nsimply discarded. However, in Node.js v0.10 and beyond,\nthe socket will remain paused forever.\n\n

\n

The workaround in this situation is to call the resume() method to\nstart the flow of data:\n\n

\n
// Workaround\nnet.createServer((socket) => {\n\n  socket.on('end', () => {\n    socket.end('I got your message (but didnt read it)\\n');\n  });\n\n  // start the flow of data, discarding it.\n  socket.resume();\n\n}).listen(1337);
\n

In addition to new Readable streams switching into flowing mode,\npre-v0.10 style streams can be wrapped in a Readable class using the\nwrap() method.\n\n\n

\n" }, { "textRaw": "Object Mode", "name": "Object Mode", "type": "misc", "desc": "

Normally, Streams operate on Strings and Buffers exclusively.\n\n

\n

Streams that are in object mode can emit generic JavaScript values\nother than Buffers and Strings.\n\n

\n

A Readable stream in object mode will always return a single item from\na call to stream.read(size), regardless of what the size argument\nis.\n\n

\n

A Writable stream in object mode will always ignore the encoding\nargument to stream.write(data, encoding).\n\n

\n

The special value null still retains its special value for object\nmode streams. That is, for object mode readable streams, null as a\nreturn value from stream.read() indicates that there is no more\ndata, and [stream.push(null)][] will signal the end of stream data\n(EOF).\n\n

\n

No streams in Node.js core are object mode streams. This pattern is only\nused by userland streaming libraries.\n\n

\n

You should set objectMode in your stream child class constructor on\nthe options object. Setting objectMode mid-stream is not safe.\n\n

\n

For Duplex streams objectMode can be set exclusively for readable or\nwritable side with readableObjectMode and writableObjectMode\nrespectively. These options can be used to implement parsers and\nserializers with Transform streams.\n\n

\n
const util = require('util');\nconst StringDecoder = require('string_decoder').StringDecoder;\nconst Transform = require('stream').Transform;\nutil.inherits(JSONParseStream, Transform);\n\n// Gets \\n-delimited JSON string data, and emits the parsed objects\nfunction JSONParseStream() {\n  if (!(this instanceof JSONParseStream))\n    return new JSONParseStream();\n\n  Transform.call(this, { readableObjectMode : true });\n\n  this._buffer = '';\n  this._decoder = new StringDecoder('utf8');\n}\n\nJSONParseStream.prototype._transform = function(chunk, encoding, cb) {\n  this._buffer += this._decoder.write(chunk);\n  // split on newlines\n  var lines = this._buffer.split(/\\r?\\n/);\n  // keep the last partial line buffered\n  this._buffer = lines.pop();\n  for (var l = 0; l < lines.length; l++) {\n    var line = lines[l];\n    try {\n      var obj = JSON.parse(line);\n    } catch (er) {\n      this.emit('error', er);\n      return;\n    }\n    // push the parsed object out to the readable consumer\n    this.push(obj);\n  }\n  cb();\n};\n\nJSONParseStream.prototype._flush = function(cb) {\n  // Just handle any leftover\n  var rem = this._buffer.trim();\n  if (rem) {\n    try {\n      var obj = JSON.parse(rem);\n    } catch (er) {\n      this.emit('error', er);\n      return;\n    }\n    // push the parsed object out to the readable consumer\n    this.push(obj);\n  }\n  cb();\n};
\n" }, { "textRaw": "`stream.read(0)`", "name": "`stream.read(0)`", "desc": "

There are some cases where you want to trigger a refresh of the\nunderlying readable stream mechanisms, without actually consuming any\ndata. In that case, you can call stream.read(0), which will always\nreturn null.\n\n

\n

If the internal read buffer is below the highWaterMark, and the\nstream is not currently reading, then calling read(0) will trigger\na low-level _read call.\n\n

\n

There is almost never a need to do this. However, you will see some\ncases in Node.js's internals where this is done, particularly in the\nReadable stream class internals.\n\n

\n", "type": "misc", "displayName": "`stream.read(0)`" }, { "textRaw": "`stream.push('')`", "name": "`stream.push('')`", "desc": "

Pushing a zero-byte string or Buffer (when not in [Object mode][]) has an\ninteresting side effect. Because it is a call to\n[stream.push()][], it will end the reading process. However, it\ndoes not add any data to the readable buffer, so there's nothing for\na user to consume.\n\n

\n

Very rarely, there are cases where you have no data to provide now,\nbut the consumer of your stream (or, perhaps, another bit of your own\ncode) will know when to check again, by calling stream.read(0). In\nthose cases, you may call stream.push('').\n\n

\n

So far, the only use case for this functionality is in the\n[tls.CryptoStream][] class, which is deprecated in Node.js/io.js v1.0. If you\nfind that you have to use stream.push(''), please consider another\napproach, because it almost certainly indicates that something is\nhorribly wrong.\n\n

\n", "type": "misc", "displayName": "`stream.push('')`" } ] } ], "type": "module", "displayName": "Stream" }, { "textRaw": "StringDecoder", "name": "stringdecoder", "stability": 2, "stabilityText": "Stable", "desc": "

To use this module, do require('string_decoder'). StringDecoder decodes a\nbuffer to a string. It is a simple interface to buffer.toString() but provides\nadditional support for utf8.\n\n

\n
const StringDecoder = require('string_decoder').StringDecoder;\nconst decoder = new StringDecoder('utf8');\n\nconst cent = new Buffer([0xC2, 0xA2]);\nconsole.log(decoder.write(cent));\n\nconst euro = new Buffer([0xE2, 0x82, 0xAC]);\nconsole.log(decoder.write(euro));
\n", "classes": [ { "textRaw": "Class: StringDecoder", "type": "class", "name": "StringDecoder", "desc": "

Accepts a single argument, encoding which defaults to 'utf8'.\n\n

\n", "methods": [ { "textRaw": "decoder.end()", "type": "method", "name": "end", "desc": "

Returns any trailing bytes that were left in the buffer.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "decoder.write(buffer)", "type": "method", "name": "write", "desc": "

Returns a decoded string.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] } ] } ], "type": "module", "displayName": "StringDecoder" }, { "textRaw": "Timers", "name": "timers", "stability": 3, "stabilityText": "Locked", "desc": "

All of the timer functions are globals. You do not need to require()\nthis module in order to use them.\n\n

\n", "methods": [ { "textRaw": "clearImmediate(immediateObject)", "type": "method", "name": "clearImmediate", "desc": "

Stops an immediate from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "immediateObject" } ] } ] }, { "textRaw": "clearInterval(intervalObject)", "type": "method", "name": "clearInterval", "desc": "

Stops an interval from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "intervalObject" } ] } ] }, { "textRaw": "clearTimeout(timeoutObject)", "type": "method", "name": "clearTimeout", "desc": "

Prevents a timeout from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "timeoutObject" } ] } ] }, { "textRaw": "ref()", "type": "method", "name": "ref", "desc": "

If you had previously unref()d a timer you can call ref() to explicitly\nrequest the timer hold the program open. If the timer is already refd calling\nref again will have no effect.\n\n

\n

Returns the timer.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "setImmediate(callback[, arg][, ...])", "type": "method", "name": "setImmediate", "desc": "

To schedule the "immediate" execution of callback after I/O events\ncallbacks and before [setTimeout][] and [setInterval][]. Returns an\nimmediateObject for possible use with clearImmediate(). Optionally you\ncan also pass arguments to the callback.\n\n

\n

Callbacks for immediates are queued in the order in which they were created.\nThe entire callback queue is processed every event loop iteration. If you queue\nan immediate from inside an executing callback, that immediate won't fire\nuntil the next event loop iteration.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "setInterval(callback, delay[, arg][, ...])", "type": "method", "name": "setInterval", "desc": "

To schedule the repeated execution of callback every delay milliseconds.\nReturns a intervalObject for possible use with clearInterval(). Optionally\nyou can also pass arguments to the callback.\n\n

\n

To follow browser behavior, when using delays larger than 2147483647\nmilliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the\ndelay.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "delay" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "setTimeout(callback, delay[, arg][, ...])", "type": "method", "name": "setTimeout", "desc": "

To schedule execution of a one-time callback after delay milliseconds. Returns a\ntimeoutObject for possible use with clearTimeout(). Optionally you can\nalso pass arguments to the callback.\n\n

\n

It is important to note that your callback will probably not be called in exactly\ndelay milliseconds - Node.js makes no guarantees about the exact timing of when\nthe callback will fire, nor of the ordering things will fire in. The callback will\nbe called as close as possible to the time specified.\n\n

\n

To follow browser behavior, when using delays larger than 2147483647\nmilliseconds (approximately 25 days) or less than 1, the timeout is executed\nimmediately, as if the delay was set to 1.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "delay" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "unref()", "type": "method", "name": "unref", "desc": "

The opaque value returned by [setTimeout][] and [setInterval][] also has the method\ntimer.unref() which will allow you to create a timer that is active but if\nit is the only item left in the event loop, it won't keep the program running.\nIf the timer is already unrefd calling unref again will have no effect.\n\n

\n

In the case of setTimeout when you unref you create a separate timer that\nwill wakeup the event loop, creating too many of these may adversely effect\nevent loop performance -- use wisely.\n\n

\n

Returns the timer.\n\n

\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "Timers" }, { "textRaw": "TLS (SSL)", "name": "tls_(ssl)", "stability": 2, "stabilityText": "Stable", "desc": "

Use require('tls') to access this module.\n\n

\n

The tls module uses OpenSSL to provide Transport Layer Security and/or\nSecure Socket Layer: encrypted stream communication.\n\n

\n

TLS/SSL is a public/private key infrastructure. Each client and each\nserver must have a private key. A private key is created like this:\n\n

\n
openssl genrsa -out ryans-key.pem 2048
\n

All servers and some clients need to have a certificate. Certificates are public\nkeys signed by a Certificate Authority or self-signed. The first step to\ngetting a certificate is to create a "Certificate Signing Request" (CSR)\nfile. This is done with:\n\n

\n
openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem
\n

To create a self-signed certificate with the CSR, do this:\n\n

\n
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
\n

Alternatively you can send the CSR to a Certificate Authority for signing.\n\n

\n

For Perfect Forward Secrecy, it is required to generate Diffie-Hellman\nparameters:\n\n

\n
openssl dhparam -outform PEM -out dhparam.pem 2048
\n

To create .pfx or .p12, do this:\n\n

\n
openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \\\n    -certfile ca-cert.pem -out agent5.pfx
\n
    \n
  • in: certificate
  • \n
  • inkey: private key
  • \n
  • certfile: all CA certs concatenated in one file like\ncat ca1-cert.pem ca2-cert.pem > ca-cert.pem
  • \n
\n", "miscs": [ { "textRaw": "Client-initiated renegotiation attack mitigation", "name": "Client-initiated renegotiation attack mitigation", "type": "misc", "desc": "

The TLS protocol lets the client renegotiate certain aspects of the TLS session.\nUnfortunately, session renegotiation requires a disproportional amount of\nserver-side resources, which makes it a potential vector for denial-of-service\nattacks.\n\n

\n

To mitigate this, renegotiations are limited to three times every 10 minutes. An\nerror is emitted on the [tls.TLSSocket][] instance when the threshold is\nexceeded. The limits are configurable:\n\n

\n
    \n
  • tls.CLIENT_RENEG_LIMIT: renegotiation limit, default is 3.

    \n
  • \n
  • tls.CLIENT_RENEG_WINDOW: renegotiation window in seconds, default is\n10 minutes.

    \n
  • \n
\n

Don't change the defaults unless you know what you are doing.\n\n

\n

To test your server, connect to it with openssl s_client -connect address:port\nand tap R<CR> (that's the letter R followed by a carriage return) a few\ntimes.\n\n\n

\n" }, { "textRaw": "NPN and SNI", "name": "NPN and SNI", "type": "misc", "desc": "

NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS\nhandshake extensions allowing you:\n\n

\n
    \n
  • NPN - to use one TLS server for multiple protocols (HTTP, SPDY)
  • \n
  • SNI - to use one TLS server for multiple hostnames with different SSL\ncertificates.
  • \n
\n" }, { "textRaw": "Perfect Forward Secrecy", "name": "Perfect Forward Secrecy", "type": "misc", "desc": "

The term "[Forward Secrecy]" or "Perfect Forward Secrecy" describes a feature of\nkey-agreement (i.e. key-exchange) methods. Practically it means that even if the\nprivate key of a (your) server is compromised, communication can only be\ndecrypted by eavesdroppers if they manage to obtain the key-pair specifically\ngenerated for each session.\n\n

\n

This is achieved by randomly generating a key pair for key-agreement on every\nhandshake (in contrary to the same key for all sessions). Methods implementing\nthis technique, thus offering Perfect Forward Secrecy, are called "ephemeral".\n\n

\n

Currently two methods are commonly used to achieve Perfect Forward Secrecy (note\nthe character "E" appended to the traditional abbreviations):\n\n

\n
    \n
  • [DHE] - An ephemeral version of the Diffie Hellman key-agreement protocol.
  • \n
  • [ECDHE] - An ephemeral version of the Elliptic Curve Diffie Hellman\nkey-agreement protocol.
  • \n
\n

Ephemeral methods may have some performance drawbacks, because key generation\nis expensive.\n\n\n

\n" } ], "modules": [ { "textRaw": "Modifying the Default TLS Cipher suite", "name": "modifying_the_default_tls_cipher_suite", "desc": "

Node.js is built with a default suite of enabled and disabled TLS ciphers.\nCurrently, the default cipher suite is:\n\n

\n
ECDHE-RSA-AES128-GCM-SHA256:\nECDHE-ECDSA-AES128-GCM-SHA256:\nECDHE-RSA-AES256-GCM-SHA384:\nECDHE-ECDSA-AES256-GCM-SHA384:\nDHE-RSA-AES128-GCM-SHA256:\nECDHE-RSA-AES128-SHA256:\nDHE-RSA-AES128-SHA256:\nECDHE-RSA-AES256-SHA384:\nDHE-RSA-AES256-SHA384:\nECDHE-RSA-AES256-SHA256:\nDHE-RSA-AES256-SHA256:\nHIGH:\n!aNULL:\n!eNULL:\n!EXPORT:\n!DES:\n!RC4:\n!MD5:\n!PSK:\n!SRP:\n!CAMELLIA
\n

This default can be overriden entirely using the --tls-cipher-list command\nline switch. For instance, the following makes\nECDHE-RSA-AES128-GCM-SHA256:!RC4 the default TLS cipher suite:\n\n

\n
node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
\n

Note that the default cipher suite included within Node.js has been carefully\nselected to reflect current security best practices and risk mitigation.\nChanging the default cipher suite can have a significant impact on the security\nof an application. The --tls-cipher-list switch should by used only if\nabsolutely necessary.\n\n\n

\n", "type": "module", "displayName": "Modifying the Default TLS Cipher suite" } ], "classes": [ { "textRaw": "Class: CryptoStream", "type": "class", "name": "CryptoStream", "stability": 0, "stabilityText": "Deprecated: Use [tls.TLSSocket][] instead.", "desc": "

This is an encrypted stream.\n\n

\n", "properties": [ { "textRaw": "cryptoStream.bytesWritten", "name": "bytesWritten", "desc": "

A proxy to the underlying socket's bytesWritten accessor, this will return\nthe total bytes written to the socket, including the TLS overhead.\n\n\n

\n" } ] }, { "textRaw": "Class: SecurePair", "type": "class", "name": "SecurePair", "desc": "

Returned by tls.createSecurePair.\n\n

\n", "events": [ { "textRaw": "Event: 'secure'", "type": "event", "name": "secure", "desc": "

The event is emitted from the SecurePair once the pair has successfully\nestablished a secure connection.\n\n

\n

Similarly to the checking for the server 'secureConnection' event,\npair.cleartext.authorized should be checked to confirm whether the certificate\nused properly authorized.\n\n\n

\n", "params": [] } ] }, { "textRaw": "Class: tls.Server", "type": "class", "name": "tls.Server", "desc": "

This class is a subclass of net.Server and has the same methods on it.\nInstead of accepting just raw TCP connections, this accepts encrypted\nconnections using TLS or SSL.\n\n

\n", "events": [ { "textRaw": "Event: 'clientError'", "type": "event", "name": "clientError", "desc": "

function (exception, tlsSocket) { }\n\n

\n

When a client connection emits an 'error' event before secure connection is\nestablished - it will be forwarded here.\n\n

\n

tlsSocket is the [tls.TLSSocket][] that the error originated from.\n\n

\n", "params": [] }, { "textRaw": "Event: 'newSession'", "type": "event", "name": "newSession", "desc": "

function (sessionId, sessionData, callback) { }\n\n

\n

Emitted on creation of TLS session. May be used to store sessions in external\nstorage. callback must be invoked eventually, otherwise no data will be\nsent or received from secure connection.\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n", "params": [] }, { "textRaw": "Event: 'OCSPRequest'", "type": "event", "name": "OCSPRequest", "desc": "

function (certificate, issuer, callback) { }\n\n

\n

Emitted when the client sends a certificate status request. You could parse\nserver's current certificate to obtain OCSP url and certificate id, and after\nobtaining OCSP response invoke callback(null, resp), where resp is a\nBuffer instance. Both certificate and issuer are a Buffer\nDER-representations of the primary and issuer's certificates. They could be used\nto obtain OCSP certificate id and OCSP endpoint url.\n\n

\n

Alternatively, callback(null, null) could be called, meaning that there is no\nOCSP response.\n\n

\n

Calling callback(err) will result in a socket.destroy(err) call.\n\n

\n

Typical flow:\n\n

\n
    \n
  1. Client connects to server and sends 'OCSPRequest' to it (via status info\nextension in ClientHello.)
  2. \n
  3. Server receives request and invokes 'OCSPRequest' event listener if present
  4. \n
  5. Server grabs OCSP url from either certificate or issuer and performs an\n[OCSP request] to the CA
  6. \n
  7. Server receives OCSPResponse from CA and sends it back to client via\ncallback argument
  8. \n
  9. Client validates the response and either destroys socket or performs a\nhandshake.
  10. \n
\n

NOTE: issuer could be null, if the certificate is self-signed or if the issuer\nis not in the root certificates list. (You could provide an issuer via ca\noption.)\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n

NOTE: you may want to use some npm module like [asn1.js] to parse the\ncertificates.\n\n

\n", "params": [] }, { "textRaw": "Event: 'resumeSession'", "type": "event", "name": "resumeSession", "desc": "

function (sessionId, callback) { }\n\n

\n

Emitted when client wants to resume previous TLS session. Event listener may\nperform lookup in external storage using given sessionId, and invoke\ncallback(null, sessionData) once finished. If session can't be resumed\n(i.e. doesn't exist in storage) one may call callback(null, null). Calling\ncallback(err) will terminate incoming connection and destroy socket.\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n

Here's an example for using TLS session resumption:\n\n

\n
var tlsSessionStore = {};\nserver.on('newSession', (id, data, cb) => {\n  tlsSessionStore[id.toString('hex')] = data;\n  cb();\n});\nserver.on('resumeSession', (id, cb) => {\n  cb(null, tlsSessionStore[id.toString('hex')] || null);\n});
\n", "params": [] }, { "textRaw": "Event: 'secureConnection'", "type": "event", "name": "secureConnection", "desc": "

function (tlsSocket) {}\n\n

\n

This event is emitted after a new connection has been successfully\nhandshaked. The argument is an instance of [tls.TLSSocket][]. It has all the\ncommon stream methods and events.\n\n

\n

socket.authorized is a boolean value which indicates if the\nclient has verified by one of the supplied certificate authorities for the\nserver. If socket.authorized is false, then\nsocket.authorizationError is set to describe how authorization\nfailed. Implied but worth mentioning: depending on the settings of the TLS\nserver, you unauthorized connections may be accepted.\nsocket.npnProtocol is a string containing selected NPN protocol.\nsocket.servername is a string containing servername requested with\nSNI.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.addContext(hostname, context)", "type": "method", "name": "addContext", "desc": "

Add secure context that will be used if client request's SNI hostname is\nmatching passed hostname (wildcards can be used). context can contain\nkey, cert, ca and/or any other properties from tls.createSecureContext\noptions argument.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "context" } ] } ] }, { "textRaw": "server.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nserver as reported by the operating system. See [net.Server.address()][] for\nmore information.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections. This function is\nasynchronous, the server is finally closed when the server emits a 'close'\nevent. Optionally, you can pass a callback to listen for the 'close' event.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.getTicketKeys()", "type": "method", "name": "getTicketKeys", "desc": "

Returns Buffer instance holding the keys currently used for\nencryption/decryption of the [TLS Session Tickets][]\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.listen(port[, hostname][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

This function is asynchronous. The last parameter callback will be called\nwhen the server has been bound.\n\n

\n

See net.Server for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.setTicketKeys(keys)", "type": "method", "name": "setTicketKeys", "desc": "

Updates the keys for encryption/decryption of the [TLS Session Tickets][].\n\n

\n

NOTE: the buffer should be 48 bytes long. See server ticketKeys option for\nmore information oh how it is going to be used.\n\n

\n

NOTE: the change is effective only for the future server connections. Existing\nor currently pending server connections will use previous keys.\n\n\n

\n", "signatures": [ { "params": [ { "name": "keys" } ] } ] } ], "properties": [ { "textRaw": "server.connections", "name": "connections", "desc": "

The number of concurrent connections on the server.\n\n

\n" }, { "textRaw": "server.maxConnections", "name": "maxConnections", "desc": "

Set this property to reject connections when the server's connection count\ngets high.\n\n

\n" } ] }, { "textRaw": "Class: tls.TLSSocket", "type": "class", "name": "tls.TLSSocket", "desc": "

This is a wrapped version of [net.Socket][] that does transparent encryption\nof written data and all required TLS negotiation.\n\n

\n

This instance implements a duplex [Stream][] interfaces. It has all the\ncommon stream methods and events.\n\n

\n

Methods that return TLS connection meta data (e.g. [getPeerCertificate][] will\nonly return data while the connection is open.\n\n

\n" } ], "methods": [ { "textRaw": "new tls.TLSSocket(socket[, options])", "type": "method", "name": "TLSSocket", "desc": "

Construct a new TLSSocket object from existing TCP socket.\n\n

\n

socket is an instance of [net.Socket][]\n\n

\n

options is an optional object that might contain following properties:\n\n

\n
    \n
  • secureContext: An optional TLS context object from\n tls.createSecureContext( ... )

    \n
  • \n
  • isServer: If true - TLS socket will be instantiated in server-mode.\nDefault: false

    \n
  • \n
  • server: An optional [net.Server][] instance

    \n
  • \n
  • requestCert: Optional, see [tls.createSecurePair][]

    \n
  • \n
  • rejectUnauthorized: Optional, see [tls.createSecurePair][]

    \n
  • \n
  • NPNProtocols: Optional, see [tls.createServer][]

    \n
  • \n
  • SNICallback: Optional, see [tls.createServer][]

    \n
  • \n
  • session: Optional, a Buffer instance, containing TLS session

    \n
  • \n
  • requestOCSP: Optional, if true - OCSP status request extension would\nbe added to client hello, and 'OCSPResponse' event will be emitted on socket\nbefore establishing secure communication

    \n
  • \n
\n", "events": [ { "textRaw": "Event: 'OCSPResponse'", "type": "event", "name": "OCSPResponse", "desc": "

function (response) { }\n\n

\n

This event will be emitted if requestOCSP option was set. response is a\nbuffer object, containing server's OCSP response.\n\n

\n

Traditionally, the response is a signed object from the server's CA that\ncontains information about server's certificate revocation status.\n\n

\n", "params": [] }, { "textRaw": "Event: 'secureConnect'", "type": "event", "name": "secureConnect", "desc": "

This event is emitted after a new connection has been successfully handshaked.\nThe listener will be called no matter if the server's certificate was\nauthorized or not. It is up to the user to test tlsSocket.authorized\nto see if the server certificate was signed by one of the specified CAs.\nIf tlsSocket.authorized === false then the error can be found in\ntlsSocket.authorizationError. Also if NPN was used - you can check\ntlsSocket.npnProtocol for negotiated protocol.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "tlsSocket.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nunderlying socket as reported by the operating system. Returns an\nobject with three properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getCipher()", "type": "method", "name": "getCipher", "desc": "

Returns an object representing the cipher name and the SSL/TLS\nprotocol version of the current connection.\n\n

\n

Example:\n{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }\n\n

\n

See SSL_CIPHER_get_name() and SSL_CIPHER_get_version() in\nhttps://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS for more\ninformation.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getPeerCertificate([ detailed ])", "type": "method", "name": "getPeerCertificate", "desc": "

Returns an object representing the peer's certificate. The returned object has\nsome properties corresponding to the field of the certificate. If detailed\nargument is true - the full chain with issuer property will be returned,\nif false - only the top certificate without issuer property.\n\n

\n

Example:\n\n

\n
{ subject:\n   { C: 'UK',\n     ST: 'Acknack Ltd',\n     L: 'Rhys Jones',\n     O: 'node.js',\n     OU: 'Test TLS Certificate',\n     CN: 'localhost' },\n  issuerInfo:\n   { C: 'UK',\n     ST: 'Acknack Ltd',\n     L: 'Rhys Jones',\n     O: 'node.js',\n     OU: 'Test TLS Certificate',\n     CN: 'localhost' },\n  issuer:\n   { ... another certificate ... },\n  raw: < RAW DER buffer >,\n  valid_from: 'Nov 11 09:52:22 2009 GMT',\n  valid_to: 'Nov  6 09:52:22 2029 GMT',\n  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',\n  serialNumber: 'B9B0D332A1AA5635' }
\n

If the peer does not provide a certificate, it returns null or an empty\nobject.\n\n

\n", "signatures": [ { "params": [ { "name": "detailed", "optional": true } ] } ] }, { "textRaw": "tlsSocket.getSession()", "type": "method", "name": "getSession", "desc": "

Return ASN.1 encoded TLS session or undefined if none was negotiated. Could\nbe used to speed up handshake establishment when reconnecting to the server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getTLSTicket()", "type": "method", "name": "getTLSTicket", "desc": "

NOTE: Works only with client TLS sockets. Useful only for debugging, for\nsession reuse provide session option to tls.connect.\n\n

\n

Return TLS session ticket or undefined if none was negotiated.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.renegotiate(options, callback)", "type": "method", "name": "renegotiate", "desc": "

Initiate TLS renegotiation process. The options may contain the following\nfields: rejectUnauthorized, requestCert (See [tls.createServer][]\nfor details). callback(err) will be executed with null as err,\nonce the renegotiation is successfully completed.\n\n

\n

NOTE: Can be used to request peer's certificate after the secure connection\nhas been established.\n\n

\n

ANOTHER NOTE: When running as the server, socket will be destroyed\nwith an error after handshakeTimeout timeout.\n\n

\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] }, { "textRaw": "tlsSocket.setMaxSendFragment(size)", "type": "method", "name": "setMaxSendFragment", "desc": "

Set maximum TLS fragment size (default and maximum value is: 16384, minimum\nis: 512). Returns true on success, false otherwise.\n\n

\n

Smaller fragment size decreases buffering latency on the client: large\nfragments are buffered by the TLS layer until the entire fragment is received\nand its integrity is verified; large fragments can span multiple roundtrips,\nand their processing can be delayed due to packet loss or reordering. However,\nsmaller fragments add extra TLS framing bytes and CPU overhead, which may\ndecrease overall server throughput.\n\n

\n", "signatures": [ { "params": [ { "name": "size" } ] } ] } ], "properties": [ { "textRaw": "tlsSocket.authorized", "name": "authorized", "desc": "

A boolean that is true if the peer certificate was signed by one of the\nspecified CAs, otherwise false\n\n

\n" }, { "textRaw": "tlsSocket.authorizationError", "name": "authorizationError", "desc": "

The reason why the peer's certificate has not been verified. This property\nbecomes available only when tlsSocket.authorized === false.\n\n

\n" }, { "textRaw": "tlsSocket.encrypted", "name": "encrypted", "desc": "

Static boolean value, always true. May be used to distinguish TLS sockets\nfrom regular ones.\n\n

\n" }, { "textRaw": "tlsSocket.localPort", "name": "localPort", "desc": "

The numeric representation of the local port.\n\n

\n" }, { "textRaw": "tlsSocket.localAddress", "name": "localAddress", "desc": "

The string representation of the local IP address.\n\n

\n" }, { "textRaw": "tlsSocket.remoteAddress", "name": "remoteAddress", "desc": "

The string representation of the remote IP address. For example,\n'74.125.127.100' or '2001:4860:a005::68'.\n\n

\n" }, { "textRaw": "tlsSocket.remoteFamily", "name": "remoteFamily", "desc": "

The string representation of the remote IP family. 'IPv4' or 'IPv6'.\n\n

\n" }, { "textRaw": "tlsSocket.remotePort", "name": "remotePort", "desc": "

The numeric representation of the remote port. For example, 443.\n\n

\n" } ], "signatures": [ { "params": [ { "name": "socket" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "tls.connect(options[, callback])", "type": "method", "name": "connect", "desc": "

Creates a new client connection to the given port and host (old API) or\noptions.port and options.host. (If host is omitted, it defaults to\nlocalhost.) options should be an object which specifies:\n\n

\n
    \n
  • host: Host the client should connect to

    \n
  • \n
  • port: Port the client should connect to

    \n
  • \n
  • socket: Establish secure connection on a given socket rather than\ncreating a new socket. If this option is specified, host and port\nare ignored.

    \n
  • \n
  • path: Creates unix socket connection to path. If this option is\nspecified, host and port are ignored.

    \n
  • \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the client in PFX or PKCS12 format.

    \n
  • \n
  • key: A string or Buffer containing the private key of the client in\nPEM format. (Could be an array of keys).

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the client in\nPEM format. (Could be an array of certs).

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. Uses the same default cipher suite as tls.createServer.

    \n
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails; err.code contains the OpenSSL error code. Default: true.

    \n
  • \n
  • NPNProtocols: An array of strings or Buffers containing supported NPN\nprotocols. Buffers should have following format: 0x05hello0x05world,\nwhere first byte is next protocol name's length. (Passing array should\nusually be much simpler: ['hello', 'world'].)

    \n
  • \n
  • servername: Servername for SNI (Server Name Indication) TLS extension.

    \n
  • \n
  • checkServerIdentity(servername, cert): Provide an override for checking\nserver's hostname against the certificate. Should return an error if verification\nfails. Return undefined if passing.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
  • session: A Buffer instance, containing TLS session.

    \n
  • \n
\n

The callback parameter will be added as a listener for the\n['secureConnect'][] event.\n\n

\n

tls.connect() returns a [tls.TLSSocket][] object.\n\n

\n

Here is an example of a client of echo server as described previously:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  // These are necessary only if using the client certificate authentication\n  key: fs.readFileSync('client-key.pem'),\n  cert: fs.readFileSync('client-cert.pem'),\n\n  // This is necessary only if the server uses the self-signed certificate\n  ca: [ fs.readFileSync('server-cert.pem') ]\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('client.pfx')\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "tls.connect(port[, host][, options][, callback])", "type": "method", "name": "connect", "desc": "

Creates a new client connection to the given port and host (old API) or\noptions.port and options.host. (If host is omitted, it defaults to\nlocalhost.) options should be an object which specifies:\n\n

\n
    \n
  • host: Host the client should connect to

    \n
  • \n
  • port: Port the client should connect to

    \n
  • \n
  • socket: Establish secure connection on a given socket rather than\ncreating a new socket. If this option is specified, host and port\nare ignored.

    \n
  • \n
  • path: Creates unix socket connection to path. If this option is\nspecified, host and port are ignored.

    \n
  • \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the client in PFX or PKCS12 format.

    \n
  • \n
  • key: A string or Buffer containing the private key of the client in\nPEM format. (Could be an array of keys).

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the client in\nPEM format. (Could be an array of certs).

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. Uses the same default cipher suite as tls.createServer.

    \n
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails; err.code contains the OpenSSL error code. Default: true.

    \n
  • \n
  • NPNProtocols: An array of strings or Buffers containing supported NPN\nprotocols. Buffers should have following format: 0x05hello0x05world,\nwhere first byte is next protocol name's length. (Passing array should\nusually be much simpler: ['hello', 'world'].)

    \n
  • \n
  • servername: Servername for SNI (Server Name Indication) TLS extension.

    \n
  • \n
  • checkServerIdentity(servername, cert): Provide an override for checking\nserver's hostname against the certificate. Should return an error if verification\nfails. Return undefined if passing.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
  • session: A Buffer instance, containing TLS session.

    \n
  • \n
\n

The callback parameter will be added as a listener for the\n['secureConnect'][] event.\n\n

\n

tls.connect() returns a [tls.TLSSocket][] object.\n\n

\n

Here is an example of a client of echo server as described previously:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  // These are necessary only if using the client certificate authentication\n  key: fs.readFileSync('client-key.pem'),\n  cert: fs.readFileSync('client-cert.pem'),\n\n  // This is necessary only if the server uses the self-signed certificate\n  ca: [ fs.readFileSync('server-cert.pem') ]\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('client.pfx')\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "tls.createSecureContext(details)", "type": "method", "name": "createSecureContext", "desc": "

Creates a credentials object, with the optional details being a\ndictionary with keys:\n\n

\n
    \n
  • pfx : A string or buffer holding the PFX or PKCS12 encoded private\nkey, certificate and CA certificates
  • \n
  • key: A string or Buffer containing the private key of the server in\nPEM format. To support multiple keys using different algorithms, an array\ncan be provided. It can either be a plain array of keys, or an array of\nobjects in the format {pem: key, passphrase: passphrase}. (Required)
  • \n
  • passphrase : A string of passphrase for the private key or pfx
  • \n
  • cert : A string holding the PEM encoded certificate
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs\n(Certificate Revocation List)
  • \n
  • ciphers: A string describing the ciphers to use or exclude.\nConsult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT\nfor details on the format.
  • \n
  • honorCipherOrder : When choosing a cipher, use the server's preferences\ninstead of the client preferences. For further details see tls module\ndocumentation.
  • \n
\n

If no 'ca' details are given, then Node.js will use the default\npublicly trusted list of CAs as given in\n

\n

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.\n\n\n

\n", "signatures": [ { "params": [ { "name": "details" } ] } ] }, { "textRaw": "tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])", "type": "method", "name": "createSecurePair", "desc": "

Creates a new secure pair object with two streams, one of which reads/writes\nencrypted data, and one reads/writes cleartext data.\nGenerally the encrypted one is piped to/from an incoming encrypted data stream,\nand the cleartext one is used as a replacement for the initial encrypted stream.\n\n

\n
    \n
  • credentials: A secure context object from tls.createSecureContext( ... )

    \n
  • \n
  • isServer: A boolean indicating whether this tls connection should be\nopened as a server or a client.

    \n
  • \n
  • requestCert: A boolean indicating whether a server should request a\ncertificate from a connecting client. Only applies to server connections.

    \n
  • \n
  • rejectUnauthorized: A boolean indicating whether a server should\nautomatically reject clients with invalid certificates. Only applies to\nservers with requestCert enabled.

    \n
  • \n
\n

tls.createSecurePair() returns a SecurePair object with cleartext and\nencrypted stream properties.\n\n

\n

NOTE: cleartext has the same APIs as [tls.TLSSocket][]\n\n

\n", "signatures": [ { "params": [ { "name": "context", "optional": true }, { "name": "isServer", "optional": true }, { "name": "requestCert", "optional": true }, { "name": "rejectUnauthorized", "optional": true } ] } ] }, { "textRaw": "tls.createServer(options[, secureConnectionListener])", "type": "method", "name": "createServer", "desc": "

Creates a new [tls.Server][]. The connectionListener argument is\nautomatically set as a listener for the ['secureConnection'][] event. The\noptions object has these possibilities:\n\n

\n
    \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the server in PFX or PKCS12 format. (Mutually exclusive with\nthe key, cert and ca options.)

    \n
  • \n
  • key: A string or Buffer containing the private key of the server in\nPEM format. To support multiple keys using different algorithms, an array\ncan be provided. It can either be a plain array of keys, or an array of\nobjects in the format {pem: key, passphrase: passphrase}. (Required)

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the server in\nPEM format. (Could be an array of certs). (Required)

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate\nRevocation List)

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. The default cipher suite is:

    \n
    ECDHE-RSA-AES128-GCM-SHA256:\nECDHE-ECDSA-AES128-GCM-SHA256:\nECDHE-RSA-AES256-GCM-SHA384:\nECDHE-ECDSA-AES256-GCM-SHA384:\nDHE-RSA-AES128-GCM-SHA256:\nECDHE-RSA-AES128-SHA256:\nDHE-RSA-AES128-SHA256:\nECDHE-RSA-AES256-SHA384:\nDHE-RSA-AES256-SHA384:\nECDHE-RSA-AES256-SHA256:\nDHE-RSA-AES256-SHA256:\nHIGH:\n!aNULL:\n!eNULL:\n!EXPORT:\n!DES:\n!RC4:\n!MD5:\n!PSK:\n!SRP:\n!CAMELLIA
    \n

    The default cipher suite prefers GCM ciphers for [Chrome's 'modern\ncryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect\nForward secrecy, while offering some backward compatibiltity.

    \n

    128 bit AES is preferred over 192 and 256 bit AES in light of [specific\nattacks affecting larger AES key sizes].

    \n

    Old clients that rely on insecure and deprecated RC4 or DES-based ciphers\n(like Internet Explorer 6) aren't able to complete the handshake with the default\nconfiguration. If you absolutely must support these clients, the\n[TLS recommendations] may offer a compatible cipher suite. For more details\non the format, see the [OpenSSL cipher list format documentation].

    \n
  • \n
  • ecdhCurve: A string describing a named curve to use for ECDH key agreement\nor false to disable ECDH.

    \n

    Defaults to prime256v1 (NIST P-256). Use [crypto.getCurves()][] to obtain\na list of available curve names. On recent releases,\nopenssl ecparam -list_curves will also display the name and description of\neach available elliptic curve.

    \n
  • \n
  • dhparam: A string or Buffer containing Diffie Hellman parameters,\nrequired for Perfect Forward Secrecy. Use openssl dhparam to create it.\nIts key length should be greater than or equal to 1024 bits, otherwise\nit throws an error. It is strongly recommended to use 2048 bits or\nmore for stronger security. If omitted or invalid, it is silently\ndiscarded and DHE ciphers won't be available.

    \n
  • \n
  • handshakeTimeout: Abort the connection if the SSL/TLS handshake does not\nfinish in this many milliseconds. The default is 120 seconds.

    \n

    A 'clientError' is emitted on the tls.Server object whenever a handshake\ntimes out.

    \n
  • \n
  • honorCipherOrder : When choosing a cipher, use the server's preferences\ninstead of the client preferences. Default: true.

    \n
  • \n
  • requestCert: If true the server will request a certificate from\nclients that connect and attempt to verify that certificate. Default:\nfalse.

    \n
  • \n
  • rejectUnauthorized: If true the server will reject any connection\nwhich is not authorized with the list of supplied CAs. This option only\nhas an effect if requestCert is true. Default: false.

    \n
  • \n
  • NPNProtocols: An array or Buffer of possible NPN protocols. (Protocols\nshould be ordered by their priority).

    \n
  • \n
  • SNICallback(servername, cb): A function that will be called if client\nsupports SNI TLS extension. Two argument will be passed to it: servername,\nand cb. SNICallback should invoke cb(null, ctx), where ctx is a\nSecureContext instance.\n(You can use tls.createSecureContext(...) to get proper\nSecureContext). If SNICallback wasn't provided - default callback with\nhigh-level API will be used (see below).

    \n
  • \n
  • sessionTimeout: An integer specifying the seconds after which TLS\nsession identifiers and TLS session tickets created by the server are\ntimed out. See [SSL_CTX_set_timeout] for more details.

    \n
  • \n
  • ticketKeys: A 48-byte Buffer instance consisting of 16-byte prefix,\n16-byte hmac key, 16-byte AES key. You could use it to accept tls session\ntickets on multiple instances of tls server.

    \n

    NOTE: Automatically shared between cluster module workers.

    \n
  • \n
  • sessionIdContext: A string containing an opaque identifier for session\nresumption. If requestCert is true, the default is MD5 hash value\ngenerated from command-line. (In FIPS mode a truncated SHA1 hash is\nused instead.) Otherwise, the default is not provided.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
\n

Here is a simple example echo server:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  key: fs.readFileSync('server-key.pem'),\n  cert: fs.readFileSync('server-cert.pem'),\n\n  // This is necessary only if using the client certificate authentication.\n  requestCert: true,\n\n  // This is necessary only if the client uses the self-signed certificate.\n  ca: [ fs.readFileSync('client-cert.pem') ]\n};\n\nvar server = tls.createServer(options, (socket) => {\n  console.log('server connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  socket.write('welcome!\\n');\n  socket.setEncoding('utf8');\n  socket.pipe(socket);\n});\nserver.listen(8000, () => {\n  console.log('server bound');\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('server.pfx'),\n\n  // This is necessary only if using the client certificate authentication.\n  requestCert: true,\n\n};\n\nvar server = tls.createServer(options, (socket) => {\n  console.log('server connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  socket.write('welcome!\\n');\n  socket.setEncoding('utf8');\n  socket.pipe(socket);\n});\nserver.listen(8000, () => {\n  console.log('server bound');\n});
\n

You can test this server by connecting to it with openssl s_client:\n\n\n

\n
openssl s_client -connect 127.0.0.1:8000
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "secureConnectionListener", "optional": true } ] } ] }, { "textRaw": "tls.getCiphers()", "type": "method", "name": "getCiphers", "desc": "

Returns an array with the names of the supported SSL ciphers.\n\n

\n

Example:\n\n

\n
var ciphers = tls.getCiphers();\nconsole.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "TLS (SSL)" }, { "textRaw": "TTY", "name": "tty", "stability": 2, "stabilityText": "Stable", "desc": "

The tty module houses the tty.ReadStream and tty.WriteStream classes. In\nmost cases, you will not need to use this module directly.\n\n

\n

When Node.js detects that it is being run inside a TTY context, then process.stdin\nwill be a tty.ReadStream instance and process.stdout will be\na tty.WriteStream instance. The preferred way to check if Node.js is being run\nin a TTY context is to check process.stdout.isTTY:\n\n

\n
$ node -p -e "Boolean(process.stdout.isTTY)"\ntrue\n$ node -p -e "Boolean(process.stdout.isTTY)" | cat\nfalse
\n", "classes": [ { "textRaw": "Class: ReadStream", "type": "class", "name": "ReadStream", "desc": "

A net.Socket subclass that represents the readable portion of a tty. In normal\ncircumstances, process.stdin will be the only tty.ReadStream instance in any\nNode.js program (only when isatty(0) is true).\n\n

\n", "properties": [ { "textRaw": "rs.isRaw", "name": "isRaw", "desc": "

A Boolean that is initialized to false. It represents the current "raw" state\nof the tty.ReadStream instance.\n\n

\n" } ], "methods": [ { "textRaw": "rs.setRawMode(mode)", "type": "method", "name": "setRawMode", "desc": "

mode should be true or false. This sets the properties of the\ntty.ReadStream to act either as a raw device or default. isRaw will be set\nto the resulting mode.\n\n

\n", "signatures": [ { "params": [ { "name": "mode" } ] } ] } ] }, { "textRaw": "Class: WriteStream", "type": "class", "name": "WriteStream", "desc": "

A net.Socket subclass that represents the writable portion of a tty. In normal\ncircumstances, process.stdout will be the only tty.WriteStream instance\never created (and only when isatty(1) is true).\n\n

\n", "events": [ { "textRaw": "Event: 'resize'", "type": "event", "name": "resize", "desc": "

function () {}\n\n

\n

Emitted by refreshSize() when either of the columns or rows properties\nhas changed.\n\n

\n
process.stdout.on('resize', () => {\n  console.log('screen size has changed!');\n  console.log(`${process.stdout.columns}x${process.stdout.rows}`);\n});
\n", "params": [] } ], "properties": [ { "textRaw": "ws.columns", "name": "columns", "desc": "

A Number that gives the number of columns the TTY currently has. This property\ngets updated on 'resize' events.\n\n

\n" }, { "textRaw": "ws.rows", "name": "rows", "desc": "

A Number that gives the number of rows the TTY currently has. This property\ngets updated on 'resize' events.\n\n

\n" } ] } ], "methods": [ { "textRaw": "tty.isatty(fd)", "type": "method", "name": "isatty", "desc": "

Returns true or false depending on if the fd is associated with a\nterminal.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "tty.setRawMode(mode)", "type": "method", "name": "setRawMode", "stability": 0, "stabilityText": "Deprecated: Use [tty.ReadStream#setRawMode][] (i.e. process.stdin.setRawMode) instead.", "signatures": [ { "params": [ { "name": "mode" } ] } ] } ], "type": "module", "displayName": "TTY" }, { "textRaw": "URL", "name": "url", "stability": 2, "stabilityText": "Stable", "desc": "

This module has utilities for URL resolution and parsing.\nCall require('url') to use it.\n\n

\n", "modules": [ { "textRaw": "URL Parsing", "name": "url_parsing", "desc": "

Parsed URL objects have some or all of the following fields, depending on\nwhether or not they exist in the URL string. Any parts that are not in the URL\nstring will not be in the parsed object. Examples are shown for the URL\n\n

\n

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'\n\n

\n
    \n
  • href: The full URL that was originally parsed. Both the protocol and host are lowercased.

    \n

    Example: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

    \n
  • \n
  • protocol: The request protocol, lowercased.

    \n

    Example: 'http:'

    \n
  • \n
  • slashes: The protocol requires slashes after the colon.

    \n

    Example: true or false

    \n
  • \n
  • host: The full lowercased host portion of the URL, including port\ninformation.

    \n

    Example: 'host.com:8080'

    \n
  • \n
  • auth: The authentication information portion of a URL.

    \n

    Example: 'user:pass'

    \n
  • \n
  • hostname: Just the lowercased hostname portion of the host.

    \n

    Example: 'host.com'

    \n
  • \n
  • port: The port number portion of the host.

    \n

    Example: '8080'

    \n
  • \n
  • pathname: The path section of the URL, that comes after the host and\nbefore the query, including the initial slash if present. No decoding is\nperformed.

    \n

    Example: '/p/a/t/h'

    \n
  • \n
  • search: The 'query string' portion of the URL, including the leading\nquestion mark.

    \n

    Example: '?query=string'

    \n
  • \n
  • path: Concatenation of pathname and search. No decoding is performed.

    \n

    Example: '/p/a/t/h?query=string'

    \n
  • \n
  • query: Either the 'params' portion of the query string, or a\nquerystring-parsed object.

    \n

    Example: 'query=string' or {'query':'string'}

    \n
  • \n
  • hash: The 'fragment' portion of the URL including the pound-sign.

    \n

    Example: '#hash'

    \n
  • \n
\n", "modules": [ { "textRaw": "Escaped Characters", "name": "escaped_characters", "desc": "

Spaces (' ') and the following characters will be automatically escaped in the\nproperties of URL objects:\n\n

\n
< > " ` \\r \\n \\t { } | \\ ^ '
\n
\n

The following methods are provided by the URL module:\n\n

\n", "type": "module", "displayName": "Escaped Characters" } ], "type": "module", "displayName": "URL Parsing" } ], "methods": [ { "textRaw": "url.format(urlObj)", "type": "method", "name": "format", "desc": "

Take a parsed URL object, and return a formatted URL string.\n\n

\n

Here's how the formatting process works:\n\n

\n
    \n
  • href will be ignored.
  • \n
  • path will be ignored.
  • \n
  • protocol is treated the same with or without the trailing : (colon).
      \n
    • The protocols http, https, ftp, gopher, file will be\npostfixed with :// (colon-slash-slash) as long as host/hostname are present.
    • \n
    • All other protocols mailto, xmpp, aim, sftp, foo, etc will\nbe postfixed with : (colon).
    • \n
    \n
  • \n
  • slashes set to true if the protocol requires :// (colon-slash-slash)
      \n
    • Only needs to be set for protocols not previously listed as requiring\nslashes, such as mongodb://localhost:8000/, or if host/hostname are absent.
    • \n
    \n
  • \n
  • auth will be used if present.
  • \n
  • hostname will only be used if host is absent.
  • \n
  • port will only be used if host is absent.
  • \n
  • host will be used in place of hostname and port.
  • \n
  • pathname is treated the same with or without the leading / (slash).
  • \n
  • query (object; see querystring) will only be used if search is absent.
  • \n
  • search will be used in place of query.
      \n
    • It is treated the same with or without the leading ? (question mark).
    • \n
    \n
  • \n
  • hash is treated the same with or without the leading # (pound sign, anchor).
  • \n
\n", "signatures": [ { "params": [ { "name": "urlObj" } ] } ] }, { "textRaw": "url.parse(urlStr[, parseQueryString][, slashesDenoteHost])", "type": "method", "name": "parse", "desc": "

Take a URL string, and return an object.\n\n

\n

Pass true as the second argument to also parse the query string using the\nquerystring module. If true then the query property will always be\nassigned an object, and the search property will always be a (possibly\nempty) string. If false then the query property will not be parsed or\ndecoded. Defaults to false.\n\n

\n

Pass true as the third argument to treat //foo/bar as\n{ host: 'foo', pathname: '/bar' } rather than\n{ pathname: '//foo/bar' }. Defaults to false.\n\n

\n", "signatures": [ { "params": [ { "name": "urlStr" }, { "name": "parseQueryString", "optional": true }, { "name": "slashesDenoteHost", "optional": true } ] } ] }, { "textRaw": "url.resolve(from, to)", "type": "method", "name": "resolve", "desc": "

Take a base URL, and a href URL, and resolve them as a browser would for\nan anchor tag. Examples:\n\n

\n
url.resolve('/one/two/three', 'four')         // '/one/two/four'\nurl.resolve('http://example.com/', '/one')    // 'http://example.com/one'\nurl.resolve('http://example.com/one', '/two') // 'http://example.com/two'
\n", "signatures": [ { "params": [ { "name": "from" }, { "name": "to" } ] } ] } ], "type": "module", "displayName": "URL" }, { "textRaw": "util", "name": "util", "stability": 2, "stabilityText": "Stable", "desc": "

These functions are in the module 'util'. Use require('util') to\naccess them.\n\n

\n

The util module is primarily designed to support the needs of Node.js's\ninternal APIs. Many of these utilities are useful for your own\nprograms. If you find that these functions are lacking for your\npurposes, however, you are encouraged to write your own utilities. We\nare not interested in any future additions to the util module that\nare unnecessary for Node.js's internal functionality.\n\n

\n", "methods": [ { "textRaw": "util.debug(string)", "type": "method", "name": "debug", "stability": 0, "stabilityText": "Deprecated: use console.error() instead.", "desc": "

Deprecated predecessor of console.error.\n\n

\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "util.debuglog(section)", "type": "method", "name": "debuglog", "signatures": [ { "return": { "textRaw": "Returns: {Function} The logging function ", "name": "return", "type": "Function", "desc": "The logging function" }, "params": [ { "textRaw": "`section` {String} The section of the program to be debugged ", "name": "section", "type": "String", "desc": "The section of the program to be debugged" } ] }, { "params": [ { "name": "section" } ] } ], "desc": "

This is used to create a function which conditionally writes to stderr\nbased on the existence of a NODE_DEBUG environment variable. If the\nsection name appears in that environment variable, then the returned\nfunction will be similar to console.error(). If not, then the\nreturned function is a no-op.\n\n

\n

For example:\n\n

\n
var debuglog = util.debuglog('foo');\n\nvar bar = 123;\ndebuglog('hello from foo [%d]', bar);
\n

If this program is run with NODE_DEBUG=foo in the environment, then\nit will output something like:\n\n

\n
FOO 3245: hello from foo [123]
\n

where 3245 is the process id. If it is not run with that\nenvironment variable set, then it will not print anything.\n\n

\n

You may separate multiple NODE_DEBUG environment variables with a\ncomma. For example, NODE_DEBUG=fs,net,tls.\n\n

\n" }, { "textRaw": "util.deprecate(function, string)", "type": "method", "name": "deprecate", "desc": "

Marks that a method should not be used any more.\n\n

\n
const util = require('util');\n\nexports.puts = util.deprecate(function() {\n  for (var i = 0, len = arguments.length; i < len; ++i) {\n    process.stdout.write(arguments[i] + '\\n');\n  }\n}, 'util.puts: Use console.log instead');
\n

It returns a modified function which warns once by default.\n\n

\n

If --no-deprecation is set then this function is a NO-OP. Configurable\nat run-time through the process.noDeprecation boolean (only effective\nwhen set before a module is loaded.)\n\n

\n

If --trace-deprecation is set, a warning and a stack trace are logged\nto the console the first time the deprecated API is used. Configurable\nat run-time through the process.traceDeprecation boolean.\n\n

\n

If --throw-deprecation is set then the application throws an exception\nwhen the deprecated API is used. Configurable at run-time through the\nprocess.throwDeprecation boolean.\n\n

\n

process.throwDeprecation takes precedence over process.traceDeprecation.\n\n

\n", "signatures": [ { "params": [ { "name": "function" }, { "name": "string" } ] } ] }, { "textRaw": "util.error([...])", "type": "method", "name": "error", "stability": 0, "stabilityText": "Deprecated: Use console.error() instead.", "desc": "

Deprecated predecessor of console.error.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.format(format[, ...])", "type": "method", "name": "format", "desc": "

Returns a formatted string using the first argument as a printf-like format.\n\n

\n

The first argument is a string that contains zero or more placeholders.\nEach placeholder is replaced with the converted value from its corresponding\nargument. Supported placeholders are:\n\n

\n
    \n
  • %s - String.
  • \n
  • %d - Number (both integer and float).
  • \n
  • %j - JSON. Replaced with the string '[Circular]' if the argument\ncontains circular references.
  • \n
  • %% - single percent sign ('%'). This does not consume an argument.
  • \n
\n

If the placeholder does not have a corresponding argument, the placeholder is\nnot replaced.\n\n

\n
util.format('%s:%s', 'foo'); // 'foo:%s'
\n

If there are more arguments than placeholders, the extra arguments are\ncoerced to strings (for objects and symbols, util.inspect() is used)\nand then concatenated, delimited by a space.\n\n

\n
util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'
\n

If the first argument is not a format string then util.format() returns\na string that is the concatenation of all its arguments separated by spaces.\nEach argument is converted to a string with util.inspect().\n\n

\n
util.format(1, 2, 3); // '1 2 3'
\n", "signatures": [ { "params": [ { "name": "format" }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.inherits(constructor, superConstructor)", "type": "method", "name": "inherits", "desc": "

Inherit the prototype methods from one [constructor][] into another. The\nprototype of constructor will be set to a new object created from\nsuperConstructor.\n\n

\n

As an additional convenience, superConstructor will be accessible\nthrough the constructor.super_ property.\n\n

\n
const util = require('util');\nconst EventEmitter = require('events');\n\nfunction MyStream() {\n    EventEmitter.call(this);\n}\n\nutil.inherits(MyStream, EventEmitter);\n\nMyStream.prototype.write = function(data) {\n    this.emit('data', data);\n}\n\nvar stream = new MyStream();\n\nconsole.log(stream instanceof EventEmitter); // true\nconsole.log(MyStream.super_ === EventEmitter); // true\n\nstream.on('data', (data) => {\n  console.log(`Received data: "${data}"`);\n})\nstream.write('It works!'); // Received data: "It works!"
\n", "signatures": [ { "params": [ { "name": "constructor" }, { "name": "superConstructor" } ] } ] }, { "textRaw": "util.inspect(object[, options])", "type": "method", "name": "inspect", "desc": "

Return a string representation of object, which is useful for debugging.\n\n

\n

An optional options object may be passed that alters certain aspects of the\nformatted string:\n\n

\n
    \n
  • showHidden - if true then the object's non-enumerable and symbol\nproperties will be shown too. Defaults to false.

    \n
  • \n
  • depth - tells inspect how many times to recurse while formatting the\nobject. This is useful for inspecting large complicated objects. Defaults to\n2. To make it recurse indefinitely pass null.

    \n
  • \n
  • colors - if true, then the output will be styled with ANSI color codes.\nDefaults to false. Colors are customizable, see below.

    \n
  • \n
  • customInspect - if false, then custom inspect(depth, opts) functions\ndefined on the objects being inspected won't be called. Defaults to true.

    \n
  • \n
\n

Example of inspecting all properties of the util object:\n\n

\n
const util = require('util');\n\nconsole.log(util.inspect(util, { showHidden: true, depth: null }));
\n

Values may supply their own custom inspect(depth, opts) functions, when\ncalled they receive the current depth in the recursive inspection, as well as\nthe options object passed to util.inspect().\n\n

\n", "miscs": [ { "textRaw": "Customizing `util.inspect` colors", "name": "Customizing `util.inspect` colors", "type": "misc", "desc": "

Color output (if enabled) of util.inspect is customizable globally\nvia util.inspect.styles and util.inspect.colors objects.\n\n

\n

util.inspect.styles is a map assigning each style a color\nfrom util.inspect.colors.\nHighlighted styles and their default values are:\n number (yellow)\n boolean (yellow)\n string (green)\n date (magenta)\n regexp (red)\n null (bold)\n undefined (grey)\n special - only function at this time (cyan)\n * name (intentionally no styling)\n\n

\n

Predefined color codes are: white, grey, black, blue, cyan,\ngreen, magenta, red and yellow.\nThere are also bold, italic, underline and inverse codes.\n\n

\n" }, { "textRaw": "Custom `inspect()` function on Objects", "name": "Custom `inspect()` function on Objects", "type": "misc", "desc": "

Objects also may define their own inspect(depth) function which util.inspect()\nwill invoke and use the result of when inspecting the object:\n\n

\n
const util = require('util');\n\nvar obj = { name: 'nate' };\nobj.inspect = function(depth) {\n  return `{${this.name}}`;\n};\n\nutil.inspect(obj);\n  // "{nate}"
\n

You may also return another Object entirely, and the returned String will be\nformatted according to the returned Object. This is similar to how\nJSON.stringify() works:\n\n

\n
var obj = { foo: 'this will not show up in the inspect() output' };\nobj.inspect = function(depth) {\n  return { bar: 'baz' };\n};\n\nutil.inspect(obj);\n  // "{ bar: 'baz' }"
\n" } ], "signatures": [ { "params": [ { "name": "object" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "util.isArray(object)", "type": "method", "name": "isArray", "stability": 0, "stabilityText": "Deprecated", "desc": "

Internal alias for [Array.isArray][].\n\n

\n

Returns true if the given "object" is an Array. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isArray([])\n  // true\nutil.isArray(new Array)\n  // true\nutil.isArray({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isBoolean(object)", "type": "method", "name": "isBoolean", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Boolean. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isBoolean(1)\n  // false\nutil.isBoolean(0)\n  // false\nutil.isBoolean(false)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isBuffer(object)", "type": "method", "name": "isBuffer", "stability": 0, "stabilityText": "Deprecated", "desc": "

Use Buffer.isBuffer() instead.\n\n

\n

Returns true if the given "object" is a Buffer. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isBuffer({ length: 0 })\n  // false\nutil.isBuffer([])\n  // false\nutil.isBuffer(new Buffer('hello world'))\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isDate(object)", "type": "method", "name": "isDate", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Date. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isDate(new Date())\n  // true\nutil.isDate(Date())\n  // false (without 'new' returns a String)\nutil.isDate({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isError(object)", "type": "method", "name": "isError", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is an [Error][]. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isError(new Error())\n  // true\nutil.isError(new TypeError())\n  // true\nutil.isError({ name: 'Error', message: 'an error occurred' })\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isFunction(object)", "type": "method", "name": "isFunction", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Function. false otherwise.\n\n

\n
const util = require('util');\n\nfunction Foo() {}\nvar Bar = function() {};\n\nutil.isFunction({})\n  // false\nutil.isFunction(Foo)\n  // true\nutil.isFunction(Bar)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNull(object)", "type": "method", "name": "isNull", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is strictly null. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNull(0)\n  // false\nutil.isNull(undefined)\n  // false\nutil.isNull(null)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNullOrUndefined(object)", "type": "method", "name": "isNullOrUndefined", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is null or undefined. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNullOrUndefined(0)\n  // false\nutil.isNullOrUndefined(undefined)\n  // true\nutil.isNullOrUndefined(null)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNumber(object)", "type": "method", "name": "isNumber", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Number. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNumber(false)\n  // false\nutil.isNumber(Infinity)\n  // true\nutil.isNumber(0)\n  // true\nutil.isNumber(NaN)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isObject(object)", "type": "method", "name": "isObject", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is strictly an Object and not a\nFunction. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isObject(5)\n  // false\nutil.isObject(null)\n  // false\nutil.isObject({})\n  // true\nutil.isObject(function(){})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isPrimitive(object)", "type": "method", "name": "isPrimitive", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a primitive type. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isPrimitive(5)\n  // true\nutil.isPrimitive('foo')\n  // true\nutil.isPrimitive(false)\n  // true\nutil.isPrimitive(null)\n  // true\nutil.isPrimitive(undefined)\n  // true\nutil.isPrimitive({})\n  // false\nutil.isPrimitive(function() {})\n  // false\nutil.isPrimitive(/^$/)\n  // false\nutil.isPrimitive(new Date())\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isRegExp(object)", "type": "method", "name": "isRegExp", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a RegExp. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isRegExp(/some regexp/)\n  // true\nutil.isRegExp(new RegExp('another regexp'))\n  // true\nutil.isRegExp({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isString(object)", "type": "method", "name": "isString", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a String. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isString('')\n  // true\nutil.isString('foo')\n  // true\nutil.isString(String('foo'))\n  // true\nutil.isString(5)\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isSymbol(object)", "type": "method", "name": "isSymbol", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Symbol. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isSymbol(5)\n  // false\nutil.isSymbol('foo')\n  // false\nutil.isSymbol(Symbol('foo'))\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isUndefined(object)", "type": "method", "name": "isUndefined", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is undefined. false otherwise.\n\n

\n
const util = require('util');\n\nvar foo;\nutil.isUndefined(5)\n  // false\nutil.isUndefined(foo)\n  // true\nutil.isUndefined(null)\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.log(string)", "type": "method", "name": "log", "desc": "

Output with timestamp on stdout.\n\n

\n
require('util').log('Timestamped message.');
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "util.print([...])", "type": "method", "name": "print", "stability": 0, "stabilityText": "Deprecated: Use `console.log` instead.", "desc": "

Deprecated predecessor of console.log.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.pump(readableStream, writableStream[, callback])", "type": "method", "name": "pump", "stability": 0, "stabilityText": "Deprecated: Use readableStream.pipe(writableStream)", "desc": "

Deprecated predecessor of stream.pipe().\n\n

\n", "signatures": [ { "params": [ { "name": "readableStream" }, { "name": "writableStream" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "util.puts([...])", "type": "method", "name": "puts", "stability": 0, "stabilityText": "Deprecated: Use console.log() instead.", "desc": "

Deprecated predecessor of console.log.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] } ], "type": "module", "displayName": "util" }, { "textRaw": "V8", "name": "v8", "stability": 2, "stabilityText": "Stable", "desc": "

This module exposes events and interfaces specific to the version of [V8][]\nbuilt with Node.js. These interfaces are subject to change by upstream and are\ntherefore not covered under the stability index.\n\n

\n", "methods": [ { "textRaw": "getHeapStatistics()", "type": "method", "name": "getHeapStatistics", "desc": "

Returns an object with the following properties\n\n

\n
{\n  total_heap_size: 7326976,\n  total_heap_size_executable: 4194304,\n  total_physical_size: 7326976,\n  total_available_size: 1152656,\n  used_heap_size: 3476208,\n  heap_size_limit: 1535115264\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "setFlagsFromString(string)", "type": "method", "name": "setFlagsFromString", "desc": "

Set additional V8 command line flags. Use with care; changing settings\nafter the VM has started may result in unpredictable behavior, including\ncrashes and data loss. Or it may simply do nothing.\n\n

\n

The V8 options available for a version of Node.js may be determined by running\nnode --v8-options. An unofficial, community-maintained list of options\nand their effects is available [here][].\n\n

\n

Usage:\n\n

\n
// Print GC events to stdout for one minute.\nconst v8 = require('v8');\nv8.setFlagsFromString('--trace_gc');\nsetTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] } ], "type": "module", "displayName": "V8" }, { "textRaw": "Executing JavaScript", "name": "vm", "stability": 2, "stabilityText": "Stable", "desc": "

You can access this module with:\n\n

\n
const vm = require('vm');
\n

JavaScript code can be compiled and run immediately or compiled, saved, and run\nlater.\n\n

\n", "classes": [ { "textRaw": "Class: Script", "type": "class", "name": "Script", "desc": "

A class for holding precompiled scripts, and running them in specific sandboxes.\n\n

\n", "methods": [ { "textRaw": "new vm.Script(code, options)", "type": "method", "name": "Script", "desc": "

Creating a new Script compiles code but does not run it. Instead, the\ncreated vm.Script object represents this compiled code. This script can be run\nlater many times using methods below. The returned script is not bound to any\nglobal object. It is bound before each run, just for that run.\n\n

\n

The options when creating a script are:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced from this script.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nApplies only to syntax errors compiling the code; errors while running the\ncode are controlled by the options to the script's methods.
  • \n
  • timeout: a number of milliseconds to execute code before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "options" } ] } ] }, { "textRaw": "script.runInContext(contextifiedSandbox[, options])", "type": "method", "name": "runInContext", "desc": "

Similar to vm.runInContext but a method of a precompiled Script object.\nscript.runInContext runs script's compiled code in contextifiedSandbox\nand returns the result. Running code does not have access to local scope.\n\n

\n

script.runInContext takes the same options as script.runInThisContext.\n\n

\n

Example: compile code that increments a global variable and sets one, then\nexecute the code multiple times. These globals are contained in the sandbox.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nvar sandbox = {\n  animal: 'cat',\n  count: 2\n};\n\nvar context = new vm.createContext(sandbox);\nvar script = new vm.Script('count += 1; name = "kitty"');\n\nfor (var i = 0; i < 10; ++i) {\n  script.runInContext(context);\n}\n\nconsole.log(util.inspect(sandbox));\n\n// { animal: 'cat', count: 12, name: 'kitty' }
\n

Note that running untrusted code is a tricky business requiring great care.\nscript.runInContext is quite useful, but safely running untrusted code\nrequires a separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "contextifiedSandbox" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "script.runInNewContext([sandbox][, options])", "type": "method", "name": "runInNewContext", "desc": "

Similar to vm.runInNewContext but a method of a precompiled Script object.\nscript.runInNewContext contextifies sandbox if passed or creates a new\ncontextified sandbox if it's omitted, and then runs script's compiled code\nwith the sandbox as the global object and returns the result. Running code does\nnot have access to local scope.\n\n

\n

script.runInNewContext takes the same options as script.runInThisContext.\n\n

\n

Example: compile code that sets a global variable, then execute the code\nmultiple times in different contexts. These globals are set on and contained in\nthe sandboxes.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandboxes = [{}, {}, {}];\n\nconst script = new vm.Script('globalVar = "set"');\n\nsandboxes.forEach((sandbox) => {\n  script.runInNewContext(sandbox);\n});\n\nconsole.log(util.inspect(sandboxes));\n\n// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
\n

Note that running untrusted code is a tricky business requiring great care.\nscript.runInNewContext is quite useful, but safely running untrusted code\nrequires a separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "script.runInThisContext([options])", "type": "method", "name": "runInThisContext", "desc": "

Similar to vm.runInThisContext but a method of a precompiled Script object.\nscript.runInThisContext runs script's compiled code and returns the result.\nRunning code does not have access to local scope, but does have access to the\ncurrent global object.\n\n

\n

Example of using script.runInThisContext to compile code once and run it\nmultiple times:\n\n

\n
const vm = require('vm');\n\nglobal.globalVar = 0;\n\nconst script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });\n\nfor (var i = 0; i < 1000; ++i) {\n  script.runInThisContext();\n}\n\nconsole.log(globalVar);\n\n// 1000
\n

The options for running a script are:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nApplies only to runtime errors executing the code; it is impossible to create\na Script instance with syntax errors, as the constructor will throw.
  • \n
  • timeout: a number of milliseconds to execute the script before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] } ] } ], "methods": [ { "textRaw": "vm.createContext([sandbox])", "type": "method", "name": "createContext", "desc": "

If given a sandbox object, will "contextify" that sandbox so that it can be\nused in calls to vm.runInContext or script.runInContext. Inside scripts run\nas such, sandbox will be the global object, retaining all its existing\nproperties but also having the built-in objects and functions any standard\n[global object][] has. Outside of scripts run by the vm module, sandbox will\nbe unchanged.\n\n

\n

If not given a sandbox object, returns a new, empty contextified sandbox object\nyou can use.\n\n

\n

This function is useful for creating a sandbox that can be used to run multiple\nscripts, e.g. if you were emulating a web browser it could be used to create a\nsingle sandbox representing a window's global object, then run all <script>\ntags together inside that sandbox.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox", "optional": true } ] } ] }, { "textRaw": "vm.isContext(sandbox)", "type": "method", "name": "isContext", "desc": "

Returns whether or not a sandbox object has been contextified by calling\nvm.createContext on it.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox" } ] } ] }, { "textRaw": "vm.runInContext(code, contextifiedSandbox[, options])", "type": "method", "name": "runInContext", "desc": "

vm.runInContext compiles code, then runs it in contextifiedSandbox and\nreturns the result. Running code does not have access to local scope. The\ncontextifiedSandbox object must have been previously contextified via\nvm.createContext; it will be used as the global object for code.\n\n

\n

vm.runInContext takes the same options as vm.runInThisContext.\n\n

\n

Example: compile and execute different scripts in a single existing context.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandbox = { globalVar: 1 };\nvm.createContext(sandbox);\n\nfor (var i = 0; i < 10; ++i) {\n    vm.runInContext('globalVar *= 2;', sandbox);\n}\nconsole.log(util.inspect(sandbox));\n\n// { globalVar: 1024 }
\n

Note that running untrusted code is a tricky business requiring great care.\nvm.runInContext is quite useful, but safely running untrusted code requires a\nseparate process.\n\n

\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "contextifiedSandbox" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "vm.runInDebugContext(code)", "type": "method", "name": "runInDebugContext", "desc": "

vm.runInDebugContext compiles and executes code inside the V8 debug context.\nThe primary use case is to get access to the V8 debug object:\n\n

\n
const Debug = vm.runInDebugContext('Debug');\nDebug.scripts().forEach(function(script) { console.log(script.name); });
\n

Note that the debug context and object are intrinsically tied to V8's debugger\nimplementation and may change (or even get removed) without prior warning.\n\n

\n

The debug object can also be exposed with the --expose_debug_as= switch.\n\n

\n", "signatures": [ { "params": [ { "name": "code" } ] } ] }, { "textRaw": "vm.runInNewContext(code[, sandbox][, options])", "type": "method", "name": "runInNewContext", "desc": "

vm.runInNewContext compiles code, contextifies sandbox if passed or\ncreates a new contextified sandbox if it's omitted, and then runs the code with\nthe sandbox as the global object and returns the result.\n\n

\n

vm.runInNewContext takes the same options as vm.runInThisContext.\n\n

\n

Example: compile and execute code that increments a global variable and sets a\nnew one. These globals are contained in the sandbox.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandbox = {\n  animal: 'cat',\n  count: 2\n};\n\nvm.runInNewContext('count += 1; name = "kitty"', sandbox);\nconsole.log(util.inspect(sandbox));\n\n// { animal: 'cat', count: 3, name: 'kitty' }
\n

Note that running untrusted code is a tricky business requiring great care.\nvm.runInNewContext is quite useful, but safely running untrusted code requires\na separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "sandbox", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "vm.runInThisContext(code[, options])", "type": "method", "name": "runInThisContext", "desc": "

vm.runInThisContext() compiles code, runs it and returns the result. Running\ncode does not have access to local scope, but does have access to the current\nglobal object.\n\n

\n

Example of using vm.runInThisContext and eval to run the same code:\n\n

\n
const vm = require('vm');\nvar localVar = 'initial value';\n\nconst vmResult = vm.runInThisContext('localVar = "vm";');\nconsole.log('vmResult: ', vmResult);\nconsole.log('localVar: ', localVar);\n\nconst evalResult = eval('localVar = "eval";');\nconsole.log('evalResult: ', evalResult);\nconsole.log('localVar: ', localVar);\n\n// vmResult: 'vm', localVar: 'initial value'\n// evalResult: 'eval', localVar: 'eval'
\n

vm.runInThisContext does not have access to the local scope, so localVar is\nunchanged. eval does have access to the local scope, so localVar is changed.\n\n

\n

In this way vm.runInThisContext is much like an [indirect eval call][],\ne.g. (0,eval)('code'). However, it also has the following additional options:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nWill capture both syntax errors from compiling code and runtime errors\nthrown by executing the compiled code. Defaults to true.
  • \n
  • timeout: a number of milliseconds to execute code before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "vm" }, { "textRaw": "Zlib", "name": "zlib", "stability": 2, "stabilityText": "Stable", "desc": "

You can access this module with:\n\n

\n
const zlib = require('zlib');
\n

This provides bindings to Gzip/Gunzip, Deflate/Inflate, and\nDeflateRaw/InflateRaw classes. Each class takes the same options, and\nis a readable/writable Stream.\n\n

\n

Examples

\n

Compressing or decompressing a file can be done by piping an\nfs.ReadStream into a zlib stream, then into an fs.WriteStream.\n\n

\n
const gzip = zlib.createGzip();\nconst fs = require('fs');\nconst inp = fs.createReadStream('input.txt');\nconst out = fs.createWriteStream('input.txt.gz');\n\ninp.pipe(gzip).pipe(out);
\n

Compressing or decompressing data in one step can be done by using\nthe convenience methods.\n\n

\n
const input = '.................................';\nzlib.deflate(input, function(err, buffer) {\n  if (!err) {\n    console.log(buffer.toString('base64'));\n  }\n});\n\nconst buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');\nzlib.unzip(buffer, function(err, buffer) {\n  if (!err) {\n    console.log(buffer.toString());\n  }\n});
\n

To use this module in an HTTP client or server, use the [accept-encoding][]\non requests, and the [content-encoding][] header on responses.\n\n

\n

Note: these examples are drastically simplified to show\nthe basic concept. Zlib encoding can be expensive, and the results\nought to be cached. See [Memory Usage Tuning][] below for more information\non the speed/memory/compression tradeoffs involved in zlib usage.\n\n

\n
// client request example\nconst zlib = require('zlib');\nconst http = require('http');\nconst fs = require('fs');\nconst request = http.get({ host: 'izs.me',\n                         path: '/',\n                         port: 80,\n                         headers: { 'accept-encoding': 'gzip,deflate' } });\nrequest.on('response', (response) => {\n  var output = fs.createWriteStream('izs.me_index.html');\n\n  switch (response.headers['content-encoding']) {\n    // or, just use zlib.createUnzip() to handle both cases\n    case 'gzip':\n      response.pipe(zlib.createGunzip()).pipe(output);\n      break;\n    case 'deflate':\n      response.pipe(zlib.createInflate()).pipe(output);\n      break;\n    default:\n      response.pipe(output);\n      break;\n  }\n});\n\n// server example\n// Running a gzip operation on every request is quite expensive.\n// It would be much more efficient to cache the compressed buffer.\nconst zlib = require('zlib');\nconst http = require('http');\nconst fs = require('fs');\nhttp.createServer((request, response) => {\n  var raw = fs.createReadStream('index.html');\n  var acceptEncoding = request.headers['accept-encoding'];\n  if (!acceptEncoding) {\n    acceptEncoding = '';\n  }\n\n  // Note: this is not a conformant accept-encoding parser.\n  // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3\n  if (acceptEncoding.match(/\\bdeflate\\b/)) {\n    response.writeHead(200, { 'content-encoding': 'deflate' });\n    raw.pipe(zlib.createDeflate()).pipe(response);\n  } else if (acceptEncoding.match(/\\bgzip\\b/)) {\n    response.writeHead(200, { 'content-encoding': 'gzip' });\n    raw.pipe(zlib.createGzip()).pipe(response);\n  } else {\n    response.writeHead(200, {});\n    raw.pipe(response);\n  }\n}).listen(1337);
\n", "miscs": [ { "textRaw": "Memory Usage Tuning", "name": "Memory Usage Tuning", "type": "misc", "desc": "

From zlib/zconf.h, modified to node.js's usage:\n\n

\n

The memory requirements for deflate are (in bytes):\n\n

\n
(1 << (windowBits+2)) +  (1 << (memLevel+9))
\n

that is: 128K for windowBits=15 + 128K for memLevel = 8\n(default values) plus a few kilobytes for small objects.\n\n

\n

For example, if you want to reduce\nthe default memory requirements from 256K to 128K, set the options to:\n\n

\n
{ windowBits: 14, memLevel: 7 }
\n

Of course this will generally degrade compression (there's no free lunch).\n\n

\n

The memory requirements for inflate are (in bytes)\n\n

\n
1 << windowBits
\n

that is, 32K for windowBits=15 (default value) plus a few kilobytes\nfor small objects.\n\n

\n

This is in addition to a single internal output slab buffer of size\nchunkSize, which defaults to 16K.\n\n

\n

The speed of zlib compression is affected most dramatically by the\nlevel setting. A higher level will result in better compression, but\nwill take longer to complete. A lower level will result in less\ncompression, but will be much faster.\n\n

\n

In general, greater memory usage options will mean that node.js has to make\nfewer calls to zlib, since it'll be able to process more data in a\nsingle write operation. So, this is another factor that affects the\nspeed, at the cost of memory usage.\n\n

\n" }, { "textRaw": "Constants", "name": "Constants", "type": "misc", "desc": "

All of the constants defined in zlib.h are also defined on\nrequire('zlib').\nIn the normal course of operations, you will not need to ever set any of\nthese. They are documented here so that their presence is not\nsurprising. This section is taken almost directly from the\n[zlib documentation][]. See http://zlib.net/manual.html#Constants for more\ndetails.\n\n

\n

Allowed flush values.\n\n

\n
    \n
  • zlib.Z_NO_FLUSH
  • \n
  • zlib.Z_PARTIAL_FLUSH
  • \n
  • zlib.Z_SYNC_FLUSH
  • \n
  • zlib.Z_FULL_FLUSH
  • \n
  • zlib.Z_FINISH
  • \n
  • zlib.Z_BLOCK
  • \n
  • zlib.Z_TREES
  • \n
\n

Return codes for the compression/decompression functions. Negative\nvalues are errors, positive values are used for special but normal\nevents.\n\n

\n
    \n
  • zlib.Z_OK
  • \n
  • zlib.Z_STREAM_END
  • \n
  • zlib.Z_NEED_DICT
  • \n
  • zlib.Z_ERRNO
  • \n
  • zlib.Z_STREAM_ERROR
  • \n
  • zlib.Z_DATA_ERROR
  • \n
  • zlib.Z_MEM_ERROR
  • \n
  • zlib.Z_BUF_ERROR
  • \n
  • zlib.Z_VERSION_ERROR
  • \n
\n

Compression levels.\n\n

\n
    \n
  • zlib.Z_NO_COMPRESSION
  • \n
  • zlib.Z_BEST_SPEED
  • \n
  • zlib.Z_BEST_COMPRESSION
  • \n
  • zlib.Z_DEFAULT_COMPRESSION
  • \n
\n

Compression strategy.\n\n

\n
    \n
  • zlib.Z_FILTERED
  • \n
  • zlib.Z_HUFFMAN_ONLY
  • \n
  • zlib.Z_RLE
  • \n
  • zlib.Z_FIXED
  • \n
  • zlib.Z_DEFAULT_STRATEGY
  • \n
\n

Possible values of the data_type field.\n\n

\n
    \n
  • zlib.Z_BINARY
  • \n
  • zlib.Z_TEXT
  • \n
  • zlib.Z_ASCII
  • \n
  • zlib.Z_UNKNOWN
  • \n
\n

The deflate compression method (the only one supported in this version).\n\n

\n
    \n
  • zlib.Z_DEFLATED
  • \n
\n

For initializing zalloc, zfree, opaque.\n\n

\n
    \n
  • zlib.Z_NULL
  • \n
\n" }, { "textRaw": "Class Options", "name": "Class Options", "type": "misc", "desc": "

Each class takes an options object. All options are optional.\n\n

\n

Note that some options are only relevant when compressing, and are\nignored by the decompression classes.\n\n

\n
    \n
  • flush (default: zlib.Z_NO_FLUSH)
  • \n
  • chunkSize (default: 16*1024)
  • \n
  • windowBits
  • \n
  • level (compression only)
  • \n
  • memLevel (compression only)
  • \n
  • strategy (compression only)
  • \n
  • dictionary (deflate/inflate only, empty dictionary by default)
  • \n
\n

See the description of deflateInit2 and inflateInit2 at\n

\n

http://zlib.net/manual.html#Advanced for more information on these.\n\n

\n" }, { "textRaw": "Convenience Methods", "name": "Convenience Methods", "type": "misc", "desc": "

All of these take a string or buffer as the first argument, an optional second\nargument to supply options to the zlib classes and will call the supplied\ncallback with callback(error, result).\n\n

\n

Every method has a *Sync counterpart, which accept the same arguments, but\nwithout a callback.\n\n

\n", "methods": [ { "textRaw": "zlib.deflate(buf[, options], callback)", "type": "method", "name": "deflate", "desc": "

Compress a string with Deflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.deflateRaw(buf[, options], callback)", "type": "method", "name": "deflateRaw", "desc": "

Compress a string with DeflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.deflateRawSync(buf[, options])", "type": "method", "name": "deflateRawSync", "desc": "

Compress a string with DeflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.deflateSync(buf[, options])", "type": "method", "name": "deflateSync", "desc": "

Compress a string with Deflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.gunzip(buf[, options], callback)", "type": "method", "name": "gunzip", "desc": "

Decompress a raw Buffer with Gunzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.gunzipSync(buf[, options])", "type": "method", "name": "gunzipSync", "desc": "

Decompress a raw Buffer with Gunzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.gzip(buf[, options], callback)", "type": "method", "name": "gzip", "desc": "

Compress a string with Gzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.gzipSync(buf[, options])", "type": "method", "name": "gzipSync", "desc": "

Compress a string with Gzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.inflate(buf[, options], callback)", "type": "method", "name": "inflate", "desc": "

Decompress a raw Buffer with Inflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.inflateRaw(buf[, options], callback)", "type": "method", "name": "inflateRaw", "desc": "

Decompress a raw Buffer with InflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.inflateRawSync(buf[, options])", "type": "method", "name": "inflateRawSync", "desc": "

Decompress a raw Buffer with InflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.inflateSync(buf[, options])", "type": "method", "name": "inflateSync", "desc": "

Decompress a raw Buffer with Inflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.unzip(buf[, options], callback)", "type": "method", "name": "unzip", "desc": "

Decompress a raw Buffer with Unzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.unzipSync(buf[, options])", "type": "method", "name": "unzipSync", "desc": "

Decompress a raw Buffer with Unzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] } ] } ], "classes": [ { "textRaw": "Class: zlib.Deflate", "type": "class", "name": "zlib.Deflate", "desc": "

Compress data using deflate.\n\n

\n" }, { "textRaw": "Class: zlib.DeflateRaw", "type": "class", "name": "zlib.DeflateRaw", "desc": "

Compress data using deflate, and do not append a zlib header.\n\n

\n" }, { "textRaw": "Class: zlib.Gunzip", "type": "class", "name": "zlib.Gunzip", "desc": "

Decompress a gzip stream.\n\n

\n" }, { "textRaw": "Class: zlib.Gzip", "type": "class", "name": "zlib.Gzip", "desc": "

Compress data using gzip.\n\n

\n" }, { "textRaw": "Class: zlib.Inflate", "type": "class", "name": "zlib.Inflate", "desc": "

Decompress a deflate stream.\n\n

\n" }, { "textRaw": "Class: zlib.InflateRaw", "type": "class", "name": "zlib.InflateRaw", "desc": "

Decompress a raw deflate stream.\n\n

\n" }, { "textRaw": "Class: zlib.Unzip", "type": "class", "name": "zlib.Unzip", "desc": "

Decompress either a Gzip- or Deflate-compressed stream by auto-detecting\nthe header.\n\n

\n" }, { "textRaw": "Class: zlib.Zlib", "type": "class", "name": "zlib.Zlib", "desc": "

Not exported by the zlib module. It is documented here because it is the base\nclass of the compressor/decompressor classes.\n\n

\n", "methods": [ { "textRaw": "zlib.flush([kind], callback)", "type": "method", "name": "flush", "desc": "

kind defaults to zlib.Z_FULL_FLUSH.\n\n

\n

Flush pending data. Don't call this frivolously, premature flushes negatively\nimpact the effectiveness of the compression algorithm.\n\n

\n", "signatures": [ { "params": [ { "name": "kind", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.params(level, strategy, callback)", "type": "method", "name": "params", "desc": "

Dynamically update the compression level and compression strategy.\nOnly applicable to deflate algorithm.\n\n

\n", "signatures": [ { "params": [ { "name": "level" }, { "name": "strategy" }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.reset()", "type": "method", "name": "reset", "desc": "

Reset the compressor/decompressor to factory defaults. Only applicable to\nthe inflate and deflate algorithms.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "zlib.createDeflate([options])", "type": "method", "name": "createDeflate", "desc": "

Returns a new [Deflate][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createDeflateRaw([options])", "type": "method", "name": "createDeflateRaw", "desc": "

Returns a new [DeflateRaw][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createGunzip([options])", "type": "method", "name": "createGunzip", "desc": "

Returns a new [Gunzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createGzip([options])", "type": "method", "name": "createGzip", "desc": "

Returns a new [Gzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createInflate([options])", "type": "method", "name": "createInflate", "desc": "

Returns a new [Inflate][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createInflateRaw([options])", "type": "method", "name": "createInflateRaw", "desc": "

Returns a new [InflateRaw][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createUnzip([options])", "type": "method", "name": "createUnzip", "desc": "

Returns a new [Unzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "Zlib" } ], "stability": 2, "stabilityText": "Stable", "classes": [ { "textRaw": "Class: Error", "type": "class", "name": "Error", "desc": "

A generic JavaScript Error object that does not denote any specific\ncircumstance of why the error occurred. Error objects capture a "stack trace"\ndetailing the point in the code at which the Error was instantiated, and may\nprovide a text description of the error.\n\n

\n

All errors generated by Node.js, including all System and JavaScript errors,\nwill either be instances of, or inherit from, the Error class.\n\n

\n", "methods": [ { "textRaw": "Error.captureStackTrace(targetObject[, constructorOpt])", "type": "method", "name": "captureStackTrace", "desc": "

Creates a .stack property on targetObject, which when accessed returns\na string representing the location in the code at which\nError.captureStackTrace() was called.\n\n

\n
const myObject = {};\nError.captureStackTrace(myObject);\nmyObject.stack  // similar to `new Error().stack`
\n

The first line of the trace, instead of being prefixed with ErrorType:\nmessage, will be the result of calling targetObject.toString().\n\n

\n

The optional constructorOpt argument accepts a function. If given, all frames\nabove constructorOpt, including constructorOpt, will be omitted from the\ngenerated stack trace.\n\n

\n

The constructorOpt argument is useful for hiding implementation\ndetails of error generation from an end user. For instance:\n\n

\n
function MyError() {\n  Error.captureStackTrace(this, MyError);\n}\n\n// Without passing MyError to captureStackTrace, the MyError\n// frame would should up in the .stack property. by passing\n// the constructor, we omit that frame and all frames above it.\nnew MyError().stack
\n", "signatures": [ { "params": [ { "name": "targetObject" }, { "name": "constructorOpt", "optional": true } ] } ] } ], "properties": [ { "textRaw": "Error.stackTraceLimit", "name": "stackTraceLimit", "desc": "

The Error.stackTraceLimit property specifies the number of stack frames\ncollected by a stack trace (whether generated by new Error().stack or\nError.captureStackTrace(obj)).\n\n

\n

The default value is 10 but may be set to any valid JavaScript number. Changes\nwill affect any stack trace captured after the value has been changed.\n\n

\n

If set to a non-number value, or set to a negative number, stack traces will\nnot capture any frames.\n\n

\n", "properties": [ { "textRaw": "error.message", "name": "message", "desc": "

Returns the string description of error as set by calling new Error(message).\nThe message passed to the constructor will also appear in the first line of\nthe stack trace of the Error, however changing this property after the\nError object is created may not change the first line of the stack trace.\n\n

\n
const err = new Error('The message');\nconsole.log(err.message);\n  // Prints: The message
\n" }, { "textRaw": "error.stack", "name": "stack", "desc": "

Returns a string describing the point in the code at which the Error was\ninstantiated.\n\n

\n

For example:\n\n

\n
Error: Things keep happening!\n   at /home/gbusey/file.js:525:2\n   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)\n   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)\n   at increaseSynergy (/home/gbusey/actors.js:701:6)
\n

The first line is formatted as <error class name>: <error message>, and\nis followed by a series of stack frames (each line beginning with "at ").\nEach frame describes a call site within the code that lead to the error being\ngenerated. V8 attempts to display a name for each function (by variable name,\nfunction name, or object method name), but occasionally it will not be able to\nfind a suitable name. If V8 cannot determine a name for the function, only\nlocation information will be displayed for that frame. Otherwise, the\ndetermined function name will be displayed with location information appended\nin parentheses.\n\n

\n

It is important to note that frames are only generated for JavaScript\nfunctions. If, for example, execution synchronously passes through a C++ addon\nfunction called cheetahify, which itself calls a JavaScript function, the\nframe representing the cheetahify call will not be present in the stack\ntraces:\n\n

\n
const cheetahify = require('./native-binding.node');\n\nfunction makeFaster() {\n  // cheetahify *synchronously* calls speedy.\n  cheetahify(function speedy() {\n    throw new Error('oh no!');\n  });\n}\n\nmakeFaster(); // will throw:\n  // /home/gbusey/file.js:6\n  //     throw new Error('oh no!');\n  //           ^\n  // Error: oh no!\n  //     at speedy (/home/gbusey/file.js:6:11)\n  //     at makeFaster (/home/gbusey/file.js:5:3)\n  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)\n  //     at Module._compile (module.js:456:26)\n  //     at Object.Module._extensions..js (module.js:474:10)\n  //     at Module.load (module.js:356:32)\n  //     at Function.Module._load (module.js:312:12)\n  //     at Function.Module.runMain (module.js:497:10)\n  //     at startup (node.js:119:16)\n  //     at node.js:906:3
\n

The location information will be one of:\n\n

\n
    \n
  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • \n
  • plain-filename.js:line:column, if the frame represents a call internal\n to Node.js.
  • \n
  • /absolute/path/to/file.js:line:column, if the frame represents a call in\na user program, or its dependencies.
  • \n
\n

The string representing the stack trace is lazily generated when the\nerror.stack property is accessed.\n\n

\n

The number of frames captured by the stack trace is bounded by the smaller of\nError.stackTraceLimit or the number of available frames on the current event\nloop tick.\n\n

\n

System-level errors are generated as augmented Error instances, which are\ndetailed below.\n\n

\n" } ] } ], "signatures": [ { "params": [ { "name": "message" } ], "desc": "

Creates a new Error object and sets the error.message property to the\nprovided text message. If an object is passed as message, the text message\nis generated by calling message.toString(). The error.stack property will\nrepresent the point in the code at which new Error() was called. Stack traces\nare dependent on [V8's stack trace API][]. Stack traces extend only to either\n(a) the beginning of synchronous code execution, or (b) the number of frames\ngiven by the property Error.stackTraceLimit, whichever is smaller.\n\n

\n" } ] }, { "textRaw": "Class: RangeError", "type": "class", "name": "RangeError", "desc": "

A subclass of Error that indicates that a provided argument was not within the\nset or range of acceptable values for a function; whether that is a numeric\nrange, or outside the set of options for a given function parameter.\n\n

\n

For example:\n\n

\n
require('net').connect(-1);\n  // throws RangeError, port should be > 0 && < 65536
\n

Node.js will generate and throw RangeError instances immediately as a form\nof argument validation.\n\n

\n" }, { "textRaw": "Class: ReferenceError", "type": "class", "name": "ReferenceError", "desc": "

A subclass of Error that indicates that an attempt is being made to access a\nvariable that is not defined. Such errors commonly indicate typos in code, or\nan otherwise broken program.\n\n

\n

While client code may generate and propagate these errors, in practice, only V8\nwill do so.\n\n

\n
doesNotExist;\n  // throws ReferenceError, doesNotExist is not a variable in this program.
\n

ReferenceError instances will have an error.arguments property whose value\nis an array containing a single element: a string representing the variable\nthat was not defined.\n\n

\n
const assert = require('assert');\ntry {\n  doesNotExist;\n} catch(err) {\n  assert(err.arguments[0], 'doesNotExist');\n}
\n

Unless an application is dynamically generating and running code,\nReferenceError instances should always be considered a bug in the code\nor its dependencies.\n\n

\n" }, { "textRaw": "Class: SyntaxError", "type": "class", "name": "SyntaxError", "desc": "

A subclass of Error that indicates that a program is not valid JavaScript.\nThese errors may only be generated and propagated as a result of code\nevaluation. Code evaluation may happen as a result of eval, Function,\nrequire, or [vm][]. These errors are almost always indicative of a broken\nprogram.\n\n

\n
try {\n  require('vm').runInThisContext('binary ! isNotOk');\n} catch(err) {\n  // err will be a SyntaxError\n}
\n

SyntaxError instances are unrecoverable in the context that created them –\nthey may only be caught by other contexts.\n\n

\n" }, { "textRaw": "Class: TypeError", "type": "class", "name": "TypeError", "desc": "

A subclass of Error that indicates that a provided argument is not an\nallowable type. For example, passing a function to a parameter which expects a\nstring would be considered a TypeError.\n\n

\n
require('url').parse(function() { });\n  // throws TypeError, since it expected a string
\n

Node.js will generate and throw TypeError instances immediately as a form\nof argument validation.\n\n

\n" } ], "globals": [ { "textRaw": "Class: Buffer", "type": "global", "name": "Buffer", "desc": "

Used to handle binary data. See the [buffer section][].\n\n

\n" }, { "textRaw": "clearInterval(t)", "type": "global", "name": "clearInterval", "desc": "

Stop a timer that was previously created with [setInterval()][]. The callback\nwill not execute.\n\n

\n

The timer functions are global variables. See the [timers][] section.\n\n

\n" }, { "textRaw": "console", "name": "console", "type": "global", "desc": "

Used to print to stdout and stderr. See the [console][] section.\n\n

\n" }, { "textRaw": "global", "name": "global", "type": "global", "desc": "

In browsers, the top-level scope is the global scope. That means that in\nbrowsers if you're in the global scope var something will define a global\nvariable. In Node.js this is different. The top-level scope is not the global\nscope; var something inside an Node.js module will be local to that module.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object. See the [process object][] section.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object is a global object and can be accessed from anywhere.\nIt is an instance of [EventEmitter][].\n\n

\n", "events": [ { "textRaw": "Event: 'beforeExit'", "type": "event", "name": "beforeExit", "desc": "

This event is emitted when Node.js empties its event loop and has nothing else to\nschedule. Normally, Node.js exits when there is no work scheduled, but a listener\nfor 'beforeExit' can make asynchronous calls, and cause Node.js to continue.\n\n

\n

'beforeExit' is not emitted for conditions causing explicit termination, such as\n[process.exit()][] or uncaught exceptions, and should not be used as an\nalternative to the 'exit' event unless the intention is to schedule more work.\n\n

\n", "params": [] }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "desc": "

Emitted when the process is about to exit. There is no way to prevent the\nexiting of the event loop at this point, and once all 'exit' listeners have\nfinished running the process will exit. Therefore you must only perform\nsynchronous operations in this handler. This is a good hook to perform\nchecks on the module's state (like for unit tests). The callback takes one\nargument, the code the process is exiting with.\n\n

\n

This event is only emitted when Node.js exits explicitly by process.exit() or\nimplicitly by the event loop draining.\n\n

\n

Example of listening for 'exit':\n\n

\n
process.on('exit', (code) => {\n  // do *NOT* do this\n  setTimeout(() => {\n    console.log('This will not run');\n  }, 0);\n  console.log('About to exit with code:', code);\n});
\n", "params": [] }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Messages sent by [ChildProcess.send()][] are obtained using the 'message'\nevent on the child's process object.\n\n

\n" }, { "textRaw": "Event: 'rejectionHandled'", "type": "event", "name": "rejectionHandled", "desc": "

Emitted whenever a Promise was rejected and an error handler was attached to it\n(for example with .catch()) later than after an event loop turn. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • p the promise that was previously emitted in an 'unhandledRejection'\nevent, but which has now gained a rejection handler.
  • \n
\n

There is no notion of a top level for a promise chain at which rejections can\nalways be handled. Being inherently asynchronous in nature, a promise rejection\ncan be be handled at a future point in time — possibly much later than the\nevent loop turn it takes for the 'unhandledRejection' event to be emitted.\n\n

\n

Another way of stating this is that, unlike in synchronous code where there is\nan ever-growing list of unhandled exceptions, with promises there is a\ngrowing-and-shrinking list of unhandled rejections. In synchronous code, the\n'uncaughtException' event tells you when the list of unhandled exceptions\ngrows. And in asynchronous code, the 'unhandledRejection' event tells you\nwhen the list of unhandled rejections grows, while the 'rejectionHandled'\nevent tells you when the list of unhandled rejections shrinks.\n\n

\n

For example using the rejection detection hooks in order to keep a map of all\nthe rejected promise reasons at a given time:\n\n

\n
const unhandledRejections = new Map();\nprocess.on('unhandledRejection', (reason, p) => {\n  unhandledRejections.set(p, reason);\n});\nprocess.on('rejectionHandled', (p) => {\n  unhandledRejections.delete(p);\n});
\n

This map will grow and shrink over time, reflecting rejections that start\nunhandled and then become handled. You could record the errors in some error\nlog, either periodically (probably best for long-running programs, allowing\nyou to clear the map, which in the case of a very buggy program could grow\nindefinitely) or upon process exit (more convenient for scripts).\n\n

\n", "params": [] }, { "textRaw": "Event: 'uncaughtException'", "type": "event", "name": "uncaughtException", "desc": "

Emitted when an exception bubbles all the way back to the event loop. If a\nlistener is added for this exception, the default action (which is to print\na stack trace and exit) will not occur.\n\n

\n

Example of listening for 'uncaughtException':\n\n

\n
process.on('uncaughtException', (err) => {\n  console.log(`Caught exception: ${err}`);\n});\n\nsetTimeout(() => {\n  console.log('This will still run.');\n}, 500);\n\n// Intentionally cause an exception, but don't catch it.\nnonexistentFunc();\nconsole.log('This will not run.');
\n

Note that 'uncaughtException' is a very crude mechanism for exception\nhandling.\n\n

\n

Do not use it as the Node.js equivalent of On Error Resume Next. An\nunhandled exception means your application - and by extension Node.js itself -\nis in an undefined state. Blindly resuming means anything could happen.\n\n

\n

Think of resuming as pulling the power cord when you are upgrading your system.\nNine out of ten times nothing happens - but the 10th time, your system is bust.\n\n

\n

'uncaughtException' should be used to perform synchronous cleanup before\nshutting down the process. It is not safe to resume normal operation after\n'uncaughtException'. If you do use it, restart your application after every\nunhandled exception!\n\n

\n

You have been warned.\n\n

\n", "params": [] }, { "textRaw": "Event: 'unhandledRejection'", "type": "event", "name": "unhandledRejection", "desc": "

Emitted whenever a Promise is rejected and no error handler is attached to\nthe promise within a turn of the event loop. When programming with promises\nexceptions are encapsulated as rejected promises. Such promises can be caught\nand handled using [promise.catch(...)][] and rejections are propagated through\na promise chain. This event is useful for detecting and keeping track of\npromises that were rejected whose rejections were not handled yet. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • reason the object with which the promise was rejected (usually an [Error][]\ninstance).
  • \n
  • p the promise that was rejected.
  • \n
\n

Here is an example that logs every unhandled rejection to the console\n\n

\n
process.on('unhandledRejection', (reason, p) => {\n    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);\n    // application specific logging, throwing an error, or other logic here\n});
\n

For example, here is a rejection that will trigger the 'unhandledRejection'\nevent:\n\n

\n
somePromise.then((res) => {\n  return reportToUser(JSON.parse(res)); // note the typo\n}); // no `.catch` or `.then`
\n

Here is an example of a coding pattern that will also trigger\n'unhandledRejection':\n\n

\n
function SomeResource() {\n  // Initially set the loaded status to a rejected promise\n  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));\n}\n\nvar resource = new SomeResource();\n// no .catch or .then on resource.loaded for at least a turn
\n

In cases like this, you may not want to track the rejection as a developer\nerror like you would for other 'unhandledRejection' events. To address\nthis, you can either attach a dummy .catch(function() { }) handler to\nresource.loaded, preventing the 'unhandledRejection' event from being\nemitted, or you can use the 'rejectionHandled' event. Below is an\nexplanation of how to do that.\n\n

\n", "params": [] }, { "textRaw": "Signal Events", "name": "SIGINT, SIGHUP, etc.", "type": "event", "desc": "

Emitted when the processes receives a signal. See sigaction(2) for a list of\nstandard POSIX signal names such as SIGINT, SIGHUP, etc.\n\n

\n

Example of listening for SIGINT:\n\n

\n
// Start reading from stdin so we don't exit.\nprocess.stdin.resume();\n\nprocess.on('SIGINT', () => {\n  console.log('Got SIGINT.  Press Control-D to exit.');\n});
\n

An easy way to send the SIGINT signal is with Control-C in most terminal\nprograms.\n\n

\n

Note:\n\n

\n
    \n
  • SIGUSR1 is reserved by Node.js to start the debugger. It's possible to\ninstall a listener but that won't stop the debugger from starting.
  • \n
  • SIGTERM and SIGINT have default handlers on non-Windows platforms that resets\nthe terminal mode before exiting with code 128 + signal number. If one of\nthese signals has a listener installed, its default behavior will be removed\n(Node.js will no longer exit).
  • \n
  • SIGPIPE is ignored by default. It can have a listener installed.
  • \n
  • SIGHUP is generated on Windows when the console window is closed, and on other\nplatforms under various similar conditions, see signal(7). It can have a\nlistener installed, however Node.js will be unconditionally terminated by\nWindows about 10 seconds later. On non-Windows platforms, the default\nbehavior of SIGHUP is to terminate Node.js, but once a listener has been\ninstalled its default behavior will be removed.
  • \n
  • SIGTERM is not supported on Windows, it can be listened on.
  • \n
  • SIGINT from the terminal is supported on all platforms, and can usually be\ngenerated with CTRL+C (though this may be configurable). It is not generated\nwhen terminal raw mode is enabled.
  • \n
  • SIGBREAK is delivered on Windows when CTRL+BREAK is pressed, on non-Windows\nplatforms it can be listened on, but there is no way to send or generate it.
  • \n
  • SIGWINCH is delivered when the console has been resized. On Windows, this will\nonly happen on write to the console when the cursor is being moved, or when a\nreadable tty is used in raw mode.
  • \n
  • SIGKILL cannot have a listener installed, it will unconditionally terminate\nNode.js on all platforms.
  • \n
  • SIGSTOP cannot have a listener installed.
  • \n
\n

Note that Windows does not support sending Signals, but Node.js offers some\nemulation with process.kill(), and child_process.kill(). Sending signal 0\ncan be used to test for the existence of a process. Sending SIGINT,\nSIGTERM, and SIGKILL cause the unconditional termination of the target\nprocess.\n\n

\n", "params": [] } ], "modules": [ { "textRaw": "Exit Codes", "name": "exit_codes", "desc": "

Node.js will normally exit with a 0 status code when no more async\noperations are pending. The following status codes are used in other\ncases:\n\n

\n
    \n
  • 1 Uncaught Fatal Exception - There was an uncaught exception,\nand it was not handled by a domain or an 'uncaughtException' event\nhandler.
  • \n
  • 2 - Unused (reserved by Bash for builtin misuse)
  • \n
  • 3 Internal JavaScript Parse Error - The JavaScript source code\ninternal in Node.js's bootstrapping process caused a parse error. This\nis extremely rare, and generally can only happen during development\nof Node.js itself.
  • \n
  • 4 Internal JavaScript Evaluation Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process failed to\nreturn a function value when evaluated. This is extremely rare, and\ngenerally can only happen during development of Node.js itself.
  • \n
  • 5 Fatal Error - There was a fatal unrecoverable error in V8.\nTypically a message will be printed to stderr with the prefix FATAL\nERROR.
  • \n
  • 6 Non-function Internal Exception Handler - There was an\nuncaught exception, but the internal fatal exception handler\nfunction was somehow set to a non-function, and could not be called.
  • \n
  • 7 Internal Exception Handler Run-Time Failure - There was an\nuncaught exception, and the internal fatal exception handler\nfunction itself threw an error while attempting to handle it. This\ncan happen, for example, if a process.on('uncaughtException') or\ndomain.on('error') handler throws an error.
  • \n
  • 8 - Unused. In previous versions of Node.js, exit code 8 sometimes\nindicated an uncaught exception.
  • \n
  • 9 - Invalid Argument - Either an unknown option was specified,\nor an option requiring a value was provided without a value.
  • \n
  • 10 Internal JavaScript Run-Time Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process threw an error\nwhen the bootstrapping function was called. This is extremely rare,\nand generally can only happen during development of Node.js itself.
  • \n
  • 12 Invalid Debug Argument - The --debug and/or --debug-brk\noptions were set, but an invalid port number was chosen.
  • \n
  • >128 Signal Exits - If Node.js receives a fatal signal such as\nSIGKILL or SIGHUP, then its exit code will be 128 plus the\nvalue of the signal code. This is a standard Unix practice, since\nexit codes are defined to be 7-bit integers, and signal exits set\nthe high-order bit, and then contain the value of the signal code.
  • \n
\n", "type": "module", "displayName": "Exit Codes" } ], "methods": [ { "textRaw": "process.abort()", "type": "method", "name": "abort", "desc": "

This causes Node.js to emit an abort. This will cause Node.js to exit and\ngenerate a core file.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.chdir(directory)", "type": "method", "name": "chdir", "desc": "

Changes the current working directory of the process or throws an exception if that fails.\n\n

\n
console.log(`Starting directory: ${process.cwd()}`);\ntry {\n  process.chdir('/tmp');\n  console.log(`New directory: ${process.cwd()}`);\n}\ncatch (err) {\n  console.log(`chdir: ${err}`);\n}
\n", "signatures": [ { "params": [ { "name": "directory" } ] } ] }, { "textRaw": "process.cwd()", "type": "method", "name": "cwd", "desc": "

Returns the current working directory of the process.\n\n

\n
console.log(`Current directory: ${process.cwd()}`);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.disconnect()", "type": "method", "name": "disconnect", "desc": "

Close the IPC channel to the parent process, allowing this child to exit\ngracefully once there are no other connections keeping it alive.\n\n

\n

Identical to the parent process's [ChildProcess.disconnect()][].\n\n

\n

If Node.js was not spawned with an IPC channel, process.disconnect() will be\nundefined.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.exit([code])", "type": "method", "name": "exit", "desc": "

Ends the process with the specified code. If omitted, exit uses the\n'success' code 0.\n\n

\n

To exit with a 'failure' code:\n\n

\n
process.exit(1);
\n

The shell that executed Node.js should see the exit code as 1.\n\n\n

\n", "signatures": [ { "params": [ { "name": "code", "optional": true } ] } ] }, { "textRaw": "process.getegid()", "type": "method", "name": "getegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective group identity of the process. (See getegid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.geteuid()", "type": "method", "name": "geteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective user identity of the process. (See geteuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.geteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgid()", "type": "method", "name": "getgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the group identity of the process. (See getgid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgroups()", "type": "method", "name": "getgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Returns an array with the supplementary group IDs. POSIX leaves it unspecified\nif the effective group ID is included but Node.js ensures it always is.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getuid()", "type": "method", "name": "getuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the user identity of the process. (See getuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.getuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.hrtime()", "type": "method", "name": "hrtime", "desc": "

Returns the current high-resolution real time in a [seconds, nanoseconds]\ntuple Array. It is relative to an arbitrary time in the past. It is not\nrelated to the time of day and therefore not subject to clock drift. The\nprimary use is for measuring performance between intervals.\n\n

\n

You may pass in the result of a previous call to process.hrtime() to get\na diff reading, useful for benchmarks and measuring intervals:\n\n

\n
var time = process.hrtime();\n// [ 1800216, 25 ]\n\nsetTimeout(() => {\n  var diff = process.hrtime(time);\n  // [ 1, 552 ]\n\n  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);\n  // benchmark took 1000000527 nanoseconds\n}, 1000);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.initgroups(user, extra_group)", "type": "method", "name": "initgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Reads /etc/group and initializes the group access list, using all groups of\nwhich the user is a member. This is a privileged operation, meaning you need\nto be root or have the CAP_SETGID capability.\n\n

\n

user is a user name or user ID. extra_group is a group name or group ID.\n\n

\n

Some care needs to be taken when dropping privileges. Example:\n\n

\n
console.log(process.getgroups());         // [ 0 ]\nprocess.initgroups('bnoordhuis', 1000);   // switch user\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]\nprocess.setgid(1000);                     // drop root gid\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000 ]
\n", "signatures": [ { "params": [ { "name": "user" }, { "name": "extra_group" } ] } ] }, { "textRaw": "process.kill(pid[, signal])", "type": "method", "name": "kill", "desc": "

Send a signal to a process. pid is the process id and signal is the\nstring describing the signal to send. Signal names are strings like\nSIGINT or SIGHUP. If omitted, the signal will be SIGTERM.\nSee [Signal Events][] and kill(2) for more information.\n\n

\n

Will throw an error if target does not exist, and as a special case, a signal\nof 0 can be used to test for the existence of a process. Windows platforms\nwill throw an error if the pid is used to kill a process group.\n\n

\n

Note that even though the name of this function is process.kill, it is really\njust a signal sender, like the kill system call. The signal sent may do\nsomething other than kill the target process.\n\n

\n

Example of sending a signal to yourself:\n\n

\n
process.on('SIGHUP', () => {\n  console.log('Got SIGHUP signal.');\n});\n\nsetTimeout(() => {\n  console.log('Exiting.');\n  process.exit(0);\n}, 100);\n\nprocess.kill(process.pid, 'SIGHUP');
\n

Note: When SIGUSR1 is received by Node.js it starts the debugger, see\n[Signal Events][].\n\n

\n", "signatures": [ { "params": [ { "name": "pid" }, { "name": "signal", "optional": true } ] } ] }, { "textRaw": "process.memoryUsage()", "type": "method", "name": "memoryUsage", "desc": "

Returns an object describing the memory usage of the Node.js process\nmeasured in bytes.\n\n

\n
const util = require('util');\n\nconsole.log(util.inspect(process.memoryUsage()));
\n

This will generate:\n\n

\n
{ rss: 4935680,\n  heapTotal: 1826816,\n  heapUsed: 650472 }
\n

heapTotal and heapUsed refer to V8's memory usage.\n\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.nextTick(callback[, arg][, ...])", "type": "method", "name": "nextTick", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] }, { "params": [ { "name": "callback" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ], "desc": "

Once the current event loop turn runs to completion, call the callback\nfunction.\n\n

\n

This is not a simple alias to [setTimeout(fn, 0)][], it's much more\nefficient. It runs before any additional I/O events (including\ntimers) fire in subsequent ticks of the event loop.\n\n

\n
console.log('start');\nprocess.nextTick(() => {\n  console.log('nextTick callback');\n});\nconsole.log('scheduled');\n// Output:\n// start\n// scheduled\n// nextTick callback
\n

This is important in developing APIs where you want to give the user the\nchance to assign event handlers after an object has been constructed,\nbut before any I/O has occurred.\n\n

\n
function MyThing(options) {\n  this.setupOptions(options);\n\n  process.nextTick(() => {\n    this.startDoingStuff();\n  }.bind(this));\n}\n\nvar thing = new MyThing();\nthing.getReadyForStuff();\n\n// thing.startDoingStuff() gets called now, not before.
\n

It is very important for APIs to be either 100% synchronous or 100%\nasynchronous. Consider this example:\n\n

\n
// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!\nfunction maybeSync(arg, cb) {\n  if (arg) {\n    cb();\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

This API is hazardous. If you do this:\n\n

\n
maybeSync(true, function() {\n  foo();\n});\nbar();
\n

then it's not clear whether foo() or bar() will be called first.\n\n

\n

This approach is much better:\n\n

\n
function definitelyAsync(arg, cb) {\n  if (arg) {\n    process.nextTick(cb);\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

Note: the nextTick queue is completely drained on each pass of the\nevent loop before additional I/O is processed. As a result,\nrecursively setting nextTick callbacks will block any I/O from\nhappening, just like a while(true); loop.\n\n

\n" }, { "textRaw": "process.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

When Node.js is spawned with an IPC channel attached, it can send messages to its\nparent process using process.send(). Each will be received as a\n['message'][] event on the parent's ChildProcess object.\n\n

\n

If Node.js was not spawned with an IPC channel, process.send() will be undefined.\n\n

\n" }, { "textRaw": "process.setegid(id)", "type": "method", "name": "setegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective group identity of the process. (See setegid(2).)\nThis accepts either a numerical ID or a groupname string. If a groupname\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.getegid && process.setegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n  try {\n    process.setegid(501);\n    console.log(`New gid: ${process.getegid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.seteuid(id)", "type": "method", "name": "seteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective user identity of the process. (See seteuid(2).)\nThis accepts either a numerical ID or a username string. If a username\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.geteuid && process.seteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n  try {\n    process.seteuid(501);\n    console.log(`New uid: ${process.geteuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgid(id)", "type": "method", "name": "setgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the group identity of the process. (See setgid(2).) This accepts either\na numerical ID or a groupname string. If a groupname is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getgid && process.setgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n  try {\n    process.setgid(501);\n    console.log(`New gid: ${process.getgid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgroups(groups)", "type": "method", "name": "setgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the supplementary group IDs. This is a privileged operation, meaning you\nneed to be root or have the CAP_SETGID capability.\n\n

\n

The list can contain group IDs, group names or both.\n\n

\n", "signatures": [ { "params": [ { "name": "groups" } ] } ] }, { "textRaw": "process.setuid(id)", "type": "method", "name": "setuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the user identity of the process. (See setuid(2).) This accepts either\na numerical ID or a username string. If a username is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getuid && process.setuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n  try {\n    process.setuid(501);\n    console.log(`New uid: ${process.getuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.umask([mask])", "type": "method", "name": "umask", "desc": "

Sets or reads the process's file mode creation mask. Child processes inherit\nthe mask from the parent process. Returns the old mask if mask argument is\ngiven, otherwise returns the current mask.\n\n

\n
const newmask = 0o022;\nconst oldmask = process.umask(newmask);\nconsole.log(\n  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`\n);
\n", "signatures": [ { "params": [ { "name": "mask", "optional": true } ] } ] }, { "textRaw": "process.uptime()", "type": "method", "name": "uptime", "desc": "

Number of seconds Node.js has been running.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "process.arch", "name": "arch", "desc": "

What processor architecture you're running on: 'arm', 'ia32', or 'x64'.\n\n

\n
console.log('This processor architecture is ' + process.arch);
\n" }, { "textRaw": "process.argv", "name": "argv", "desc": "

An array containing the command line arguments. The first element will be\n'node', the second element will be the name of the JavaScript file. The\nnext elements will be any additional command line arguments.\n\n

\n
// print process.argv\nprocess.argv.forEach((val, index, array) => {\n  console.log(`${index}: ${val}`);\n});
\n

This will generate:\n\n

\n
$ node process-2.js one two=three four\n0: node\n1: /Users/mjr/work/node/process-2.js\n2: one\n3: two=three\n4: four
\n" }, { "textRaw": "process.config", "name": "config", "desc": "

An Object containing the JavaScript representation of the configure options\nthat were used to compile the current Node.js executable. This is the same as\nthe config.gypi file that was produced when running the ./configure script.\n\n

\n

An example of the possible output looks like:\n\n

\n
{ target_defaults:\n   { cflags: [],\n     default_configuration: 'Release',\n     defines: [],\n     include_dirs: [],\n     libraries: [] },\n  variables:\n   { host_arch: 'x64',\n     node_install_npm: 'true',\n     node_prefix: '',\n     node_shared_cares: 'false',\n     node_shared_http_parser: 'false',\n     node_shared_libuv: 'false',\n     node_shared_zlib: 'false',\n     node_use_dtrace: 'false',\n     node_use_openssl: 'true',\n     node_shared_openssl: 'false',\n     strict_aliasing: 'true',\n     target_arch: 'x64',\n     v8_use_snapshot: 'true' } }
\n", "properties": [ { "textRaw": "`connected` {Boolean} Set to false after `process.disconnect()` is called ", "name": "connected", "desc": "

If process.connected is false, it is no longer possible to send messages.\n\n

\n", "shortDesc": "Set to false after `process.disconnect()` is called" } ] }, { "textRaw": "process.env", "name": "env", "desc": "

An object containing the user environment. See environ(7).\n\n

\n

An example of this object looks like:\n\n

\n
{ TERM: 'xterm-256color',\n  SHELL: '/usr/local/bin/bash',\n  USER: 'maciej',\n  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',\n  PWD: '/Users/maciej',\n  EDITOR: 'vim',\n  SHLVL: '1',\n  HOME: '/Users/maciej',\n  LOGNAME: 'maciej',\n  _: '/usr/local/bin/node' }
\n

You can write to this object, but changes won't be reflected outside of your\nprocess. That means that the following won't work:\n\n

\n
$ node -e 'process.env.foo = "bar"' && echo $foo
\n

But this will:\n\n

\n
process.env.foo = 'bar';\nconsole.log(process.env.foo);
\n" }, { "textRaw": "process.execArgv", "name": "execArgv", "desc": "

This is the set of Node.js-specific command line options from the\nexecutable that started the process. These options do not show up in\nprocess.argv, and do not include the Node.js executable, the name of\nthe script, or any options following the script name. These options\nare useful in order to spawn child processes with the same execution\nenvironment as the parent.\n\n

\n

Example:\n\n

\n
$ node --harmony script.js --version
\n

results in process.execArgv:\n\n

\n
['--harmony']
\n

and process.argv:\n\n

\n
['/usr/local/bin/node', 'script.js', '--version']
\n" }, { "textRaw": "process.execPath", "name": "execPath", "desc": "

This is the absolute pathname of the executable that started the process.\n\n

\n

Example:\n\n

\n
/usr/local/bin/node
\n" }, { "textRaw": "process.exitCode", "name": "exitCode", "desc": "

A number which will be the process exit code, when the process either\nexits gracefully, or is exited via [process.exit()][] without specifying\na code.\n\n

\n

Specifying a code to process.exit(code) will override any previous\nsetting of process.exitCode.\n\n\n

\n" }, { "textRaw": "process.mainModule", "name": "mainModule", "desc": "

Alternate way to retrieve [require.main][]. The difference is that if the main\nmodule changes at runtime, require.main might still refer to the original main\nmodule in modules that were required before the change occurred. Generally it's\nsafe to assume that the two refer to the same module.\n\n

\n

As with require.main, it will be undefined if there was no entry script.\n\n

\n" }, { "textRaw": "process.pid", "name": "pid", "desc": "

The PID of the process.\n\n

\n
console.log(`This process is pid ${process.pid}`);
\n" }, { "textRaw": "process.platform", "name": "platform", "desc": "

What platform you're running on:\n'darwin', 'freebsd', 'linux', 'sunos' or 'win32'\n\n

\n
console.log(`This platform is ${process.platform}`);
\n" }, { "textRaw": "process.release", "name": "release", "desc": "

An Object containing metadata related to the current release, including URLs\nfor the source tarball and headers-only tarball.\n\n

\n

process.release contains the following properties:\n\n

\n
    \n
  • name: a string with a value that will always be 'node' for Node.js. For\nlegacy io.js releases, this will be 'io.js'.
  • \n
  • sourceUrl: a complete URL pointing to a .tar.gz file containing the\nsource of the current release.
  • \n
  • headersUrl: a complete URL pointing to a .tar.gz file containing only\nthe header files for the current release. This file is significantly smaller\nthan the full source file and can be used for compiling add-ons against\nNode.js.
  • \n
  • libUrl: a complete URL pointing to an node.lib file matching the\narchitecture and version of the current release. This file is used for\ncompiling add-ons against Node.js. This property is only present on Windows\nbuilds of Node.js and will be missing on all other platforms.
  • \n
\n

e.g.\n\n

\n
{ name: 'node',\n  sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz',\n  headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz',\n  libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' }
\n

In custom builds from non-release versions of the source tree, only the\nname property may be present. The additional properties should not be\nrelied upon to exist.\n\n

\n" }, { "textRaw": "process.stderr", "name": "stderr", "desc": "

A writable stream to stderr (on fd 2).\n\n

\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the finish\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n" }, { "textRaw": "process.stdin", "name": "stdin", "desc": "

A Readable Stream for stdin (on fd 0).\n\n

\n

Example of opening standard input and listening for both events:\n\n

\n
process.stdin.setEncoding('utf8');\n\nprocess.stdin.on('readable', () => {\n  var chunk = process.stdin.read();\n  if (chunk !== null) {\n    process.stdout.write(`data: ${chunk}`);\n  }\n});\n\nprocess.stdin.on('end', () => {\n  process.stdout.write('end');\n});
\n

As a Stream, process.stdin can also be used in "old" mode that is compatible\nwith scripts written for node.js prior to v0.10.\nFor more information see [Stream compatibility][].\n\n

\n

In "old" Streams mode the stdin stream is paused by default, so one\nmust call process.stdin.resume() to read from it. Note also that calling\nprocess.stdin.resume() itself would switch stream to "old" mode.\n\n

\n

If you are starting a new project you should prefer a more recent "new" Streams\nmode over "old" one.\n\n

\n" }, { "textRaw": "process.stdout", "name": "stdout", "desc": "

A Writable Stream to stdout (on fd 1).\n\n

\n

For example, a console.log equivalent could look like this:\n\n

\n
console.log = function(msg) {\n  process.stdout.write(`${msg}\\n`);\n};
\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the 'finish'\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n

To check if Node.js is being run in a TTY context, read the isTTY property\non process.stderr, process.stdout, or process.stdin:\n\n

\n
$ node -p "Boolean(process.stdin.isTTY)"\ntrue\n$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"\nfalse\n\n$ node -p "Boolean(process.stdout.isTTY)"\ntrue\n$ node -p "Boolean(process.stdout.isTTY)" | cat\nfalse
\n

See [the tty docs][] for more information.\n\n

\n" }, { "textRaw": "process.title", "name": "title", "desc": "

Getter/setter to set what is displayed in ps.\n\n

\n

When used as a setter, the maximum length is platform-specific and probably\nshort.\n\n

\n

On Linux and OS X, it's limited to the size of the binary name plus the\nlength of the command line arguments because it overwrites the argv memory.\n\n

\n

v0.8 allowed for longer process title strings by also overwriting the environ\nmemory but that was potentially insecure/confusing in some (rather obscure)\ncases.\n\n

\n" }, { "textRaw": "process.version", "name": "version", "desc": "

A compiled-in property that exposes NODE_VERSION.\n\n

\n
console.log(`Version: ${process.version}`);
\n" }, { "textRaw": "process.versions", "name": "versions", "desc": "

A property exposing version strings of Node.js and its dependencies.\n\n

\n
console.log(process.versions);
\n

Will print something like:\n\n

\n
{ http_parser: '2.3.0',\n  node: '1.1.1',\n  v8: '4.1.0.14',\n  uv: '1.3.0',\n  zlib: '1.2.8',\n  ares: '1.10.0-DEV',\n  modules: '43',\n  icu: '55.1',\n  openssl: '1.0.1k' }
\n" } ] } ], "vars": [ { "textRaw": "__dirname", "name": "__dirname", "type": "var", "desc": "

The name of the directory that the currently executing script resides in.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__dirname);\n// /Users/mjr
\n

__dirname isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "__filename", "name": "__filename", "type": "var", "desc": "

The filename of the code being executed. This is the resolved absolute path\nof this code file. For a main program this is not necessarily the same\nfilename used in the command line. The value inside a module is the path\nto that module file.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__filename);\n// /Users/mjr/example.js
\n

__filename isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "exports", "name": "exports", "type": "var", "desc": "

A reference to the module.exports that is shorter to type.\nSee [module system documentation][] for details on when to use exports and\nwhen to use module.exports.\n\n

\n

exports isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "module", "name": "module", "type": "var", "desc": "

A reference to the current module. In particular\nmodule.exports is used for defining what a module exports and makes\navailable through require().\n\n

\n

module isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "require()", "type": "var", "name": "require", "desc": "

To require modules. See the [Modules][] section. require isn't actually a\nglobal but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`cache` {Object} ", "name": "cache", "desc": "

Modules are cached in this object when they are required. By deleting a key\nvalue from this object, the next require will reload the module.\n\n

\n" }, { "textRaw": "`extensions` {Object} ", "name": "extensions", "stability": 0, "stabilityText": "Deprecated", "desc": "

Instruct require on how to handle certain file extensions.\n\n

\n

Process files with the extension .sjs as .js:\n\n

\n
require.extensions['.sjs'] = require.extensions['.js'];
\n

Deprecated In the past, this list has been used to load\nnon-JavaScript modules into Node.js by compiling them on-demand.\nHowever, in practice, there are much better ways to do this, such as\nloading modules via some other Node.js program, or compiling them to\nJavaScript ahead of time.\n\n

\n

Since the Module system is locked, this feature will probably never go\naway. However, it may have subtle bugs and complexities that are best\nleft untouched.\n\n

\n" } ], "methods": [ { "textRaw": "require.resolve()", "type": "method", "name": "resolve", "desc": "

Use the internal require() machinery to look up the location of a module,\nbut rather than loading the module, just return the resolved filename.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "clearTimeout(t)", "type": "method", "name": "clearTimeout", "desc": "

Stop a timer that was previously created with [setTimeout()][]. The callback will\nnot execute.\n\n

\n", "signatures": [ { "params": [ { "name": "t" } ] } ] }, { "textRaw": "setInterval(cb, ms)", "type": "method", "name": "setInterval", "desc": "

Run callback cb repeatedly every ms milliseconds. Note that the actual\ninterval may vary, depending on external factors like OS timer granularity and\nsystem load. It's never less than ms but it may be longer.\n\n

\n

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] }, { "textRaw": "setTimeout(cb, ms)", "type": "method", "name": "setTimeout", "desc": "

Run callback cb after at least ms milliseconds. The actual delay depends\non external factors like OS timer granularity and system load.\n\n

\n

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] } ] } node-v4.2.6/doc/api/all.markdown000644 000766 000024 00000001135 12650222326 016600 0ustar00iojsstaff000000 000000 @include documentation @include synopsis @include addons @include assert @include buffer @include child_process @include cluster @include console @include crypto @include debugger @include dgram @include dns @include domain @include errors @include events @include fs @include globals @include http @include https @include modules @include net @include os @include path @include process @include punycode @include querystring @include readline @include repl @include stream @include string_decoder @include timers @include tls @include tty @include url @include util @include v8 @include vm @include zlib node-v4.2.6/doc/api/assert.html000644 000766 000024 00000046642 12650222331 016463 0ustar00iojsstaff000000 000000 Assert Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Assert#

Stability: 3 - Locked

The assert module provides a simple set of assertion tests that can be used to test invariants. The module is intended for internal use by Node.js, but can be used in application code via require('assert'). However, assert is not a testing framework, and is not intended to be used as a general purpose assertion library.

The API for the assert module is Locked. This means that there will be no additions or changes to any of the methods implemented and exposed by the module.

assert(value[, message]), assert.ok(value[, message])#

Tests if value is truthy. It is equivalent to assert.equal(!!value, true, message).

If value is not truthy, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

const assert = require('assert');

assert(true);  // OK
assert(1);     // OK
assert(false);
  // throws "AssertionError: false == true"
assert(0);
  // throws "AssertionError: 0 == true"
assert(false, 'it\'s false');
  // throws "AssertionError: it's false"

assert.ok(true);  // OK
assert.ok(1);     // OK
assert.ok(false);
  // throws "AssertionError: false == true"
assert.ok(0);
  // throws "AssertionError: 0 == true"
assert.ok(false, 'it\'s false');
  // throws "AssertionError: it's false"

assert.deepEqual(actual, expected[, message])#

Tests for deep equality between the actual and expected parameters. Primitive values are compared with the equal comparison operator ( == ).

Only enumerable "own" properties are considered. The deepEqual() implementation does not test object prototypes, attached symbols, or non-enumerable properties. This can lead to some potentially surprising results. For example, the following example does not throw an AssertionError because the properties on the Error object are non-enumerable:

// WARNING: This does not throw an AssertionError!
assert.deepEqual(Error('a'), Error('b'));

"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:

const assert = require('assert');

const obj1 = {
  a : {
    b : 1
  }
};
const obj2 = {
  a : {
    b : 2
  }
};
const obj3 = {
  a : {
    b : 1
  }
}
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
  // OK, object is equal to itself

assert.deepEqual(obj1, obj2);
  // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
  // values of b are different

assert.deepEqual(obj1, obj3);
  // OK, objects are equal

assert.deepEqual(obj1, obj4);
  // AssertionError: { a: { b: 1 } } deepEqual {}
  // Prototypes are ignored

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.deepStrictEqual(actual, expected[, message])#

Generally identical to assert.deepEqual with the exception that primitive values are compared using the strict equality operator ( === ).

const assert = require('assert');

assert.deepEqual({a:1}, {a:'1'});
  // OK, because 1 == '1'

assert.deepStrictEqual({a:1}, {a:'1'});
  // AssertionError: { a: 1 } deepStrictEqual { a: '1' }
  // because 1 !== '1' using strict equality

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.doesNotThrow(block[, error][, message])#

Asserts that the function block does not throw an error. See assert.throws() for more details.

When assert.doesNotThrow() is called, it will immediately call the block function.

If an error is thrown and it is the same type as that specified by the error parameter, then an AssertionError is thrown. If the error is of a different type, or if the error parameter is undefined, the error is propagated back to the caller.

The following, for instance, will throw the TypeError because there is no matching error type in the assertion:

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  SyntaxError
);

However, the following will result in an AssertionError with the message 'Got unwanted exception (TypeError)..':

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  TypeError
);

If an AssertionError is thrown and a value is provided for the message parameter, the value of message will be appended to the AssertionError message:

assert.doesNotThrow(
  function() {
    throw new TypeError('Wrong value');
  },
  TypeError,
  'Whoops'
);
// Throws: AssertionError: Got unwanted exception (TypeError). Whoops

assert.equal(actual, expected[, message])#

Tests shallow, coercive equality between the actual and expected parameters using the equal comparison operator ( == ).

const assert = require('assert');

assert.equal(1, 1);
  // OK, 1 == 1
assert.equal(1, '1');
  // OK, 1 == '1'

assert.equal(1, 2);
  // AssertionError: 1 == 2
assert.equal({a: {b: 1}}, {a: {b: 1}});
  //AssertionError: { a: { b: 1 } } == { a: { b: 1 } }

If the values are not equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.fail(actual, expected, message, operator)#

Throws an AssertionError. If message is falsy, the error message is set as the values of actual and expected separated by the provided operator. Otherwise, the error message is the value of message.

const assert = require('assert');

assert.fail(1, 2, undefined, '>');
  // AssertionError: 1 > 2

assert.fail(1, 2, 'whoops', '>');
  // AssertionError: whoops

assert.ifError(value)#

Throws value if value is truthy. This is useful when testing the error argument in callbacks.

const assert = require('assert');

assert.ifError(0); // OK
assert.ifError(1); // Throws 1
assert.ifError('error') // Throws 'error'
assert.ifError(new Error()); // Throws Error

assert.notDeepEqual(actual, expected[, message])#

Tests for any deep inequality. Opposite of assert.deepEqual.

const assert = require('assert');

const obj1 = {
  a : {
    b : 1
  }
};
const obj2 = {
  a : {
    b : 2
  }
};
const obj3 = {
  a : {
    b : 1
  }
}
const obj4 = Object.create(obj1);

assert.deepEqual(obj1, obj1);
  AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.deepEqual(obj1, obj2);
  // OK, obj1 and obj2 are not deeply equal

assert.deepEqual(obj1, obj3);
  // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

assert.deepEqual(obj1, obj4);
  // OK, obj1 and obj2 are not deeply equal

If the values are deeply equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notDeepStrictEqual(actual, expected[, message])#

Tests for deep strict inequality. Opposite of assert.deepStrictEqual.

const assert = require('assert');

assert.notDeepEqual({a:1}, {a:'1'});
  // AssertionError: { a: 1 } notDeepEqual { a: '1' }

assert.notDeepStrictEqual({a:1}, {a:'1'});
  // OK

If the values are deeply and strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notEqual(actual, expected[, message])#

Tests shallow, coercive inequality with the not equal comparison operator ( != ).

const assert = require('assert');

assert.notEqual(1, 2);
  // OK

assert.notEqual(1, 1);
  // AssertionError: 1 != 1

assert.notEqual(1, '1');
  // AssertionError: 1 != '1'

If the values are equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.notStrictEqual(actual, expected[, message])#

Tests strict inequality as determined by the strict not equal operator ( !== ).

const assert = require('assert');

assert.notStrictEqual(1, 2);
  // OK

assert.notStrictEqual(1, 1);
  // AssertionError: 1 != 1

assert.notStrictEqual(1, '1');
  // OK

If the values are strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.strictEqual(actual, expected[, message])#

Tests strict equality as determined by the strict equality operator ( === ).

const assert = require('assert');

assert.strictEqual(1, 2);
  // AssertionError: 1 === 2

assert.strictEqual(1, 1);
  // OK

assert.strictEqual(1, '1');
  // AssertionError: 1 === '1'

If the values are not strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned.

assert.throws(block[, error][, message])#

Expects the function block to throw an error. If specified, error can be a constructor, RegExp, or validation function.

Validate instanceof using constructor:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  Error
);

Validate error message using RegExp:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  /value/
);

Custom error validation:

assert.throws(
  function() {
    throw new Error('Wrong value');
  },
  function(err) {
    if ( (err instanceof Error) && /value/.test(err) ) {
      return true;
    }
  },
  'unexpected error'
);
node-v4.2.6/doc/api/assert.json000644 000766 000024 00000044642 12650222331 016466 0ustar00iojsstaff000000 000000 { "source": "doc/api/assert.markdown", "modules": [ { "textRaw": "Assert", "name": "assert", "stability": 3, "stabilityText": "Locked", "desc": "

The assert module provides a simple set of assertion tests that can be used to\ntest invariants. The module is intended for internal use by Node.js, but can be\nused in application code via require('assert'). However, assert is not a\ntesting framework, and is not intended to be used as a general purpose assertion\nlibrary.\n\n

\n

The API for the assert module is [Locked][]. This means that there will be no\nadditions or changes to any of the methods implemented and exposed by\nthe module.\n\n

\n", "methods": [ { "textRaw": "assert(value[, message]), assert.ok(value[, message])", "type": "method", "name": "ok", "desc": "

Tests if value is truthy. It is equivalent to\nassert.equal(!!value, true, message).\n\n

\n

If value is not truthy, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n
const assert = require('assert');\n\nassert(true);  // OK\nassert(1);     // OK\nassert(false);\n  // throws "AssertionError: false == true"\nassert(0);\n  // throws "AssertionError: 0 == true"\nassert(false, 'it\\'s false');\n  // throws "AssertionError: it's false"\n\nassert.ok(true);  // OK\nassert.ok(1);     // OK\nassert.ok(false);\n  // throws "AssertionError: false == true"\nassert.ok(0);\n  // throws "AssertionError: 0 == true"\nassert.ok(false, 'it\\'s false');\n  // throws "AssertionError: it's false"
\n", "signatures": [ { "params": [ { "name": "value" }, { "name": "message])" }, { "name": "assert.ok(value" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.deepEqual(actual, expected[, message])", "type": "method", "name": "deepEqual", "desc": "

Tests for deep equality between the actual and expected parameters.\nPrimitive values are compared with the equal comparison operator ( == ).\n\n

\n

Only enumerable "own" properties are considered. The deepEqual()\nimplementation does not test object prototypes, attached symbols, or\nnon-enumerable properties. This can lead to some potentially surprising\nresults. For example, the following example does not throw an AssertionError\nbecause the properties on the [Error][] object are non-enumerable:\n\n

\n
// WARNING: This does not throw an AssertionError!\nassert.deepEqual(Error('a'), Error('b'));
\n

"Deep" equality means that the enumerable "own" properties of child objects\nare evaluated also:\n\n

\n
const assert = require('assert');\n\nconst obj1 = {\n  a : {\n    b : 1\n  }\n};\nconst obj2 = {\n  a : {\n    b : 2\n  }\n};\nconst obj3 = {\n  a : {\n    b : 1\n  }\n}\nconst obj4 = Object.create(obj1);\n\nassert.deepEqual(obj1, obj1);\n  // OK, object is equal to itself\n\nassert.deepEqual(obj1, obj2);\n  // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }\n  // values of b are different\n\nassert.deepEqual(obj1, obj3);\n  // OK, objects are equal\n\nassert.deepEqual(obj1, obj4);\n  // AssertionError: { a: { b: 1 } } deepEqual {}\n  // Prototypes are ignored
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.deepStrictEqual(actual, expected[, message])", "type": "method", "name": "deepStrictEqual", "desc": "

Generally identical to assert.deepEqual with the exception that primitive\nvalues are compared using the strict equality operator ( === ).\n\n

\n
const assert = require('assert');\n\nassert.deepEqual({a:1}, {a:'1'});\n  // OK, because 1 == '1'\n\nassert.deepStrictEqual({a:1}, {a:'1'});\n  // AssertionError: { a: 1 } deepStrictEqual { a: '1' }\n  // because 1 !== '1' using strict equality
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.doesNotThrow(block[, error][, message])", "type": "method", "name": "doesNotThrow", "desc": "

Asserts that the function block does not throw an error. See\n[assert.throws()][] for more details.\n\n

\n

When assert.doesNotThrow() is called, it will immediately call the block\nfunction.\n\n

\n

If an error is thrown and it is the same type as that specified by the error\nparameter, then an AssertionError is thrown. If the error is of a different\ntype, or if the error parameter is undefined, the error is propagated back\nto the caller.\n\n

\n

The following, for instance, will throw the [TypeError][] because there is no\nmatching error type in the assertion:\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  SyntaxError\n);
\n

However, the following will result in an AssertionError with the message\n'Got unwanted exception (TypeError)..':\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  TypeError\n);
\n

If an AssertionError is thrown and a value is provided for the message\nparameter, the value of message will be appended to the AssertionError\nmessage:\n\n

\n
assert.doesNotThrow(\n  function() {\n    throw new TypeError('Wrong value');\n  },\n  TypeError,\n  'Whoops'\n);\n// Throws: AssertionError: Got unwanted exception (TypeError). Whoops
\n", "signatures": [ { "params": [ { "name": "block" }, { "name": "error", "optional": true }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.equal(actual, expected[, message])", "type": "method", "name": "equal", "desc": "

Tests shallow, coercive equality between the actual and expected parameters\nusing the equal comparison operator ( == ).\n\n

\n
const assert = require('assert');\n\nassert.equal(1, 1);\n  // OK, 1 == 1\nassert.equal(1, '1');\n  // OK, 1 == '1'\n\nassert.equal(1, 2);\n  // AssertionError: 1 == 2\nassert.equal({a: {b: 1}}, {a: {b: 1}});\n  //AssertionError: { a: { b: 1 } } == { a: { b: 1 } }
\n

If the values are not equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.fail(actual, expected, message, operator)", "type": "method", "name": "fail", "desc": "

Throws an AssertionError. If message is falsy, the error message is set as\nthe values of actual and expected separated by the provided operator.\nOtherwise, the error message is the value of message.\n\n

\n
const assert = require('assert');\n\nassert.fail(1, 2, undefined, '>');\n  // AssertionError: 1 > 2\n\nassert.fail(1, 2, 'whoops', '>');\n  // AssertionError: whoops
\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message" }, { "name": "operator" } ] } ] }, { "textRaw": "assert.ifError(value)", "type": "method", "name": "ifError", "desc": "

Throws value if value is truthy. This is useful when testing the error\nargument in callbacks.\n\n

\n
const assert = require('assert');\n\nassert.ifError(0); // OK\nassert.ifError(1); // Throws 1\nassert.ifError('error') // Throws 'error'\nassert.ifError(new Error()); // Throws Error
\n", "signatures": [ { "params": [ { "name": "value" } ] } ] }, { "textRaw": "assert.notDeepEqual(actual, expected[, message])", "type": "method", "name": "notDeepEqual", "desc": "

Tests for any deep inequality. Opposite of [assert.deepEqual][].\n\n

\n
const assert = require('assert');\n\nconst obj1 = {\n  a : {\n    b : 1\n  }\n};\nconst obj2 = {\n  a : {\n    b : 2\n  }\n};\nconst obj3 = {\n  a : {\n    b : 1\n  }\n}\nconst obj4 = Object.create(obj1);\n\nassert.deepEqual(obj1, obj1);\n  AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }\n\nassert.deepEqual(obj1, obj2);\n  // OK, obj1 and obj2 are not deeply equal\n\nassert.deepEqual(obj1, obj3);\n  // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }\n\nassert.deepEqual(obj1, obj4);\n  // OK, obj1 and obj2 are not deeply equal
\n

If the values are deeply equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notDeepStrictEqual(actual, expected[, message])", "type": "method", "name": "notDeepStrictEqual", "desc": "

Tests for deep strict inequality. Opposite of [assert.deepStrictEqual][].\n\n

\n
const assert = require('assert');\n\nassert.notDeepEqual({a:1}, {a:'1'});\n  // AssertionError: { a: 1 } notDeepEqual { a: '1' }\n\nassert.notDeepStrictEqual({a:1}, {a:'1'});\n  // OK
\n

If the values are deeply and strictly equal, an AssertionError is thrown\nwith a message property set equal to the value of the message parameter. If\nthe message parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notEqual(actual, expected[, message])", "type": "method", "name": "notEqual", "desc": "

Tests shallow, coercive inequality with the not equal comparison operator\n( != ).\n\n

\n
const assert = require('assert');\n\nassert.notEqual(1, 2);\n  // OK\n\nassert.notEqual(1, 1);\n  // AssertionError: 1 != 1\n\nassert.notEqual(1, '1');\n  // AssertionError: 1 != '1'
\n

If the values are equal, an AssertionError is thrown with a message\nproperty set equal to the value of the message parameter. If the message\nparameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.notStrictEqual(actual, expected[, message])", "type": "method", "name": "notStrictEqual", "desc": "

Tests strict inequality as determined by the strict not equal operator\n( !== ).\n\n

\n
const assert = require('assert');\n\nassert.notStrictEqual(1, 2);\n  // OK\n\nassert.notStrictEqual(1, 1);\n  // AssertionError: 1 != 1\n\nassert.notStrictEqual(1, '1');\n  // OK
\n

If the values are strictly equal, an AssertionError is thrown with a\nmessage property set equal to the value of the message parameter. If the\nmessage parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.strictEqual(actual, expected[, message])", "type": "method", "name": "strictEqual", "desc": "

Tests strict equality as determined by the strict equality operator ( === ).\n\n

\n
const assert = require('assert');\n\nassert.strictEqual(1, 2);\n  // AssertionError: 1 === 2\n\nassert.strictEqual(1, 1);\n  // OK\n\nassert.strictEqual(1, '1');\n  // AssertionError: 1 === '1'
\n

If the values are not strictly equal, an AssertionError is thrown with a\nmessage property set equal to the value of the message parameter. If the\nmessage parameter is undefined, a default error message is assigned.\n\n

\n", "signatures": [ { "params": [ { "name": "actual" }, { "name": "expected" }, { "name": "message", "optional": true } ] } ] }, { "textRaw": "assert.throws(block[, error][, message])", "type": "method", "name": "throws", "desc": "

Expects the function block to throw an error. If specified, error can be a\nconstructor, [RegExp][], or validation function.\n\n

\n

Validate instanceof using constructor:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  Error\n);
\n

Validate error message using [RegExp][]:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  /value/\n);
\n

Custom error validation:\n\n

\n
assert.throws(\n  function() {\n    throw new Error('Wrong value');\n  },\n  function(err) {\n    if ( (err instanceof Error) && /value/.test(err) ) {\n      return true;\n    }\n  },\n  'unexpected error'\n);
\n", "signatures": [ { "params": [ { "name": "block" }, { "name": "error", "optional": true }, { "name": "message", "optional": true } ] } ] } ], "type": "module", "displayName": "Assert" } ] } node-v4.2.6/doc/api/assert.markdown000644 000766 000024 00000025333 12650222326 017337 0ustar00iojsstaff000000 000000 # Assert Stability: 3 - Locked The `assert` module provides a simple set of assertion tests that can be used to test invariants. The module is intended for internal use by Node.js, but can be used in application code via `require('assert')`. However, `assert` is not a testing framework, and is not intended to be used as a general purpose assertion library. The API for the `assert` module is [Locked][]. This means that there will be no additions or changes to any of the methods implemented and exposed by the module. ## assert(value[, message]), assert.ok(value[, message]) Tests if `value` is truthy. It is equivalent to `assert.equal(!!value, true, message)`. If `value` is not truthy, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is `undefined`, a default error message is assigned. const assert = require('assert'); assert(true); // OK assert(1); // OK assert(false); // throws "AssertionError: false == true" assert(0); // throws "AssertionError: 0 == true" assert(false, 'it\'s false'); // throws "AssertionError: it's false" assert.ok(true); // OK assert.ok(1); // OK assert.ok(false); // throws "AssertionError: false == true" assert.ok(0); // throws "AssertionError: 0 == true" assert.ok(false, 'it\'s false'); // throws "AssertionError: it's false" ## assert.deepEqual(actual, expected[, message]) Tests for deep equality between the `actual` and `expected` parameters. Primitive values are compared with the equal comparison operator ( `==` ). Only enumerable "own" properties are considered. The `deepEqual()` implementation does not test object prototypes, attached symbols, or non-enumerable properties. This can lead to some potentially surprising results. For example, the following example does not throw an `AssertionError` because the properties on the [`Error`][] object are non-enumerable: // WARNING: This does not throw an AssertionError! assert.deepEqual(Error('a'), Error('b')); "Deep" equality means that the enumerable "own" properties of child objects are evaluated also: const assert = require('assert'); const obj1 = { a : { b : 1 } }; const obj2 = { a : { b : 2 } }; const obj3 = { a : { b : 1 } } const obj4 = Object.create(obj1); assert.deepEqual(obj1, obj1); // OK, object is equal to itself assert.deepEqual(obj1, obj2); // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } } // values of b are different assert.deepEqual(obj1, obj3); // OK, objects are equal assert.deepEqual(obj1, obj4); // AssertionError: { a: { b: 1 } } deepEqual {} // Prototypes are ignored If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.deepStrictEqual(actual, expected[, message]) Generally identical to `assert.deepEqual` with the exception that primitive values are compared using the strict equality operator ( `===` ). const assert = require('assert'); assert.deepEqual({a:1}, {a:'1'}); // OK, because 1 == '1' assert.deepStrictEqual({a:1}, {a:'1'}); // AssertionError: { a: 1 } deepStrictEqual { a: '1' } // because 1 !== '1' using strict equality If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.doesNotThrow(block[, error][, message]) Asserts that the function `block` does not throw an error. See [`assert.throws()`][] for more details. When `assert.doesNotThrow()` is called, it will immediately call the `block` function. If an error is thrown and it is the same type as that specified by the `error` parameter, then an `AssertionError` is thrown. If the error is of a different type, or if the `error` parameter is undefined, the error is propagated back to the caller. The following, for instance, will throw the [`TypeError`][] because there is no matching error type in the assertion: assert.doesNotThrow( function() { throw new TypeError('Wrong value'); }, SyntaxError ); However, the following will result in an `AssertionError` with the message 'Got unwanted exception (TypeError)..': assert.doesNotThrow( function() { throw new TypeError('Wrong value'); }, TypeError ); If an `AssertionError` is thrown and a value is provided for the `message` parameter, the value of `message` will be appended to the `AssertionError` message: assert.doesNotThrow( function() { throw new TypeError('Wrong value'); }, TypeError, 'Whoops' ); // Throws: AssertionError: Got unwanted exception (TypeError). Whoops ## assert.equal(actual, expected[, message]) Tests shallow, coercive equality between the `actual` and `expected` parameters using the equal comparison operator ( `==` ). const assert = require('assert'); assert.equal(1, 1); // OK, 1 == 1 assert.equal(1, '1'); // OK, 1 == '1' assert.equal(1, 2); // AssertionError: 1 == 2 assert.equal({a: {b: 1}}, {a: {b: 1}}); //AssertionError: { a: { b: 1 } } == { a: { b: 1 } } If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.fail(actual, expected, message, operator) Throws an `AssertionError`. If `message` is falsy, the error message is set as the values of `actual` and `expected` separated by the provided `operator`. Otherwise, the error message is the value of `message`. const assert = require('assert'); assert.fail(1, 2, undefined, '>'); // AssertionError: 1 > 2 assert.fail(1, 2, 'whoops', '>'); // AssertionError: whoops ## assert.ifError(value) Throws `value` if `value` is truthy. This is useful when testing the `error` argument in callbacks. const assert = require('assert'); assert.ifError(0); // OK assert.ifError(1); // Throws 1 assert.ifError('error') // Throws 'error' assert.ifError(new Error()); // Throws Error ## assert.notDeepEqual(actual, expected[, message]) Tests for any deep inequality. Opposite of [`assert.deepEqual`][]. const assert = require('assert'); const obj1 = { a : { b : 1 } }; const obj2 = { a : { b : 2 } }; const obj3 = { a : { b : 1 } } const obj4 = Object.create(obj1); assert.deepEqual(obj1, obj1); AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.deepEqual(obj1, obj2); // OK, obj1 and obj2 are not deeply equal assert.deepEqual(obj1, obj3); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.deepEqual(obj1, obj4); // OK, obj1 and obj2 are not deeply equal If the values are deeply equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.notDeepStrictEqual(actual, expected[, message]) Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual`][]. const assert = require('assert'); assert.notDeepEqual({a:1}, {a:'1'}); // AssertionError: { a: 1 } notDeepEqual { a: '1' } assert.notDeepStrictEqual({a:1}, {a:'1'}); // OK If the values are deeply and strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.notEqual(actual, expected[, message]) Tests shallow, coercive inequality with the not equal comparison operator ( `!=` ). const assert = require('assert'); assert.notEqual(1, 2); // OK assert.notEqual(1, 1); // AssertionError: 1 != 1 assert.notEqual(1, '1'); // AssertionError: 1 != '1' If the values are equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.notStrictEqual(actual, expected[, message]) Tests strict inequality as determined by the strict not equal operator ( `!==` ). const assert = require('assert'); assert.notStrictEqual(1, 2); // OK assert.notStrictEqual(1, 1); // AssertionError: 1 != 1 assert.notStrictEqual(1, '1'); // OK If the values are strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.strictEqual(actual, expected[, message]) Tests strict equality as determined by the strict equality operator ( `===` ). const assert = require('assert'); assert.strictEqual(1, 2); // AssertionError: 1 === 2 assert.strictEqual(1, 1); // OK assert.strictEqual(1, '1'); // AssertionError: 1 === '1' If the values are not strictly equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. ## assert.throws(block[, error][, message]) Expects the function `block` to throw an error. If specified, `error` can be a constructor, [`RegExp`][], or validation function. Validate instanceof using constructor: assert.throws( function() { throw new Error('Wrong value'); }, Error ); Validate error message using [`RegExp`][]: assert.throws( function() { throw new Error('Wrong value'); }, /value/ ); Custom error validation: assert.throws( function() { throw new Error('Wrong value'); }, function(err) { if ( (err instanceof Error) && /value/.test(err) ) { return true; } }, 'unexpected error' ); [Locked]: documentation.html#documentation_stability_index [`assert.deepEqual`]: #assert_assert_deepequal_actual_expected_message [`assert.deepStrictEqual`]: #assert_assert_deepstrictequal_actual_expected_message [`assert.throws()`]: #assert_assert_throws_block_error_message [`Error`]: errors.html#errors_class_error [`RegExp`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions [`TypeError`]: errors.html#errors_class_typeerror node-v4.2.6/doc/api/assets/000755 000766 000024 00000000000 12650222331 015562 5ustar00iojsstaff000000 000000 node-v4.2.6/doc/api/buffer.html000644 000766 000024 00000150333 12650222331 016424 0ustar00iojsstaff000000 000000 Buffer Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

Buffer#

Stability: 2 - Stable

Pure JavaScript is Unicode-friendly but not nice to binary data. When dealing with TCP streams or the file system, it's necessary to handle octet streams. Node.js has several strategies for manipulating, creating, and consuming octet streams.

Raw data is stored in instances of the Buffer class. A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.

The Buffer class is a global, making it very rare that one would need to ever require('buffer').

Converting between Buffers and JavaScript string objects requires an explicit encoding method. The different string encodings are:

  • 'ascii' - for 7-bit ASCII data only. This encoding method is very fast and will strip the high bit if set.

  • 'utf8' - Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8.

  • 'utf16le' - 2 or 4 bytes, little-endian encoded Unicode characters. Surrogate pairs (U+10000 to U+10FFFF) are supported.

  • 'ucs2' - Alias of 'utf16le'.

  • 'base64' - Base64 string encoding.

  • 'binary' - A way of encoding the buffer into a one-byte (latin-1) encoded string. The string 'latin-1' is not supported. Instead, pass 'binary' to use 'latin-1' encoding.

  • 'hex' - Encode each byte as two hexadecimal characters.

Creating a typed array from a Buffer works with the following caveats:

  1. The buffer's memory is copied, not shared.

  2. The buffer's memory is interpreted as an array, not a byte array. That is, new Uint32Array(new Buffer([1,2,3,4])) creates a 4-element Uint32Array with elements [1,2,3,4], not a Uint32Array with a single element [0x1020304] or [0x4030201].

NOTE: Node.js v0.8 retained a reference to the buffer in array.buffer instead of cloning it.

While more efficient, it introduces subtle incompatibilities with the typed arrays specification. ArrayBuffer#slice() makes a copy of the slice while Buffer#slice() creates a view.

Class: Buffer#

The Buffer class is a global type for dealing with binary data directly. It can be constructed in a variety of ways.

new Buffer(array)#

  • array Array

Allocates a new buffer using an array of octets.

new Buffer(buffer)#

  • buffer Buffer

Copies the passed buffer data onto a new Buffer instance.

new Buffer(size)#

  • size Number

Allocates a new buffer of size bytes. size must be less than 1,073,741,824 bytes (1 GB) on 32-bit architectures or 2,147,483,648 bytes (2 GB) on 64-bit architectures. Otherwise, a RangeError is thrown.

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So the contents of a newly created Buffer are unknown and could contain sensitive data. Use buf.fill(0) to initialize a buffer to zeroes.

new Buffer(str[, encoding])#

  • str String - string to encode.
  • encoding String - encoding to use, Optional.

Allocates a new buffer containing the given str. encoding defaults to 'utf8'.

Class Method: Buffer.byteLength(string[, encoding])#

  • string String
  • encoding String, Optional, Default: 'utf8'
  • Return: Number

Gives the actual byte length of a string. encoding defaults to 'utf8'. This is not the same as String.prototype.length since that returns the number of characters in a string.

Example:

str = '\u00bd + \u00bc = \u00be';

console.log(`${str}: ${str.length} characters, ` +
            `${Buffer.byteLength(str, 'utf8')} bytes`);

// ½ + ¼ = ¾: 9 characters, 12 bytes

Class Method: Buffer.compare(buf1, buf2)#

  • buf1 Buffer
  • buf2 Buffer

The same as buf1.compare(buf2). Useful for sorting an Array of Buffers:

var arr = [Buffer('1234'), Buffer('0123')];
arr.sort(Buffer.compare);

Class Method: Buffer.concat(list[, totalLength])#

  • list Array List of Buffer objects to concat
  • totalLength Number Total length of the buffers in the list when concatenated

Returns a buffer which is the result of concatenating all the buffers in the list together.

If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.

If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.

Example: build a single buffer from a list of three buffers:

var buf1 = new Buffer(10);
var buf2 = new Buffer(14);
var buf3 = new Buffer(18);

buf1.fill(0);
buf2.fill(0);
buf3.fill(0);

var buffers = [buf1, buf2, buf3];

var totalLength = 0;
for (var i = 0; i < buffers.length; i++) {
  totalLength += buffers[i].length;
}

console.log(totalLength);
var bufA = Buffer.concat(buffers, totalLength);
console.log(bufA);
console.log(bufA.length);

// 42
// <Buffer 00 00 00 00 ...>
// 42

Class Method: Buffer.isBuffer(obj)#

  • obj Object
  • Return: Boolean

Tests if obj is a Buffer.

Class Method: Buffer.isEncoding(encoding)#

  • encoding String The encoding string to test

Returns true if the encoding is a valid encoding argument, or false otherwise.

buffer.entries()#

Creates iterator for [index, byte] arrays.

buffer.keys()#

Creates iterator for buffer keys (indices).

buffer.values()#

Creates iterator for buffer values (bytes). This function is called automatically when buffer is used in a for..of statement.

buf[index]#

Get and set the octet at index. The values refer to individual bytes, so the legal range is between 0x00 and 0xFF hex or 0 and 255.

Example: copy an ASCII string into a buffer, one byte at a time:

str = "Node.js";
buf = new Buffer(str.length);

for (var i = 0; i < str.length ; i++) {
  buf[i] = str.charCodeAt(i);
}

console.log(buf);

// Node.js

buf.compare(otherBuffer)#

  • otherBuffer Buffer

Returns a number indicating whether this comes before, after, or is the same as the otherBuffer in sort order.

buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])#

  • targetBuffer Buffer object - Buffer to copy into
  • targetStart Number, Optional, Default: 0
  • sourceStart Number, Optional, Default: 0
  • sourceEnd Number, Optional, Default: buffer.length

Copies data from a region of this buffer to a region in the target buffer even if the target memory region overlaps with the source. If undefined, the targetStart and sourceStart parameters default to 0 while sourceEnd defaults to buffer.length.

Returns the number of bytes copied.

Example: build two Buffers, then copy buf1 from byte 16 through byte 19 into buf2, starting at the 8th byte in buf2.

buf1 = new Buffer(26);
buf2 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
  buf2[i] = 33; // ASCII !
}

buf1.copy(buf2, 8, 16, 20);
console.log(buf2.toString('ascii', 0, 25));

// !!!!!!!!qrst!!!!!!!!!!!!!

Example: Build a single buffer, then copy data from one region to an overlapping region in the same buffer

buf = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97; // 97 is ASCII a
}

buf.copy(buf, 0, 4, 10);
console.log(buf.toString());

// efghijghijklmnopqrstuvwxyz

buf.equals(otherBuffer)#

  • otherBuffer Buffer

Returns a boolean indicating whether this and otherBuffer have the same bytes.

buf.fill(value[, offset][, end])#

  • value
  • offset Number, Optional
  • end Number, Optional

Fills the buffer with the specified value. If the offset (defaults to 0) and end (defaults to buffer.length) are not given it will fill the entire buffer.

var b = new Buffer(50);
b.fill('h');

buf.indexOf(value[, byteOffset])#

  • value String, Buffer or Number
  • byteOffset Number, Optional, Default: 0
  • Return: Number

Operates similar to Array#indexOf(). Accepts a String, Buffer or Number. Strings are interpreted as UTF8. Buffers will use the entire buffer. So in order to compare a partial Buffer use Buffer#slice(). Numbers can range from 0 to 255.

buf.length#

  • Number

The size of the buffer in bytes. Note that this is not necessarily the size of the contents. length refers to the amount of memory allocated for the buffer object. It does not change when the contents of the buffer are changed.

buf = new Buffer(1234);

console.log(buf.length);
buf.write('some string', 0, 'ascii');
console.log(buf.length);

// 1234
// 1234

While the length property is not immutable, changing the value of length can result in undefined and inconsistent behavior. Applications that wish to modify the length of a buffer should therefore treat length as read-only and use buf.slice to create a new buffer.

buf = new Buffer(10);
buf.write('abcdefghj', 0, 'ascii');
console.log(buf.length); // 10
buf = buf.slice(0,5);
console.log(buf.length); // 5

buf.readDoubleBE(offset[, noAssert])#

buf.readDoubleLE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a 64-bit double from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(8);

buf[0] = 0x55;
buf[1] = 0x55;
buf[2] = 0x55;
buf[3] = 0x55;
buf[4] = 0x55;
buf[5] = 0x55;
buf[6] = 0xd5;
buf[7] = 0x3f;

console.log(buf.readDoubleLE(0));

// 0.3333333333333333

buf.readFloatBE(offset[, noAssert])#

buf.readFloatLE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a 32-bit float from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x00;
buf[1] = 0x00;
buf[2] = 0x80;
buf[3] = 0x3f;

console.log(buf.readFloatLE(0));

// 0x01

buf.readInt8(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 8-bit integer from the buffer at the specified offset.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt8, except buffer contents are treated as two's complement signed values.

buf.readInt16BE(offset[, noAssert])#

buf.readInt16LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 16-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt16*, except buffer contents are treated as two's complement signed values.

buf.readInt32BE(offset[, noAssert])#

buf.readInt32LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads a signed 32-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Works as buffer.readUInt32*, except buffer contents are treated as two's complement signed values.

buf.readIntBE(offset, byteLength[, noAssert])#

buf.readIntLE(offset, byteLength[, noAssert])#

  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUInt16LE(0x90ab, 0);
b.writeUInt32LE(0x12345678, 2);
b.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)
// output: '1234567890ab'

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

buf.readUInt8(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 8-bit integer from the buffer at the specified offset.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

for (ii = 0; ii < buf.length; ii++) {
  console.log(buf.readUInt8(ii));
}

// 0x3
// 0x4
// 0x23
// 0x42

buf.readUInt16BE(offset[, noAssert])#

buf.readUInt16LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 16-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt16BE(0));
console.log(buf.readUInt16LE(0));
console.log(buf.readUInt16BE(1));
console.log(buf.readUInt16LE(1));
console.log(buf.readUInt16BE(2));
console.log(buf.readUInt16LE(2));

// 0x0304
// 0x0403
// 0x0423
// 0x2304
// 0x2342
// 0x4223

buf.readUInt32BE(offset[, noAssert])#

buf.readUInt32LE(offset[, noAssert])#

  • offset Number
  • noAssert Boolean, Optional, Default: false
  • Return: Number

Reads an unsigned 32-bit integer from the buffer at the specified offset with specified endian format.

Set noAssert to true to skip validation of offset. This means that offset may be beyond the end of the buffer. Defaults to false.

Example:

var buf = new Buffer(4);

buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;

console.log(buf.readUInt32BE(0));
console.log(buf.readUInt32LE(0));

// 0x03042342
// 0x42230403

buf.readUIntBE(offset, byteLength[, noAssert])#

buf.readUIntLE(offset, byteLength[, noAssert])#

  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUInt16LE(0x90ab, 0);
b.writeUInt32LE(0x12345678, 2);
b.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)
// output: '1234567890ab'

buf.slice([start[, end]])#

  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

Returns a new buffer which references the same memory as the old, but offset and cropped by the start (defaults to 0) and end (defaults to buffer.length) indexes. Negative indexes start from the end of the buffer.

Modifying the new buffer slice will modify memory in the original buffer!

Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte from the original Buffer.

var buf1 = new Buffer(26);

for (var i = 0 ; i < 26 ; i++) {
  buf1[i] = i + 97; // 97 is ASCII a
}

var buf2 = buf1.slice(0, 3);
console.log(buf2.toString('ascii', 0, buf2.length));
buf1[0] = 33;
console.log(buf2.toString('ascii', 0, buf2.length));

// abc
// !bc

buf.toString([encoding][, start][, end])#

  • encoding String, Optional, Default: 'utf8'
  • start Number, Optional, Default: 0
  • end Number, Optional, Default: buffer.length

Decodes and returns a string from buffer data encoded using the specified character set encoding. If encoding is undefined or null, then encoding defaults to 'utf8'. The start and end parameters default to 0 and buffer.length when undefined.

buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
  buf[i] = i + 97; // 97 is ASCII a
}
buf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz
buf.toString('ascii',0,5); // outputs: abcde
buf.toString('utf8',0,5); // outputs: abcde
buf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde

See buf.write() example, below.

buf.toJSON()#

Returns a JSON representation of the Buffer instance. JSON.stringify implicitly calls this function when stringifying a Buffer instance.

Example:

var buf = new Buffer('test');
var json = JSON.stringify(buf);

console.log(json);
// '{"type":"Buffer","data":[116,101,115,116]}'

var copy = JSON.parse(json, function(key, value) {
    return value && value.type === 'Buffer'
      ? new Buffer(value.data)
      : value;
  });

console.log(copy);
// <Buffer 74 65 73 74>

buf.write(string[, offset][, length][, encoding])#

  • string String - data to be written to buffer
  • offset Number, Optional, Default: 0
  • length Number, Optional, Default: buffer.length - offset
  • encoding String, Optional, Default: 'utf8'

Writes string to the buffer at offset using the given encoding. offset defaults to 0, encoding defaults to 'utf8'. length is the number of bytes to write. Returns number of octets written. If buffer did not contain enough space to fit the entire string, it will write a partial amount of the string. length defaults to buffer.length - offset. The method will not write partial characters.

buf = new Buffer(256);
len = buf.write('\u00bd + \u00bc = \u00be', 0);
console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);

buf.writeDoubleBE(value, offset[, noAssert])#

buf.writeDoubleLE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid 64-bit double.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(8);
buf.writeDoubleBE(0xdeadbeefcafebabe, 0);

console.log(buf);

buf.writeDoubleLE(0xdeadbeefcafebabe, 0);

console.log(buf);

// <Buffer 43 eb d5 b7 dd f9 5f d7>
// <Buffer d7 5f f9 dd b7 d5 eb 43>

buf.writeFloatBE(value, offset[, noAssert])#

buf.writeFloatLE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. Behavior is unspecified if value is not a 32-bit float.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeFloatBE(0xcafebabe, 0);

console.log(buf);

buf.writeFloatLE(0xcafebabe, 0);

console.log(buf);

// <Buffer 4f 4a fe bb>
// <Buffer bb fe 4a 4f>

buf.writeInt8(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset. value must be a valid signed 8-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt8, except value is written out as a two's complement signed integer into buffer.

buf.writeInt16BE(value, offset[, noAssert])#

buf.writeInt16LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid signed 16-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt16*, except value is written out as a two's complement signed integer into buffer.

buf.writeInt32BE(value, offset[, noAssert])#

buf.writeInt32LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid signed 32-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Works as buffer.writeUInt32*, except value is written out as a two's complement signed integer into buffer.

buf.writeIntBE(value, offset, byteLength[, noAssert])#

buf.writeIntLE(value, offset, byteLength[, noAssert])#

  • value {Number} Bytes to be written to buffer
  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

Writes value to the buffer at the specified offset and byteLength. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUIntBE(0x1234567890ab, 0, 6);
// <Buffer 12 34 56 78 90 ab>

Set noAssert to true to skip validation of value and offset. Defaults to false.

buf.writeUInt8(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset. value must be a valid unsigned 8-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt8(0x3, 0);
buf.writeUInt8(0x4, 1);
buf.writeUInt8(0x23, 2);
buf.writeUInt8(0x42, 3);

console.log(buf);

// <Buffer 03 04 23 42>

buf.writeUInt16BE(value, offset[, noAssert])#

buf.writeUInt16LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid unsigned 16-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt16BE(0xdead, 0);
buf.writeUInt16BE(0xbeef, 2);

console.log(buf);

buf.writeUInt16LE(0xdead, 0);
buf.writeUInt16LE(0xbeef, 2);

console.log(buf);

// <Buffer de ad be ef>
// <Buffer ad de ef be>

buf.writeUInt32BE(value, offset[, noAssert])#

buf.writeUInt32LE(value, offset[, noAssert])#

  • value Number
  • offset Number
  • noAssert Boolean, Optional, Default: false

Writes value to the buffer at the specified offset with specified endian format. value must be a valid unsigned 32-bit integer.

Set noAssert to true to skip validation of value and offset. This means that value may be too large for the specific function and offset may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to false.

Example:

var buf = new Buffer(4);
buf.writeUInt32BE(0xfeedface, 0);

console.log(buf);

buf.writeUInt32LE(0xfeedface, 0);

console.log(buf);

// <Buffer fe ed fa ce>
// <Buffer ce fa ed fe>

buf.writeUIntBE(value, offset, byteLength[, noAssert])#

buf.writeUIntLE(value, offset, byteLength[, noAssert])#

  • value {Number} Bytes to be written to buffer
  • offset {Number} 0 <= offset <= buf.length
  • byteLength {Number} 0 < byteLength <= 6
  • noAssert {Boolean} Default: false
  • Return: {Number}

Writes value to the buffer at the specified offset and byteLength. Supports up to 48 bits of accuracy. For example:

var b = new Buffer(6);
b.writeUIntBE(0x1234567890ab, 0, 6);
// <Buffer 12 34 56 78 90 ab>

Set noAssert to true to skip validation of value and offset. Defaults to false.

buffer.INSPECT_MAX_BYTES#

  • Number, Default: 50

How many bytes will be returned when buffer.inspect() is called. This can be overridden by user modules. See util.inspect() for more details on buffer.inspect() behavior.

Note that this is a property on the buffer module returned by require('buffer'), not on the Buffer global or a buffer instance.

ES6 iteration#

Buffers can be iterated over using for..of syntax:

var buf = new Buffer([1, 2, 3]);

for (var b of buf)
  console.log(b)

// 1
// 2
// 3

Additionally, the buffer.values(), buffer.keys(), and buffer.entries() methods can be used to create iterators.

Class: SlowBuffer#

Returns an un-pooled Buffer.

In order to avoid the garbage collection overhead of creating many individually allocated Buffers, by default allocations under 4KB are sliced from a single larger allocated object. This approach improves both performance and memory usage since v8 does not need to track and cleanup as many Persistent objects.

In the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using SlowBuffer and copy out the relevant bits.

// need to keep around a few small chunks of memory
var store = [];

socket.on('readable', function() {
  var data = socket.read();
  // allocate for retained data
  var sb = new SlowBuffer(10);
  // copy the data into the new allocation
  data.copy(sb, 0, 0, 10);
  store.push(sb);
});

This should be used only as a last resort after a developer has observed undue memory retention in their applications.

node-v4.2.6/doc/api/buffer.json000644 000766 000024 00000336304 12650222331 016435 0ustar00iojsstaff000000 000000 { "source": "doc/api/buffer.markdown", "modules": [ { "textRaw": "Buffer", "name": "buffer", "stability": 2, "stabilityText": "Stable", "desc": "

Pure JavaScript is Unicode-friendly but not nice to binary data. When\ndealing with TCP streams or the file system, it's necessary to handle octet\nstreams. Node.js has several strategies for manipulating, creating, and\nconsuming octet streams.\n\n

\n

Raw data is stored in instances of the Buffer class. A Buffer is similar\nto an array of integers but corresponds to a raw memory allocation outside\nthe V8 heap. A Buffer cannot be resized.\n\n

\n

The Buffer class is a global, making it very rare that one would need\nto ever require('buffer').\n\n

\n

Converting between Buffers and JavaScript string objects requires an explicit\nencoding method. The different string encodings are:\n\n

\n
    \n
  • 'ascii' - for 7-bit ASCII data only. This encoding method is very fast and\nwill strip the high bit if set.

    \n
  • \n
  • 'utf8' - Multibyte encoded Unicode characters. Many web pages and other\ndocument formats use UTF-8.

    \n
  • \n
  • 'utf16le' - 2 or 4 bytes, little-endian encoded Unicode characters.\nSurrogate pairs (U+10000 to U+10FFFF) are supported.

    \n
  • \n
  • 'ucs2' - Alias of 'utf16le'.

    \n
  • \n
  • 'base64' - Base64 string encoding.

    \n
  • \n
  • 'binary' - A way of encoding the buffer into a one-byte (latin-1)\nencoded string. The string 'latin-1' is not supported. Instead, pass\n'binary' to use 'latin-1' encoding.

    \n
  • \n
  • 'hex' - Encode each byte as two hexadecimal characters.

    \n
  • \n
\n

Creating a typed array from a Buffer works with the following caveats:\n\n

\n
    \n
  1. The buffer's memory is copied, not shared.

    \n
  2. \n
  3. The buffer's memory is interpreted as an array, not a byte array. That is,\nnew Uint32Array(new Buffer([1,2,3,4])) creates a 4-element Uint32Array\nwith elements [1,2,3,4], not a Uint32Array with a single element\n[0x1020304] or [0x4030201].

    \n
  4. \n
\n

NOTE: Node.js v0.8 retained a reference to the buffer in array.buffer instead\nof cloning it.\n\n

\n

While more efficient, it introduces subtle incompatibilities with the typed\narrays specification. ArrayBuffer#slice() makes a copy of the slice while\n[Buffer#slice()][] creates a view.\n\n

\n", "classes": [ { "textRaw": "Class: Buffer", "type": "class", "name": "Buffer", "desc": "

The Buffer class is a global type for dealing with binary data directly.\nIt can be constructed in a variety of ways.\n\n

\n", "classMethods": [ { "textRaw": "Class Method: Buffer.byteLength(string[, encoding])", "type": "classMethod", "name": "byteLength", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`string` String ", "name": "string", "desc": "String" }, { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true } ] }, { "params": [ { "name": "string" }, { "name": "encoding", "optional": true } ] } ], "desc": "

Gives the actual byte length of a string. encoding defaults to 'utf8'.\nThis is not the same as [String.prototype.length][] since that returns the\nnumber of characters in a string.\n\n

\n

Example:\n\n

\n
str = '\\u00bd + \\u00bc = \\u00be';\n\nconsole.log(`${str}: ${str.length} characters, ` +\n            `${Buffer.byteLength(str, 'utf8')} bytes`);\n\n// ½ + ¼ = ¾: 9 characters, 12 bytes
\n" }, { "textRaw": "Class Method: Buffer.compare(buf1, buf2)", "type": "classMethod", "name": "compare", "signatures": [ { "params": [ { "textRaw": "`buf1` {Buffer} ", "name": "buf1", "type": "Buffer" }, { "textRaw": "`buf2` {Buffer} ", "name": "buf2", "type": "Buffer" } ] }, { "params": [ { "name": "buf1" }, { "name": "buf2" } ] } ], "desc": "

The same as [buf1.compare(buf2)][]. Useful for sorting an Array of Buffers:\n\n

\n
var arr = [Buffer('1234'), Buffer('0123')];\narr.sort(Buffer.compare);
\n" }, { "textRaw": "Class Method: Buffer.concat(list[, totalLength])", "type": "classMethod", "name": "concat", "signatures": [ { "params": [ { "textRaw": "`list` {Array} List of Buffer objects to concat ", "name": "list", "type": "Array", "desc": "List of Buffer objects to concat" }, { "textRaw": "`totalLength` {Number} Total length of the buffers in the list when concatenated ", "name": "totalLength", "type": "Number", "desc": "Total length of the buffers in the list when concatenated", "optional": true } ] }, { "params": [ { "name": "list" }, { "name": "totalLength", "optional": true } ] } ], "desc": "

Returns a buffer which is the result of concatenating all the buffers in\nthe list together.\n\n

\n

If the list has no items, or if the totalLength is 0, then it returns a\nzero-length buffer.\n\n

\n

If totalLength is not provided, it is read from the buffers in the list.\nHowever, this adds an additional loop to the function, so it is faster\nto provide the length explicitly.\n\n

\n

Example: build a single buffer from a list of three buffers:\n\n

\n
var buf1 = new Buffer(10);\nvar buf2 = new Buffer(14);\nvar buf3 = new Buffer(18);\n\nbuf1.fill(0);\nbuf2.fill(0);\nbuf3.fill(0);\n\nvar buffers = [buf1, buf2, buf3];\n\nvar totalLength = 0;\nfor (var i = 0; i < buffers.length; i++) {\n  totalLength += buffers[i].length;\n}\n\nconsole.log(totalLength);\nvar bufA = Buffer.concat(buffers, totalLength);\nconsole.log(bufA);\nconsole.log(bufA.length);\n\n// 42\n// <Buffer 00 00 00 00 ...>\n// 42
\n" }, { "textRaw": "Class Method: Buffer.isBuffer(obj)", "type": "classMethod", "name": "isBuffer", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`obj` Object ", "name": "obj", "desc": "Object" } ] }, { "params": [ { "name": "obj" } ] } ], "desc": "

Tests if obj is a Buffer.\n\n

\n" }, { "textRaw": "Class Method: Buffer.isEncoding(encoding)", "type": "classMethod", "name": "isEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The encoding string to test ", "name": "encoding", "type": "String", "desc": "The encoding string to test" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Returns true if the encoding is a valid encoding argument, or false\notherwise.\n\n

\n" } ], "methods": [ { "textRaw": "buffer.entries()", "type": "method", "name": "entries", "desc": "

Creates iterator for [index, byte] arrays.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buffer.keys()", "type": "method", "name": "keys", "desc": "

Creates iterator for buffer keys (indices).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buffer.values()", "type": "method", "name": "values", "desc": "

Creates iterator for buffer values (bytes). This function is called automatically\nwhen buffer is used in a for..of statement.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buf.compare(otherBuffer)", "type": "method", "name": "compare", "signatures": [ { "params": [ { "textRaw": "`otherBuffer` {Buffer} ", "name": "otherBuffer", "type": "Buffer" } ] }, { "params": [ { "name": "otherBuffer" } ] } ], "desc": "

Returns a number indicating whether this comes before, after, or is\nthe same as the otherBuffer in sort order.\n\n\n

\n" }, { "textRaw": "buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])", "type": "method", "name": "copy", "signatures": [ { "params": [ { "textRaw": "`targetBuffer` Buffer object - Buffer to copy into ", "name": "targetBuffer", "desc": "Buffer object - Buffer to copy into" }, { "textRaw": "`targetStart` Number, Optional, Default: 0 ", "name": "targetStart", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`sourceStart` Number, Optional, Default: 0 ", "name": "sourceStart", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`sourceEnd` Number, Optional, Default: `buffer.length` ", "name": "sourceEnd", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "targetBuffer" }, { "name": "targetStart", "optional": true }, { "name": "sourceStart", "optional": true }, { "name": "sourceEnd", "optional": true } ] } ], "desc": "

Copies data from a region of this buffer to a region in the target buffer even\nif the target memory region overlaps with the source. If undefined, the\ntargetStart and sourceStart parameters default to 0 while sourceEnd\ndefaults to buffer.length.\n\n

\n

Returns the number of bytes copied.\n\n

\n

Example: build two Buffers, then copy buf1 from byte 16 through byte 19\ninto buf2, starting at the 8th byte in buf2.\n\n

\n
buf1 = new Buffer(26);\nbuf2 = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf1[i] = i + 97; // 97 is ASCII a\n  buf2[i] = 33; // ASCII !\n}\n\nbuf1.copy(buf2, 8, 16, 20);\nconsole.log(buf2.toString('ascii', 0, 25));\n\n// !!!!!!!!qrst!!!!!!!!!!!!!
\n

Example: Build a single buffer, then copy data from one region to an overlapping\nregion in the same buffer\n\n

\n
buf = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf[i] = i + 97; // 97 is ASCII a\n}\n\nbuf.copy(buf, 0, 4, 10);\nconsole.log(buf.toString());\n\n// efghijghijklmnopqrstuvwxyz
\n" }, { "textRaw": "buf.equals(otherBuffer)", "type": "method", "name": "equals", "signatures": [ { "params": [ { "textRaw": "`otherBuffer` {Buffer} ", "name": "otherBuffer", "type": "Buffer" } ] }, { "params": [ { "name": "otherBuffer" } ] } ], "desc": "

Returns a boolean indicating whether this and otherBuffer have the same bytes.\n\n

\n" }, { "textRaw": "buf.fill(value[, offset][, end])", "type": "method", "name": "fill", "signatures": [ { "params": [ { "textRaw": "`value` ", "name": "value" }, { "textRaw": "`offset` Number, Optional ", "name": "offset", "optional": true, "desc": "Number" }, { "textRaw": "`end` Number, Optional ", "name": "end", "optional": true, "desc": "Number" } ] }, { "params": [ { "name": "value" }, { "name": "offset", "optional": true }, { "name": "end", "optional": true } ] } ], "desc": "

Fills the buffer with the specified value. If the offset (defaults to 0)\nand end (defaults to buffer.length) are not given it will fill the entire\nbuffer.\n\n

\n
var b = new Buffer(50);\nb.fill('h');
\n" }, { "textRaw": "buf.indexOf(value[, byteOffset])", "type": "method", "name": "indexOf", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`value` String, Buffer or Number ", "name": "value", "desc": "String, Buffer or Number" }, { "textRaw": "`byteOffset` Number, Optional, Default: 0 ", "name": "byteOffset", "desc": "Number, Optional, Default: 0", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "byteOffset", "optional": true } ] } ], "desc": "

Operates similar to [Array#indexOf()][]. Accepts a String, Buffer or Number.\nStrings are interpreted as UTF8. Buffers will use the entire buffer. So in order\nto compare a partial Buffer use [Buffer#slice()][]. Numbers can range from 0 to\n255.\n\n

\n" }, { "textRaw": "buf.readDoubleBE(offset[, noAssert])", "type": "method", "name": "readDoubleBE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 64-bit double from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\n\nbuf[0] = 0x55;\nbuf[1] = 0x55;\nbuf[2] = 0x55;\nbuf[3] = 0x55;\nbuf[4] = 0x55;\nbuf[5] = 0x55;\nbuf[6] = 0xd5;\nbuf[7] = 0x3f;\n\nconsole.log(buf.readDoubleLE(0));\n\n// 0.3333333333333333
\n" }, { "textRaw": "buf.readDoubleLE(offset[, noAssert])", "type": "method", "name": "readDoubleLE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 64-bit double from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\n\nbuf[0] = 0x55;\nbuf[1] = 0x55;\nbuf[2] = 0x55;\nbuf[3] = 0x55;\nbuf[4] = 0x55;\nbuf[5] = 0x55;\nbuf[6] = 0xd5;\nbuf[7] = 0x3f;\n\nconsole.log(buf.readDoubleLE(0));\n\n// 0.3333333333333333
\n" }, { "textRaw": "buf.readFloatBE(offset[, noAssert])", "type": "method", "name": "readFloatBE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 32-bit float from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x00;\nbuf[1] = 0x00;\nbuf[2] = 0x80;\nbuf[3] = 0x3f;\n\nconsole.log(buf.readFloatLE(0));\n\n// 0x01
\n" }, { "textRaw": "buf.readFloatLE(offset[, noAssert])", "type": "method", "name": "readFloatLE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a 32-bit float from the buffer at the specified offset with specified\nendian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x00;\nbuf[1] = 0x00;\nbuf[2] = 0x80;\nbuf[3] = 0x3f;\n\nconsole.log(buf.readFloatLE(0));\n\n// 0x01
\n" }, { "textRaw": "buf.readInt8(offset[, noAssert])", "type": "method", "name": "readInt8", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 8-bit integer from the buffer at the specified offset.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt8, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt16BE(offset[, noAssert])", "type": "method", "name": "readInt16BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt16*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt16LE(offset[, noAssert])", "type": "method", "name": "readInt16LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt16*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt32BE(offset[, noAssert])", "type": "method", "name": "readInt32BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt32*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readInt32LE(offset[, noAssert])", "type": "method", "name": "readInt32LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads a signed 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Works as buffer.readUInt32*, except buffer contents are treated as two's\ncomplement signed values.\n\n

\n" }, { "textRaw": "buf.readIntBE(offset, byteLength[, noAssert])", "type": "method", "name": "readIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n" }, { "textRaw": "buf.readIntLE(offset, byteLength[, noAssert])", "type": "method", "name": "readIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n" }, { "textRaw": "buf.readUInt8(offset[, noAssert])", "type": "method", "name": "readUInt8", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 8-bit integer from the buffer at the specified offset.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nfor (ii = 0; ii < buf.length; ii++) {\n  console.log(buf.readUInt8(ii));\n}\n\n// 0x3\n// 0x4\n// 0x23\n// 0x42
\n" }, { "textRaw": "buf.readUInt16BE(offset[, noAssert])", "type": "method", "name": "readUInt16BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt16BE(0));\nconsole.log(buf.readUInt16LE(0));\nconsole.log(buf.readUInt16BE(1));\nconsole.log(buf.readUInt16LE(1));\nconsole.log(buf.readUInt16BE(2));\nconsole.log(buf.readUInt16LE(2));\n\n// 0x0304\n// 0x0403\n// 0x0423\n// 0x2304\n// 0x2342\n// 0x4223
\n" }, { "textRaw": "buf.readUInt16LE(offset[, noAssert])", "type": "method", "name": "readUInt16LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 16-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt16BE(0));\nconsole.log(buf.readUInt16LE(0));\nconsole.log(buf.readUInt16BE(1));\nconsole.log(buf.readUInt16LE(1));\nconsole.log(buf.readUInt16BE(2));\nconsole.log(buf.readUInt16LE(2));\n\n// 0x0304\n// 0x0403\n// 0x0423\n// 0x2304\n// 0x2342\n// 0x4223
\n" }, { "textRaw": "buf.readUInt32BE(offset[, noAssert])", "type": "method", "name": "readUInt32BE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt32BE(0));\nconsole.log(buf.readUInt32LE(0));\n\n// 0x03042342\n// 0x42230403
\n" }, { "textRaw": "buf.readUInt32LE(offset[, noAssert])", "type": "method", "name": "readUInt32LE", "signatures": [ { "return": { "textRaw": "Return: Number ", "name": "return", "desc": "Number" }, "params": [ { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Reads an unsigned 32-bit integer from the buffer at the specified offset with\nspecified endian format.\n\n

\n

Set noAssert to true to skip validation of offset. This means that offset\nmay be beyond the end of the buffer. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\n\nbuf[0] = 0x3;\nbuf[1] = 0x4;\nbuf[2] = 0x23;\nbuf[3] = 0x42;\n\nconsole.log(buf.readUInt32BE(0));\nconsole.log(buf.readUInt32LE(0));\n\n// 0x03042342\n// 0x42230403
\n" }, { "textRaw": "buf.readUIntBE(offset, byteLength[, noAssert])", "type": "method", "name": "readUIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n" }, { "textRaw": "buf.readUIntLE(offset, byteLength[, noAssert])", "type": "method", "name": "readUIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

A generalized version of all numeric read methods. Supports up to 48 bits of\naccuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUInt16LE(0x90ab, 0);\nb.writeUInt32LE(0x12345678, 2);\nb.readUIntLE(0, 6).toString(16);  // Specify 6 bytes (48 bits)\n// output: '1234567890ab'
\n" }, { "textRaw": "buf.slice([start[, end]])", "type": "method", "name": "slice", "signatures": [ { "params": [ { "textRaw": "`start` Number, Optional, Default: 0 ", "name": "start", "desc": "Number, Optional, Default: 0" }, { "textRaw": "`end` Number, Optional, Default: `buffer.length` ", "name": "end", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "start" }, { "name": "end]", "optional": true } ] } ], "desc": "

Returns a new buffer which references the same memory as the old, but offset\nand cropped by the start (defaults to 0) and end (defaults to\nbuffer.length) indexes. Negative indexes start from the end of the buffer.\n\n

\n

Modifying the new buffer slice will modify memory in the original buffer!\n\n

\n

Example: build a Buffer with the ASCII alphabet, take a slice, then modify one\nbyte from the original Buffer.\n\n

\n
var buf1 = new Buffer(26);\n\nfor (var i = 0 ; i < 26 ; i++) {\n  buf1[i] = i + 97; // 97 is ASCII a\n}\n\nvar buf2 = buf1.slice(0, 3);\nconsole.log(buf2.toString('ascii', 0, buf2.length));\nbuf1[0] = 33;\nconsole.log(buf2.toString('ascii', 0, buf2.length));\n\n// abc\n// !bc
\n" }, { "textRaw": "buf.toString([encoding][, start][, end])", "type": "method", "name": "toString", "signatures": [ { "params": [ { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true }, { "textRaw": "`start` Number, Optional, Default: 0 ", "name": "start", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`end` Number, Optional, Default: `buffer.length` ", "name": "end", "desc": "Number, Optional, Default: `buffer.length`", "optional": true } ] }, { "params": [ { "name": "encoding", "optional": true }, { "name": "start", "optional": true }, { "name": "end", "optional": true } ] } ], "desc": "

Decodes and returns a string from buffer data encoded using the specified\ncharacter set encoding. If encoding is undefined or null, then encoding\ndefaults to 'utf8'. The start and end parameters default to 0 and\nbuffer.length when undefined.\n\n

\n
buf = new Buffer(26);\nfor (var i = 0 ; i < 26 ; i++) {\n  buf[i] = i + 97; // 97 is ASCII a\n}\nbuf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz\nbuf.toString('ascii',0,5); // outputs: abcde\nbuf.toString('utf8',0,5); // outputs: abcde\nbuf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde
\n

See buf.write() example, below.\n\n\n

\n" }, { "textRaw": "buf.toJSON()", "type": "method", "name": "toJSON", "desc": "

Returns a JSON representation of the Buffer instance. JSON.stringify\nimplicitly calls this function when stringifying a Buffer instance.\n\n

\n

Example:\n\n

\n
var buf = new Buffer('test');\nvar json = JSON.stringify(buf);\n\nconsole.log(json);\n// '{"type":"Buffer","data":[116,101,115,116]}'\n\nvar copy = JSON.parse(json, function(key, value) {\n    return value && value.type === 'Buffer'\n      ? new Buffer(value.data)\n      : value;\n  });\n\nconsole.log(copy);\n// <Buffer 74 65 73 74>
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "buf.write(string[, offset][, length][, encoding])", "type": "method", "name": "write", "signatures": [ { "params": [ { "textRaw": "`string` String - data to be written to buffer ", "name": "string", "desc": "String - data to be written to buffer" }, { "textRaw": "`offset` Number, Optional, Default: 0 ", "name": "offset", "desc": "Number, Optional, Default: 0", "optional": true }, { "textRaw": "`length` Number, Optional, Default: `buffer.length - offset` ", "name": "length", "desc": "Number, Optional, Default: `buffer.length - offset`", "optional": true }, { "textRaw": "`encoding` String, Optional, Default: 'utf8' ", "name": "encoding", "desc": "String, Optional, Default: 'utf8'", "optional": true } ] }, { "params": [ { "name": "string" }, { "name": "offset", "optional": true }, { "name": "length", "optional": true }, { "name": "encoding", "optional": true } ] } ], "desc": "

Writes string to the buffer at offset using the given encoding.\noffset defaults to 0, encoding defaults to 'utf8'. length is\nthe number of bytes to write. Returns number of octets written. If buffer did\nnot contain enough space to fit the entire string, it will write a partial\namount of the string. length defaults to buffer.length - offset.\nThe method will not write partial characters.\n\n

\n
buf = new Buffer(256);\nlen = buf.write('\\u00bd + \\u00bc = \\u00be', 0);\nconsole.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`);
\n" }, { "textRaw": "buf.writeDoubleBE(value, offset[, noAssert])", "type": "method", "name": "writeDoubleBE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid 64-bit double.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\nbuf.writeDoubleBE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeDoubleLE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 43 eb d5 b7 dd f9 5f d7>\n// <Buffer d7 5f f9 dd b7 d5 eb 43>
\n" }, { "textRaw": "buf.writeDoubleLE(value, offset[, noAssert])", "type": "method", "name": "writeDoubleLE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid 64-bit double.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(8);\nbuf.writeDoubleBE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeDoubleLE(0xdeadbeefcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 43 eb d5 b7 dd f9 5f d7>\n// <Buffer d7 5f f9 dd b7 d5 eb 43>
\n" }, { "textRaw": "buf.writeFloatBE(value, offset[, noAssert])", "type": "method", "name": "writeFloatBE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. Behavior is unspecified if value is not a 32-bit float.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeFloatLE(0xcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 4f 4a fe bb>\n// <Buffer bb fe 4a 4f>
\n" }, { "textRaw": "buf.writeFloatLE(value, offset[, noAssert])", "type": "method", "name": "writeFloatLE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. Behavior is unspecified if value is not a 32-bit float.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeFloatBE(0xcafebabe, 0);\n\nconsole.log(buf);\n\nbuf.writeFloatLE(0xcafebabe, 0);\n\nconsole.log(buf);\n\n// <Buffer 4f 4a fe bb>\n// <Buffer bb fe 4a 4f>
\n" }, { "textRaw": "buf.writeInt8(value, offset[, noAssert])", "type": "method", "name": "writeInt8", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset. value must be a\nvalid signed 8-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt8, except value is written out as a two's complement\nsigned integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt16BE(value, offset[, noAssert])", "type": "method", "name": "writeInt16BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt16*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt16LE(value, offset[, noAssert])", "type": "method", "name": "writeInt16LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt16*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt32BE(value, offset[, noAssert])", "type": "method", "name": "writeInt32BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt32*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeInt32LE(value, offset[, noAssert])", "type": "method", "name": "writeInt32LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid signed 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Works as buffer.writeUInt32*, except value is written out as a two's\ncomplement signed integer into buffer.\n\n

\n" }, { "textRaw": "buf.writeIntBE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeIntLE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeUInt8(value, offset[, noAssert])", "type": "method", "name": "writeUInt8", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset. value must be a\nvalid unsigned 8-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt8(0x3, 0);\nbuf.writeUInt8(0x4, 1);\nbuf.writeUInt8(0x23, 2);\nbuf.writeUInt8(0x42, 3);\n\nconsole.log(buf);\n\n// <Buffer 03 04 23 42>
\n" }, { "textRaw": "buf.writeUInt16BE(value, offset[, noAssert])", "type": "method", "name": "writeUInt16BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n\n// <Buffer de ad be ef>\n// <Buffer ad de ef be>
\n" }, { "textRaw": "buf.writeUInt16LE(value, offset[, noAssert])", "type": "method", "name": "writeUInt16LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 16-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt16BE(0xdead, 0);\nbuf.writeUInt16BE(0xbeef, 2);\n\nconsole.log(buf);\n\nbuf.writeUInt16LE(0xdead, 0);\nbuf.writeUInt16LE(0xbeef, 2);\n\nconsole.log(buf);\n\n// <Buffer de ad be ef>\n// <Buffer ad de ef be>
\n" }, { "textRaw": "buf.writeUInt32BE(value, offset[, noAssert])", "type": "method", "name": "writeUInt32BE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n\n// <Buffer fe ed fa ce>\n// <Buffer ce fa ed fe>
\n" }, { "textRaw": "buf.writeUInt32LE(value, offset[, noAssert])", "type": "method", "name": "writeUInt32LE", "signatures": [ { "params": [ { "textRaw": "`value` Number ", "name": "value", "desc": "Number" }, { "textRaw": "`offset` Number ", "name": "offset", "desc": "Number" }, { "textRaw": "`noAssert` Boolean, Optional, Default: false ", "name": "noAssert", "desc": "Boolean, Optional, Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset with specified endian\nformat. value must be a valid unsigned 32-bit integer.\n\n

\n

Set noAssert to true to skip validation of value and offset. This means\nthat value may be too large for the specific function and offset may be\nbeyond the end of the buffer leading to the values being silently dropped. This\nshould not be used unless you are certain of correctness. Defaults to false.\n\n

\n

Example:\n\n

\n
var buf = new Buffer(4);\nbuf.writeUInt32BE(0xfeedface, 0);\n\nconsole.log(buf);\n\nbuf.writeUInt32LE(0xfeedface, 0);\n\nconsole.log(buf);\n\n// <Buffer fe ed fa ce>\n// <Buffer ce fa ed fe>
\n" }, { "textRaw": "buf.writeUIntBE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeUIntBE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" }, { "textRaw": "buf.writeUIntLE(value, offset, byteLength[, noAssert])", "type": "method", "name": "writeUIntLE", "signatures": [ { "return": { "textRaw": "Return: {Number} ", "name": "return", "type": "Number" }, "params": [ { "textRaw": "`value` {Number} Bytes to be written to buffer ", "name": "value", "type": "Number", "desc": "Bytes to be written to buffer" }, { "textRaw": "`offset` {Number} `0 <= offset <= buf.length` ", "name": "offset", "type": "Number", "desc": "`0 <= offset <= buf.length`" }, { "textRaw": "`byteLength` {Number} `0 < byteLength <= 6` ", "name": "byteLength", "type": "Number", "desc": "`0 < byteLength <= 6`" }, { "textRaw": "`noAssert` {Boolean} Default: false ", "name": "noAssert", "type": "Boolean", "desc": "Default: false", "optional": true } ] }, { "params": [ { "name": "value" }, { "name": "offset" }, { "name": "byteLength" }, { "name": "noAssert", "optional": true } ] } ], "desc": "

Writes value to the buffer at the specified offset and byteLength.\nSupports up to 48 bits of accuracy. For example:\n\n

\n
var b = new Buffer(6);\nb.writeUIntBE(0x1234567890ab, 0, 6);\n// <Buffer 12 34 56 78 90 ab>
\n

Set noAssert to true to skip validation of value and offset. Defaults\nto false.\n\n

\n" } ], "properties": [ { "textRaw": "buf[index]", "name": "[index]", "desc": "

Get and set the octet at index. The values refer to individual bytes,\nso the legal range is between 0x00 and 0xFF hex or 0 and 255.\n\n

\n

Example: copy an ASCII string into a buffer, one byte at a time:\n\n

\n
str = "Node.js";\nbuf = new Buffer(str.length);\n\nfor (var i = 0; i < str.length ; i++) {\n  buf[i] = str.charCodeAt(i);\n}\n\nconsole.log(buf);\n\n// Node.js
\n" }, { "textRaw": "`length` Number ", "name": "length", "desc": "

The size of the buffer in bytes. Note that this is not necessarily the size\nof the contents. length refers to the amount of memory allocated for the\nbuffer object. It does not change when the contents of the buffer are changed.\n\n

\n
buf = new Buffer(1234);\n\nconsole.log(buf.length);\nbuf.write('some string', 0, 'ascii');\nconsole.log(buf.length);\n\n// 1234\n// 1234
\n

While the length property is not immutable, changing the value of length\ncan result in undefined and inconsistent behavior. Applications that wish to\nmodify the length of a buffer should therefore treat length as read-only and\nuse [buf.slice][] to create a new buffer.\n\n

\n
buf = new Buffer(10);\nbuf.write('abcdefghj', 0, 'ascii');\nconsole.log(buf.length); // 10\nbuf = buf.slice(0,5);\nconsole.log(buf.length); // 5
\n", "shortDesc": "Number" } ], "signatures": [ { "params": [ { "textRaw": "`array` Array ", "name": "array", "desc": "Array" } ], "desc": "

Allocates a new buffer using an array of octets.\n\n

\n" }, { "params": [ { "name": "array" } ], "desc": "

Allocates a new buffer using an array of octets.\n\n

\n" }, { "params": [ { "textRaw": "`buffer` {Buffer} ", "name": "buffer", "type": "Buffer" } ], "desc": "

Copies the passed buffer data onto a new Buffer instance.\n\n

\n" }, { "params": [ { "name": "buffer" } ], "desc": "

Copies the passed buffer data onto a new Buffer instance.\n\n

\n" }, { "params": [ { "textRaw": "`size` Number ", "name": "size", "desc": "Number" } ], "desc": "

Allocates a new buffer of size bytes. size must be less than\n1,073,741,824 bytes (1 GB) on 32-bit architectures or\n2,147,483,648 bytes (2 GB) on 64-bit architectures.\nOtherwise, a [RangeError][] is thrown.\n\n

\n

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So\nthe contents of a newly created Buffer are unknown and could contain\nsensitive data. Use [buf.fill(0)][] to initialize a buffer to zeroes.\n\n

\n" }, { "params": [ { "name": "size" } ], "desc": "

Allocates a new buffer of size bytes. size must be less than\n1,073,741,824 bytes (1 GB) on 32-bit architectures or\n2,147,483,648 bytes (2 GB) on 64-bit architectures.\nOtherwise, a [RangeError][] is thrown.\n\n

\n

Unlike ArrayBuffers, the underlying memory for buffers is not initialized. So\nthe contents of a newly created Buffer are unknown and could contain\nsensitive data. Use [buf.fill(0)][] to initialize a buffer to zeroes.\n\n

\n" }, { "params": [ { "textRaw": "`str` String - string to encode. ", "name": "str", "desc": "String - string to encode." }, { "textRaw": "`encoding` String - encoding to use, Optional. ", "name": "encoding", "desc": "String - encoding to use, Optional.", "optional": true } ], "desc": "

Allocates a new buffer containing the given str.\nencoding defaults to 'utf8'.\n\n

\n" }, { "params": [ { "name": "str" }, { "name": "encoding", "optional": true } ], "desc": "

Allocates a new buffer containing the given str.\nencoding defaults to 'utf8'.\n\n

\n" } ] }, { "textRaw": "Class: SlowBuffer", "type": "class", "name": "SlowBuffer", "desc": "

Returns an un-pooled Buffer.\n\n

\n

In order to avoid the garbage collection overhead of creating many individually\nallocated Buffers, by default allocations under 4KB are sliced from a single\nlarger allocated object. This approach improves both performance and memory\nusage since v8 does not need to track and cleanup as many Persistent objects.\n\n

\n

In the case where a developer may need to retain a small chunk of memory from a\npool for an indeterminate amount of time, it may be appropriate to create an\nun-pooled Buffer instance using SlowBuffer and copy out the relevant bits.\n\n

\n
// need to keep around a few small chunks of memory\nvar store = [];\n\nsocket.on('readable', function() {\n  var data = socket.read();\n  // allocate for retained data\n  var sb = new SlowBuffer(10);\n  // copy the data into the new allocation\n  data.copy(sb, 0, 0, 10);\n  store.push(sb);\n});
\n

This should be used only as a last resort after a developer has observed\nundue memory retention in their applications.\n\n

\n" } ], "properties": [ { "textRaw": "`INSPECT_MAX_BYTES` Number, Default: 50 ", "name": "INSPECT_MAX_BYTES", "desc": "

How many bytes will be returned when buffer.inspect() is called. This can\nbe overridden by user modules. See [util.inspect()][] for more details on\nbuffer.inspect() behavior.\n\n

\n

Note that this is a property on the buffer module returned by\nrequire('buffer'), not on the Buffer global or a buffer instance.\n\n

\n", "shortDesc": "Number, Default: 50" } ], "modules": [ { "textRaw": "ES6 iteration", "name": "es6_iteration", "desc": "

Buffers can be iterated over using for..of syntax:\n\n

\n
var buf = new Buffer([1, 2, 3]);\n\nfor (var b of buf)\n  console.log(b)\n\n// 1\n// 2\n// 3
\n

Additionally, the buffer.values(), buffer.keys(), and buffer.entries()\nmethods can be used to create iterators.\n\n

\n", "type": "module", "displayName": "ES6 iteration" } ], "type": "module", "displayName": "Buffer" } ] } node-v4.2.6/doc/api/buffer.markdown000644 000766 000024 00000066610 12650222326 017312 0ustar00iojsstaff000000 000000 # Buffer Stability: 2 - Stable Pure JavaScript is Unicode-friendly but not nice to binary data. When dealing with TCP streams or the file system, it's necessary to handle octet streams. Node.js has several strategies for manipulating, creating, and consuming octet streams. Raw data is stored in instances of the `Buffer` class. A `Buffer` is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A `Buffer` cannot be resized. The `Buffer` class is a global, making it very rare that one would need to ever `require('buffer')`. Converting between Buffers and JavaScript string objects requires an explicit encoding method. The different string encodings are: * `'ascii'` - for 7-bit ASCII data only. This encoding method is very fast and will strip the high bit if set. * `'utf8'` - Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. * `'utf16le'` - 2 or 4 bytes, little-endian encoded Unicode characters. Surrogate pairs (U+10000 to U+10FFFF) are supported. * `'ucs2'` - Alias of `'utf16le'`. * `'base64'` - Base64 string encoding. * `'binary'` - A way of encoding the buffer into a one-byte (`latin-1`) encoded string. The string `'latin-1'` is not supported. Instead, pass `'binary'` to use `'latin-1'` encoding. * `'hex'` - Encode each byte as two hexadecimal characters. Creating a typed array from a `Buffer` works with the following caveats: 1. The buffer's memory is copied, not shared. 2. The buffer's memory is interpreted as an array, not a byte array. That is, `new Uint32Array(new Buffer([1,2,3,4]))` creates a 4-element `Uint32Array` with elements `[1,2,3,4]`, not a `Uint32Array` with a single element `[0x1020304]` or `[0x4030201]`. NOTE: Node.js v0.8 retained a reference to the buffer in `array.buffer` instead of cloning it. While more efficient, it introduces subtle incompatibilities with the typed arrays specification. `ArrayBuffer#slice()` makes a copy of the slice while [`Buffer#slice()`][] creates a view. ## Class: Buffer The Buffer class is a global type for dealing with binary data directly. It can be constructed in a variety of ways. ### new Buffer(array) * `array` Array Allocates a new buffer using an `array` of octets. ### new Buffer(buffer) * `buffer` {Buffer} Copies the passed `buffer` data onto a new `Buffer` instance. ### new Buffer(size) * `size` Number Allocates a new buffer of `size` bytes. `size` must be less than 1,073,741,824 bytes (1 GB) on 32-bit architectures or 2,147,483,648 bytes (2 GB) on 64-bit architectures. Otherwise, a [`RangeError`][] is thrown. Unlike `ArrayBuffers`, the underlying memory for buffers is not initialized. So the contents of a newly created `Buffer` are unknown and could contain sensitive data. Use [`buf.fill(0)`][] to initialize a buffer to zeroes. ### new Buffer(str[, encoding]) * `str` String - string to encode. * `encoding` String - encoding to use, Optional. Allocates a new buffer containing the given `str`. `encoding` defaults to `'utf8'`. ### Class Method: Buffer.byteLength(string[, encoding]) * `string` String * `encoding` String, Optional, Default: 'utf8' * Return: Number Gives the actual byte length of a string. `encoding` defaults to `'utf8'`. This is not the same as [`String.prototype.length`][] since that returns the number of *characters* in a string. Example: str = '\u00bd + \u00bc = \u00be'; console.log(`${str}: ${str.length} characters, ` + `${Buffer.byteLength(str, 'utf8')} bytes`); // ½ + ¼ = ¾: 9 characters, 12 bytes ### Class Method: Buffer.compare(buf1, buf2) * `buf1` {Buffer} * `buf2` {Buffer} The same as [`buf1.compare(buf2)`][]. Useful for sorting an Array of Buffers: var arr = [Buffer('1234'), Buffer('0123')]; arr.sort(Buffer.compare); ### Class Method: Buffer.concat(list[, totalLength]) * `list` {Array} List of Buffer objects to concat * `totalLength` {Number} Total length of the buffers in the list when concatenated Returns a buffer which is the result of concatenating all the buffers in the list together. If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. Example: build a single buffer from a list of three buffers: var buf1 = new Buffer(10); var buf2 = new Buffer(14); var buf3 = new Buffer(18); buf1.fill(0); buf2.fill(0); buf3.fill(0); var buffers = [buf1, buf2, buf3]; var totalLength = 0; for (var i = 0; i < buffers.length; i++) { totalLength += buffers[i].length; } console.log(totalLength); var bufA = Buffer.concat(buffers, totalLength); console.log(bufA); console.log(bufA.length); // 42 // // 42 ### Class Method: Buffer.isBuffer(obj) * `obj` Object * Return: Boolean Tests if `obj` is a `Buffer`. ### Class Method: Buffer.isEncoding(encoding) * `encoding` {String} The encoding string to test Returns true if the `encoding` is a valid encoding argument, or false otherwise. ### buffer.entries() Creates iterator for `[index, byte]` arrays. ### buffer.keys() Creates iterator for buffer keys (indices). ### buffer.values() Creates iterator for buffer values (bytes). This function is called automatically when `buffer` is used in a `for..of` statement. ### buf[index] Get and set the octet at `index`. The values refer to individual bytes, so the legal range is between `0x00` and `0xFF` hex or `0` and `255`. Example: copy an ASCII string into a buffer, one byte at a time: str = "Node.js"; buf = new Buffer(str.length); for (var i = 0; i < str.length ; i++) { buf[i] = str.charCodeAt(i); } console.log(buf); // Node.js ### buf.compare(otherBuffer) * `otherBuffer` {Buffer} Returns a number indicating whether `this` comes before, after, or is the same as the `otherBuffer` in sort order. ### buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd]) * `targetBuffer` Buffer object - Buffer to copy into * `targetStart` Number, Optional, Default: 0 * `sourceStart` Number, Optional, Default: 0 * `sourceEnd` Number, Optional, Default: `buffer.length` Copies data from a region of this buffer to a region in the target buffer even if the target memory region overlaps with the source. If `undefined`, the `targetStart` and `sourceStart` parameters default to `0` while `sourceEnd` defaults to `buffer.length`. Returns the number of bytes copied. Example: build two Buffers, then copy `buf1` from byte 16 through byte 19 into `buf2`, starting at the 8th byte in `buf2`. buf1 = new Buffer(26); buf2 = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a buf2[i] = 33; // ASCII ! } buf1.copy(buf2, 8, 16, 20); console.log(buf2.toString('ascii', 0, 25)); // !!!!!!!!qrst!!!!!!!!!!!!! Example: Build a single buffer, then copy data from one region to an overlapping region in the same buffer buf = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97; // 97 is ASCII a } buf.copy(buf, 0, 4, 10); console.log(buf.toString()); // efghijghijklmnopqrstuvwxyz ### buf.equals(otherBuffer) * `otherBuffer` {Buffer} Returns a boolean indicating whether `this` and `otherBuffer` have the same bytes. ### buf.fill(value[, offset][, end]) * `value` * `offset` Number, Optional * `end` Number, Optional Fills the buffer with the specified value. If the `offset` (defaults to `0`) and `end` (defaults to `buffer.length`) are not given it will fill the entire buffer. var b = new Buffer(50); b.fill('h'); ### buf.indexOf(value[, byteOffset]) * `value` String, Buffer or Number * `byteOffset` Number, Optional, Default: 0 * Return: Number Operates similar to [`Array#indexOf()`][]. Accepts a String, Buffer or Number. Strings are interpreted as UTF8. Buffers will use the entire buffer. So in order to compare a partial Buffer use [`Buffer#slice()`][]. Numbers can range from 0 to 255. ### buf.length * Number The size of the buffer in bytes. Note that this is not necessarily the size of the contents. `length` refers to the amount of memory allocated for the buffer object. It does not change when the contents of the buffer are changed. buf = new Buffer(1234); console.log(buf.length); buf.write('some string', 0, 'ascii'); console.log(buf.length); // 1234 // 1234 While the `length` property is not immutable, changing the value of `length` can result in undefined and inconsistent behavior. Applications that wish to modify the length of a buffer should therefore treat `length` as read-only and use [`buf.slice`][] to create a new buffer. buf = new Buffer(10); buf.write('abcdefghj', 0, 'ascii'); console.log(buf.length); // 10 buf = buf.slice(0,5); console.log(buf.length); // 5 ### buf.readDoubleBE(offset[, noAssert]) ### buf.readDoubleLE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads a 64-bit double from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Example: var buf = new Buffer(8); buf[0] = 0x55; buf[1] = 0x55; buf[2] = 0x55; buf[3] = 0x55; buf[4] = 0x55; buf[5] = 0x55; buf[6] = 0xd5; buf[7] = 0x3f; console.log(buf.readDoubleLE(0)); // 0.3333333333333333 ### buf.readFloatBE(offset[, noAssert]) ### buf.readFloatLE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads a 32-bit float from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Example: var buf = new Buffer(4); buf[0] = 0x00; buf[1] = 0x00; buf[2] = 0x80; buf[3] = 0x3f; console.log(buf.readFloatLE(0)); // 0x01 ### buf.readInt8(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads a signed 8-bit integer from the buffer at the specified offset. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt8`, except buffer contents are treated as two's complement signed values. ### buf.readInt16BE(offset[, noAssert]) ### buf.readInt16LE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads a signed 16-bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt16*`, except buffer contents are treated as two's complement signed values. ### buf.readInt32BE(offset[, noAssert]) ### buf.readInt32LE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads a signed 32-bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt32*`, except buffer contents are treated as two's complement signed values. ### buf.readIntBE(offset, byteLength[, noAssert]) ### buf.readIntLE(offset, byteLength[, noAssert]) * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example: var b = new Buffer(6); b.writeUInt16LE(0x90ab, 0); b.writeUInt32LE(0x12345678, 2); b.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) // output: '1234567890ab' Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. ### buf.readUInt8(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads an unsigned 8-bit integer from the buffer at the specified offset. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Example: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; for (ii = 0; ii < buf.length; ii++) { console.log(buf.readUInt8(ii)); } // 0x3 // 0x4 // 0x23 // 0x42 ### buf.readUInt16BE(offset[, noAssert]) ### buf.readUInt16LE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads an unsigned 16-bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Example: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; console.log(buf.readUInt16BE(0)); console.log(buf.readUInt16LE(0)); console.log(buf.readUInt16BE(1)); console.log(buf.readUInt16LE(1)); console.log(buf.readUInt16BE(2)); console.log(buf.readUInt16LE(2)); // 0x0304 // 0x0403 // 0x0423 // 0x2304 // 0x2342 // 0x4223 ### buf.readUInt32BE(offset[, noAssert]) ### buf.readUInt32LE(offset[, noAssert]) * `offset` Number * `noAssert` Boolean, Optional, Default: false * Return: Number Reads an unsigned 32-bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. Defaults to `false`. Example: var buf = new Buffer(4); buf[0] = 0x3; buf[1] = 0x4; buf[2] = 0x23; buf[3] = 0x42; console.log(buf.readUInt32BE(0)); console.log(buf.readUInt32LE(0)); // 0x03042342 // 0x42230403 ### buf.readUIntBE(offset, byteLength[, noAssert]) ### buf.readUIntLE(offset, byteLength[, noAssert]) * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} A generalized version of all numeric read methods. Supports up to 48 bits of accuracy. For example: var b = new Buffer(6); b.writeUInt16LE(0x90ab, 0); b.writeUInt32LE(0x12345678, 2); b.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) // output: '1234567890ab' ### buf.slice([start[, end]]) * `start` Number, Optional, Default: 0 * `end` Number, Optional, Default: `buffer.length` Returns a new buffer which references the same memory as the old, but offset and cropped by the `start` (defaults to `0`) and `end` (defaults to `buffer.length`) indexes. Negative indexes start from the end of the buffer. **Modifying the new buffer slice will modify memory in the original buffer!** Example: build a Buffer with the ASCII alphabet, take a slice, then modify one byte from the original Buffer. var buf1 = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf1[i] = i + 97; // 97 is ASCII a } var buf2 = buf1.slice(0, 3); console.log(buf2.toString('ascii', 0, buf2.length)); buf1[0] = 33; console.log(buf2.toString('ascii', 0, buf2.length)); // abc // !bc ### buf.toString([encoding][, start][, end]) * `encoding` String, Optional, Default: 'utf8' * `start` Number, Optional, Default: 0 * `end` Number, Optional, Default: `buffer.length` Decodes and returns a string from buffer data encoded using the specified character set encoding. If `encoding` is `undefined` or `null`, then `encoding` defaults to `'utf8'`. The `start` and `end` parameters default to `0` and `buffer.length` when `undefined`. buf = new Buffer(26); for (var i = 0 ; i < 26 ; i++) { buf[i] = i + 97; // 97 is ASCII a } buf.toString('ascii'); // outputs: abcdefghijklmnopqrstuvwxyz buf.toString('ascii',0,5); // outputs: abcde buf.toString('utf8',0,5); // outputs: abcde buf.toString(undefined,0,5); // encoding defaults to 'utf8', outputs abcde See `buf.write()` example, below. ### buf.toJSON() Returns a JSON representation of the Buffer instance. `JSON.stringify` implicitly calls this function when stringifying a Buffer instance. Example: var buf = new Buffer('test'); var json = JSON.stringify(buf); console.log(json); // '{"type":"Buffer","data":[116,101,115,116]}' var copy = JSON.parse(json, function(key, value) { return value && value.type === 'Buffer' ? new Buffer(value.data) : value; }); console.log(copy); // ### buf.write(string[, offset][, length][, encoding]) * `string` String - data to be written to buffer * `offset` Number, Optional, Default: 0 * `length` Number, Optional, Default: `buffer.length - offset` * `encoding` String, Optional, Default: 'utf8' Writes `string` to the buffer at `offset` using the given encoding. `offset` defaults to `0`, `encoding` defaults to `'utf8'`. `length` is the number of bytes to write. Returns number of octets written. If `buffer` did not contain enough space to fit the entire string, it will write a partial amount of the string. `length` defaults to `buffer.length - offset`. The method will not write partial characters. buf = new Buffer(256); len = buf.write('\u00bd + \u00bc = \u00be', 0); console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); ### buf.writeDoubleBE(value, offset[, noAssert]) ### buf.writeDoubleLE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. `value` must be a valid 64-bit double. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: var buf = new Buffer(8); buf.writeDoubleBE(0xdeadbeefcafebabe, 0); console.log(buf); buf.writeDoubleLE(0xdeadbeefcafebabe, 0); console.log(buf); // // ### buf.writeFloatBE(value, offset[, noAssert]) ### buf.writeFloatLE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. Behavior is unspecified if `value` is not a 32-bit float. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: var buf = new Buffer(4); buf.writeFloatBE(0xcafebabe, 0); console.log(buf); buf.writeFloatLE(0xcafebabe, 0); console.log(buf); // // ### buf.writeInt8(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset. `value` must be a valid signed 8-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt8`, except value is written out as a two's complement signed integer into `buffer`. ### buf.writeInt16BE(value, offset[, noAssert]) ### buf.writeInt16LE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. `value` must be a valid signed 16-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt16*`, except value is written out as a two's complement signed integer into `buffer`. ### buf.writeInt32BE(value, offset[, noAssert]) ### buf.writeInt32LE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. `value` must be a valid signed 32-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt32*`, except value is written out as a two's complement signed integer into `buffer`. ### buf.writeIntBE(value, offset, byteLength[, noAssert]) ### buf.writeIntLE(value, offset, byteLength[, noAssert]) * `value` {Number} Bytes to be written to buffer * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} Writes `value` to the buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: var b = new Buffer(6); b.writeUIntBE(0x1234567890ab, 0, 6); // Set `noAssert` to `true` to skip validation of `value` and `offset`. Defaults to `false`. ### buf.writeUInt8(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset. `value` must be a valid unsigned 8-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: var buf = new Buffer(4); buf.writeUInt8(0x3, 0); buf.writeUInt8(0x4, 1); buf.writeUInt8(0x23, 2); buf.writeUInt8(0x42, 3); console.log(buf); // ### buf.writeUInt16BE(value, offset[, noAssert]) ### buf.writeUInt16LE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. `value` must be a valid unsigned 16-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: var buf = new Buffer(4); buf.writeUInt16BE(0xdead, 0); buf.writeUInt16BE(0xbeef, 2); console.log(buf); buf.writeUInt16LE(0xdead, 0); buf.writeUInt16LE(0xbeef, 2); console.log(buf); // // ### buf.writeUInt32BE(value, offset[, noAssert]) ### buf.writeUInt32LE(value, offset[, noAssert]) * `value` Number * `offset` Number * `noAssert` Boolean, Optional, Default: false Writes `value` to the buffer at the specified offset with specified endian format. `value` must be a valid unsigned 32-bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This should not be used unless you are certain of correctness. Defaults to `false`. Example: var buf = new Buffer(4); buf.writeUInt32BE(0xfeedface, 0); console.log(buf); buf.writeUInt32LE(0xfeedface, 0); console.log(buf); // // ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) ### buf.writeUIntLE(value, offset, byteLength[, noAssert]) * `value` {Number} Bytes to be written to buffer * `offset` {Number} `0 <= offset <= buf.length` * `byteLength` {Number} `0 < byteLength <= 6` * `noAssert` {Boolean} Default: false * Return: {Number} Writes `value` to the buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: var b = new Buffer(6); b.writeUIntBE(0x1234567890ab, 0, 6); // Set `noAssert` to `true` to skip validation of `value` and `offset`. Defaults to `false`. ## buffer.INSPECT_MAX_BYTES * Number, Default: 50 How many bytes will be returned when `buffer.inspect()` is called. This can be overridden by user modules. See [`util.inspect()`][] for more details on `buffer.inspect()` behavior. Note that this is a property on the buffer module returned by `require('buffer')`, not on the Buffer global or a buffer instance. ## ES6 iteration Buffers can be iterated over using `for..of` syntax: var buf = new Buffer([1, 2, 3]); for (var b of buf) console.log(b) // 1 // 2 // 3 Additionally, the `buffer.values()`, `buffer.keys()`, and `buffer.entries()` methods can be used to create iterators. ## Class: SlowBuffer Returns an un-pooled `Buffer`. In order to avoid the garbage collection overhead of creating many individually allocated Buffers, by default allocations under 4KB are sliced from a single larger allocated object. This approach improves both performance and memory usage since v8 does not need to track and cleanup as many `Persistent` objects. In the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using SlowBuffer and copy out the relevant bits. // need to keep around a few small chunks of memory var store = []; socket.on('readable', function() { var data = socket.read(); // allocate for retained data var sb = new SlowBuffer(10); // copy the data into the new allocation data.copy(sb, 0, 0, 10); store.push(sb); }); This should be used only as a last resort *after* a developer has observed undue memory retention in their applications. [`Array#indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf [`buf.fill(0)`]: #buffer_buf_fill_value_offset_end [`buf.slice`]: #buffer_buf_slice_start_end [`buf1.compare(buf2)`]: #buffer_buf_compare_otherbuffer [`Buffer#slice()`]: #buffer_buf_slice_start_end [`RangeError`]: errors.html#errors_class_rangeerror [`String.prototype.length`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length [`util.inspect()`]: util.html#util_util_inspect_object_options node-v4.2.6/doc/api/child_process.html000644 000766 000024 00000145330 12650222331 017775 0ustar00iojsstaff000000 000000 Child Process Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Child Process#

Stability: 2 - Stable

Node.js provides a tri-directional popen(3) facility through the child_process module.

It is possible to stream data through a child's stdin, stdout, and stderr in a fully non-blocking way. (Note that some programs use line-buffered I/O internally. That doesn't affect Node.js but it means data you send to the child process may not be immediately consumed.)

To create a child process, use require('child_process').spawn() or require('child_process').fork(). The semantics of each are slightly different as explained below.

For scripting purposes you may find the synchronous counterparts more convenient.

Class: ChildProcess#

ChildProcess is an EventEmitter.

Child processes always have three streams associated with them. child.stdin, child.stdout, and child.stderr. These may be shared with the stdio streams of the parent process, or they may be separate stream objects which can be piped to and from.

The ChildProcess class is not intended to be used directly. Use the spawn(), exec(), execFile(), or fork() methods to create an instance of ChildProcess.

Event: 'close'#

  • code Number the exit code, if it exited normally.
  • signal String the signal passed to kill the child process, if it was killed by the parent.

This event is emitted when the stdio streams of a child process have all terminated. This is distinct from 'exit', since multiple processes might share the same stdio streams.

Event: 'disconnect'#

This event is emitted after calling the .disconnect() method in the parent or in the child. After disconnecting it is no longer possible to send messages, and the .connected property is false.

Event: 'error'#

  • err Error Object the error.

Emitted when:

  1. The process could not be spawned, or
  2. The process could not be killed, or
  3. Sending a message to the child process failed.

Note that the 'exit' event may or may not fire after an error has occurred. If you are listening on both events to fire a function, remember to guard against calling your function twice.

See also ChildProcess#kill() and ChildProcess#send().

Event: 'exit'#

  • code Number the exit code, if it exited normally.
  • signal String the signal passed to kill the child process, if it was killed by the parent.

This event is emitted after the child process ends. If the process terminated normally, code is the final exit code of the process, otherwise null. If the process terminated due to receipt of a signal, signal is the string name of the signal, otherwise null.

Note that the child process stdio streams might still be open.

Also, note that Node.js establishes signal handlers for SIGINT and SIGTERM. It will not terminate due to receipt of those signals. It will exit.

See waitpid(2).

Event: 'message'#

  • message Object a parsed JSON object or primitive value.
  • sendHandle Handle object a net.Socket or net.Server object, or undefined.

Messages sent by .send(message, [sendHandle]) are obtained using the 'message' event.

child.connected#

  • Boolean Set to false after .disconnect is called

If .connected is false, it is no longer possible to send messages.

child.disconnect()#

Close the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. After calling this method the .connected flag will be set to false in both the parent and child, and it is no longer possible to send messages.

The 'disconnect' event will be emitted when there are no messages in the process of being received, most likely immediately.

Note that you can also call process.disconnect() in the child process when the child process has any open IPC channels with the parent (i.e fork()).

child.kill([signal])#

  • signal String

Send a signal to the child process. If no argument is given, the process will be sent 'SIGTERM'. See signal(7) for a list of available signals.

const spawn = require('child_process').spawn;
const grep = spawn('grep', ['ssh']);

grep.on('close', (code, signal) => {
  console.log(
    `child process terminated due to receipt of signal ${signal}`);
});

// send SIGHUP to process
grep.kill('SIGHUP');

May emit an 'error' event when the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will be delivered to that process instead. What happens next is anyone's guess.

Note that while the function is called kill, the signal delivered to the child process may not actually kill it. kill really just sends a signal to a process.

See kill(2)

child.pid#

  • Integer

The process identifier (PID) of the child process.

Example:

const spawn = require('child_process').spawn;
const grep = spawn('grep', ['ssh']);

console.log(`Spawned child pid: ${grep.pid}`);
grep.stdin.end();

child.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object
  • callback Function
  • Return: Boolean

When using child_process.fork() you can write to the child using child.send(message[, sendHandle][, callback]) and messages are received by a 'message' event on the child.

For example:

const cp = require('child_process');
const n = cp.fork(`${__dirname}/sub.js`);

n.on('message', (m) => {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

And then the child script, 'sub.js' might look like this:

process.on('message', (m) => {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

In the child, the process object will have a send() method, and process will emit objects each time it receives a message on its channel.

There is a special case when sending a {cmd: 'NODE_foo'} message. All messages containing a NODE_ prefix in its cmd property will not be emitted in the 'message' event, since they are internal messages used by Node.js core. Messages containing the prefix are emitted in the 'internalMessage' event. Avoid using this feature; it is subject to change without notice.

The sendHandle option to child.send() is for sending a TCP server or socket object to another process. The child will receive the object as its second argument to the 'message' event.

The callback option is a function that is invoked after the message is sent but before the target may have received it. It is called with a single argument: null on success, or an Error object on failure.

child.send() emits an 'error' event if no callback was given and the message cannot be sent, for example because the child process has already exited.

Returns true under normal circumstances or false when the backlog of unsent messages exceeds a threshold that makes it unwise to send more. Use the callback mechanism to implement flow control.

Example: sending server object#

Here is an example of sending a server:

const child = require('child_process').fork('child.js');

// Open up the server object and send the handle.
const server = require('net').createServer();
server.on('connection', (socket) => {
  socket.end('handled by parent');
});
server.listen(1337, () => {
  child.send('server', server);
});

And the child would then receive the server object as:

process.on('message', (m, server) => {
  if (m === 'server') {
    server.on('connection', (socket) => {
      socket.end('handled by child');
    });
  }
});

Note that the server is now shared between the parent and child, this means that some connections will be handled by the parent and some by the child.

For dgram servers the workflow is exactly the same. Here you listen on a 'message' event instead of 'connection' and use server.bind instead of server.listen. (Currently only supported on UNIX platforms.)

Example: sending socket object#

Here is an example of sending a socket. It will spawn two children and handle connections with the remote address 74.125.127.100 as VIP by sending the socket to a "special" child process. Other sockets will go to a "normal" process.

const normal = require('child_process').fork('child.js', ['normal']);
const special = require('child_process').fork('child.js', ['special']);

// Open up the server and send sockets to child
const server = require('net').createServer();
server.on('connection', (socket) => {

  // if this is a VIP
  if (socket.remoteAddress === '74.125.127.100') {
    special.send('socket', socket);
    return;
  }
  // just the usual...
  normal.send('socket', socket);
});
server.listen(1337);

The child.js could look like this:

process.on('message', (m, socket) => {
  if (m === 'socket') {
    socket.end(`You were handled as a ${process.argv[2]} person`);
  }
});

Note that once a single socket has been sent to a child the parent can no longer keep track of when the socket is destroyed. To indicate this condition the .connections property becomes null. It is also recommended not to use .maxConnections in this condition.

child.stderr#

  • Stream object

A Readable Stream that represents the child process's stderr.

If the child was not spawned with stdio[2] set to 'pipe', then this will not be set.

child.stderr is shorthand for child.stdio[2]. Both properties will refer to the same object, or null.

child.stdin#

  • Stream object

A Writable Stream that represents the child process's stdin. If the child is waiting to read all its input, it will not continue until this stream has been closed via end().

If the child was not spawned with stdio[0] set to 'pipe', then this will not be set.

child.stdin is shorthand for child.stdio[0]. Both properties will refer to the same object, or null.

child.stdio#

  • Array

A sparse array of pipes to the child process, corresponding with positions in the stdio option to spawn() that have been set to 'pipe'. Note that streams 0-2 are also available as ChildProcess.stdin, ChildProcess.stdout, and ChildProcess.stderr, respectively.

In the following example, only the child's fd 1 is setup as a pipe, so only the parent's child.stdio[1] is a stream, all other values in the array are null.

const assert = require('assert');
const fs = require('fs');
const child_process = require('child_process');

const child = child_process.spawn('ls', {
    stdio: [
      0, // use parents stdin for child
      'pipe', // pipe child's stdout to parent
      fs.openSync('err.out', 'w') // direct child's stderr to a file
    ]
});

assert.equal(child.stdio[0], null);
assert.equal(child.stdio[0], child.stdin);

assert(child.stdout);
assert.equal(child.stdio[1], child.stdout);

assert.equal(child.stdio[2], null);
assert.equal(child.stdio[2], child.stderr);

child.stdout#

  • Stream object

A Readable Stream that represents the child process's stdout.

If the child was not spawned with stdio[1] set to 'pipe', then this will not be set.

child.stdout is shorthand for child.stdio[1]. Both properties will refer to the same object, or null.

Asynchronous Process Creation#

These methods follow the common async programming patterns (accepting a callback or returning an EventEmitter).

child_process.exec(command[, options], callback)#

  • command String The command to run, with space-separated arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • encoding String (Default: 'utf8')
    • shell String Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
    • timeout Number (Default: 0)
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200*1024)
    • killSignal String (Default: 'SIGTERM')
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • callback Function called with the output when process terminates
    • error Error
    • stdout Buffer
    • stderr Buffer
  • Return: ChildProcess object

Runs a command in a shell and buffers the output.

const exec = require('child_process').exec;
const child = exec('cat *.js bad_file | wc -l',
  (error, stdout, stderr) => {
    console.log(`stdout: ${stdout}`);
    console.log(`stderr: ${stderr}`);
    if (error !== null) {
      console.log(`exec error: ${error}`);
    }
});

The callback gets the arguments (error, stdout, stderr). On success, error will be null. On error, error will be an instance of Error and error.code will be the exit code of the child process, and error.signal will be set to the signal that terminated the process.

There is a second optional argument to specify several options. The default options are

{ encoding: 'utf8',
  timeout: 0,
  maxBuffer: 200*1024,
  killSignal: 'SIGTERM',
  cwd: null,
  env: null }

If timeout is greater than 0, then it will kill the child process if it runs longer than timeout milliseconds. The child process is killed with killSignal (default: 'SIGTERM'). maxBuffer specifies the largest amount of data (in bytes) allowed on stdout or stderr - if this value is exceeded then the child process is killed.

Note: Unlike the exec() POSIX system call, child_process.exec() does not replace the existing process and uses a shell to execute the command.

child_process.execFile(file[, args][, options][, callback])#

  • file String The filename of the program to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • encoding String (Default: 'utf8')
    • timeout Number (Default: 0)
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200*1024)
    • killSignal String (Default: 'SIGTERM')
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • callback Function called with the output when process terminates
    • error Error
    • stdout Buffer
    • stderr Buffer
  • Return: ChildProcess object

This is similar to child_process.exec() except it does not execute a subshell but rather the specified file directly. This makes it slightly leaner than child_process.exec(). It has the same options.

child_process.fork(modulePath[, args][, options])#

  • modulePath String The module to run in the child
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • execPath String Executable used to create the child process
    • execArgv Array List of string arguments passed to the executable (Default: process.execArgv)
    • silent Boolean If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the 'pipe' and 'inherit' options for spawn()'s stdio for more details (default is false)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • Return: ChildProcess object

This is a special case of the child_process.spawn() functionality for spawning Node.js processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. See ChildProcess#send() for details.

These child Node.js processes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node.js. That is, you cannot create many thousands of them.

The execPath property in the options object allows for a process to be created for the child rather than the current node executable. This should be done with care and by default will talk over the fd represented an environmental variable NODE_CHANNEL_FD on the child process. The input and output on this fd is expected to be line delimited JSON objects.

Note: Unlike the fork() POSIX system call, child_process.fork() does not clone the current process.

child_process.spawn(command[, args][, options])#

  • command String The command to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • env Object Environment key-value pairs
    • stdio Array|String Child's stdio configuration. (See below)
    • detached Boolean Prepare child to run independently of its parent process. Specific behavior depends on the platform, see below)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
  • return: ChildProcess object

Launches a new process with the given command, with command line arguments in args. If omitted, args defaults to an empty Array.

The third argument is used to specify additional options, with these defaults:

{ cwd: undefined,
  env: process.env
}

Use cwd to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory.

Use env to specify environment variables that will be visible to the new process, the default is process.env.

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:

const spawn = require('child_process').spawn;
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

Example: A very elaborate way to run 'ps ax | grep ssh'

const spawn = require('child_process').spawn;
const ps = spawn('ps', ['ax']);
const grep = spawn('grep', ['ssh']);

ps.stdout.on('data', (data) => {
  grep.stdin.write(data);
});

ps.stderr.on('data', (data) => {
  console.log(`ps stderr: ${data}`);
});

ps.on('close', (code) => {
  if (code !== 0) {
    console.log(`ps process exited with code ${code}`);
  }
  grep.stdin.end();
});

grep.stdout.on('data', (data) => {
  console.log(`${data}`);
});

grep.stderr.on('data', (data) => {
  console.log(`grep stderr: ${data}`);
});

grep.on('close', (code) => {
  if (code !== 0) {
    console.log(`grep process exited with code ${code}`);
  }
});

Example of checking for failed exec:

const spawn = require('child_process').spawn;
const child = spawn('bad_command');

child.on('error', (err) => {
  console.log('Failed to start child process.');
});

options.detached#

On Windows, this makes it possible for the child to continue running after the parent exits. The child will have a new console window (this cannot be disabled).

On non-Windows, if the detached option is set, the child process will be made the leader of a new process group and session. Note that child processes may continue running after the parent exits whether they are detached or not. See setsid(2) for more information.

By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given child, use the child.unref() method, and the parent's event loop will not include the child in its reference count.

Example of detaching a long-running process and redirecting its output to a file:

 const fs = require('fs');
 const spawn = require('child_process').spawn;
 const out = fs.openSync('./out.log', 'a');
 const err = fs.openSync('./out.log', 'a');

 const child = spawn('prg', [], {
   detached: true,
   stdio: [ 'ignore', out, err ]
 });

 child.unref();

When using the detached option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a stdio configuration that is not connected to the parent. If the parent's stdio is inherited, the child will remain attached to the controlling terminal.

options.stdio#

As a shorthand, the stdio argument may be one of the following strings:

  • 'pipe' - ['pipe', 'pipe', 'pipe'], this is the default value
  • 'ignore' - ['ignore', 'ignore', 'ignore']
  • 'inherit' - [process.stdin, process.stdout, process.stderr] or [0,1,2]

Otherwise, the 'stdio' option to child_process.spawn() is an array where each index corresponds to a fd in the child. The value is one of the following:

  1. 'pipe' - Create a pipe between the child process and the parent process. The parent end of the pipe is exposed to the parent as a property on the child_process object as ChildProcess.stdio[fd]. Pipes created for fds 0 - 2 are also available as ChildProcess.stdin, ChildProcess.stdout and ChildProcess.stderr, respectively.
  2. 'ipc' - Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most one IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is an Node.js program, then the presence of an IPC channel will enable process.send() and process.on('message').
  3. 'ignore' - Do not set this file descriptor in the child. Note that Node.js will always open fd 0 - 2 for the processes it spawns. When any of these is ignored Node.js will open /dev/null and attach it to the child's fd.
  4. Stream object - Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream's underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the stdio array. Note that the stream must have an underlying descriptor (file streams do not until the 'open' event has occurred).
  5. Positive integer - The integer value is interpreted as a file descriptor that is is currently open in the parent process. It is shared with the child process, similar to how Stream objects can be shared.
  6. null, undefined - Use default value. For stdio fds 0, 1 and 2 (in other words, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the default is 'ignore'.

Example:

const spawn = require('child_process').spawn;

// Child will use parent's stdios
spawn('prg', [], { stdio: 'inherit' });

// Spawn child sharing only stderr
spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });

// Open an extra fd=4, to interact with programs present a
// startd-style interface.
spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });

See also: child_process.exec() and child_process.fork()

Synchronous Process Creation#

These methods are synchronous, meaning they WILL block the event loop, pausing execution of your code until the spawned process exits.

Blocking calls like these are mostly useful for simplifying general purpose scripting tasks and for simplifying the loading/processing of application configuration at startup.

child_process.execFileSync(file[, args][, options])#

  • file String The filename of the program to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration. (Default: 'pipe')
      • stderr by default will be output to the parent process' stderr unless stdio is specified
    • env Object Environment key-value pairs
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execFileSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync()

child_process.execSync(command[, options])#

  • command String The command to run
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration. (Default: 'pipe')
      • stderr by default will be output to the parent process' stderr unless stdio is specified
    • env Object Environment key-value pairs
    • shell String Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the -c switch on UNIX or /s /c on Windows. On Windows, command line parsing should be compatible with cmd.exe.)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync()

child_process.spawnSync(command[, args][, options])#

  • command String The command to run
  • args Array List of string arguments
  • options Object
    • cwd String Current working directory of the child process
    • input String|Buffer The value which will be passed as stdin to the spawned process
      • supplying this value will override stdio[0]
    • stdio Array Child's stdio configuration.
    • env Object Environment key-value pairs
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)
    • timeout Number In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignal String The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBuffer Number largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed
    • encoding String The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Object
    • pid Number Pid of the child process
    • output Array Array of results from stdio output
    • stdout Buffer|String The contents of output[1]
    • stderr Buffer|String The contents of output[2]
    • status Number The exit code of the child process
    • signal String The signal used to kill the child process
    • error Error The error object if the child process failed or timed out

spawnSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won't return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn't exit, your process will wait until the child process has exited.

node-v4.2.6/doc/api/child_process.json000644 000766 000024 00000215164 12650222331 020005 0ustar00iojsstaff000000 000000 { "source": "doc/api/child_process.markdown", "modules": [ { "textRaw": "Child Process", "name": "child_process", "stability": 2, "stabilityText": "Stable", "desc": "

Node.js provides a tri-directional popen(3) facility through the\nchild_process module.\n\n

\n

It is possible to stream data through a child's stdin, stdout, and\nstderr in a fully non-blocking way. (Note that some programs use\nline-buffered I/O internally. That doesn't affect Node.js but it means\ndata you send to the child process may not be immediately consumed.)\n\n

\n

To create a child process, use require('child_process').spawn() or\nrequire('child_process').fork(). The semantics of each are slightly\ndifferent as explained [below][].\n\n

\n

For scripting purposes you may find the [synchronous counterparts][] more\nconvenient.\n\n

\n", "classes": [ { "textRaw": "Class: ChildProcess", "type": "class", "name": "ChildProcess", "desc": "

ChildProcess is an [EventEmitter][].\n\n

\n

Child processes always have three streams associated with them. child.stdin,\nchild.stdout, and child.stderr. These may be shared with the stdio\nstreams of the parent process, or they may be separate stream objects\nwhich can be piped to and from.\n\n

\n

The ChildProcess class is not intended to be used directly. Use the\n[spawn()][], [exec()][], [execFile()][], or [fork()][] methods to create\nan instance of ChildProcess.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "params": [], "desc": "

This event is emitted when the stdio streams of a child process have all\nterminated. This is distinct from 'exit', since multiple processes\nmight share the same stdio streams.\n\n

\n" }, { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "desc": "

This event is emitted after calling the .disconnect() method in the parent\nor in the child. After disconnecting it is no longer possible to send messages,\nand the .connected property is false.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when:\n\n

\n
    \n
  1. The process could not be spawned, or
  2. \n
  3. The process could not be killed, or
  4. \n
  5. Sending a message to the child process failed.
  6. \n
\n

Note that the 'exit' event may or may not fire after an error has occurred.\nIf you are listening on both events to fire a function, remember to guard\nagainst calling your function twice.\n\n

\n

See also [ChildProcess#kill()][] and [ChildProcess#send()][].\n\n

\n" }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

This event is emitted after the child process ends. If the process terminated\nnormally, code is the final exit code of the process, otherwise null. If\nthe process terminated due to receipt of a signal, signal is the string name\nof the signal, otherwise null.\n\n

\n

Note that the child process stdio streams might still be open.\n\n

\n

Also, note that Node.js establishes signal handlers for SIGINT and\nSIGTERM. It will not terminate due to receipt of those signals. It will exit.\n\n

\n

See waitpid(2).\n\n

\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Messages sent by .send(message, [sendHandle]) are obtained using the\n'message' event.\n\n

\n" } ], "properties": [ { "textRaw": "`connected` {Boolean} Set to false after `.disconnect` is called ", "name": "connected", "desc": "

If .connected is false, it is no longer possible to send messages.\n\n

\n", "shortDesc": "Set to false after `.disconnect` is called" }, { "textRaw": "`pid` {Integer} ", "name": "pid", "desc": "

The process identifier (PID) of the child process.\n\n

\n

Example:\n\n

\n
const spawn = require('child_process').spawn;\nconst grep = spawn('grep', ['ssh']);\n\nconsole.log(`Spawned child pid: ${grep.pid}`);\ngrep.stdin.end();
\n" }, { "textRaw": "`stderr` {Stream object} ", "name": "stderr", "desc": "

A Readable Stream that represents the child process's stderr.\n\n

\n

If the child was not spawned with stdio[2] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stderr is shorthand for child.stdio[2]. Both properties will refer\nto the same object, or null.\n\n

\n" }, { "textRaw": "`stdin` {Stream object} ", "name": "stdin", "desc": "

A Writable Stream that represents the child process's stdin.\nIf the child is waiting to read all its input, it will not continue until this\nstream has been closed via end().\n\n

\n

If the child was not spawned with stdio[0] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stdin is shorthand for child.stdio[0]. Both properties will refer\nto the same object, or null.\n\n

\n" }, { "textRaw": "`stdio` {Array} ", "name": "stdio", "desc": "

A sparse array of pipes to the child process, corresponding with positions in\nthe [stdio][] option to [spawn()][] that have been set to 'pipe'.\nNote that streams 0-2 are also available as ChildProcess.stdin,\nChildProcess.stdout, and ChildProcess.stderr, respectively.\n\n

\n

In the following example, only the child's fd 1 is setup as a pipe, so only\nthe parent's child.stdio[1] is a stream, all other values in the array are\nnull.\n\n

\n
const assert = require('assert');\nconst fs = require('fs');\nconst child_process = require('child_process');\n\nconst child = child_process.spawn('ls', {\n    stdio: [\n      0, // use parents stdin for child\n      'pipe', // pipe child's stdout to parent\n      fs.openSync('err.out', 'w') // direct child's stderr to a file\n    ]\n});\n\nassert.equal(child.stdio[0], null);\nassert.equal(child.stdio[0], child.stdin);\n\nassert(child.stdout);\nassert.equal(child.stdio[1], child.stdout);\n\nassert.equal(child.stdio[2], null);\nassert.equal(child.stdio[2], child.stderr);
\n" }, { "textRaw": "`stdout` {Stream object} ", "name": "stdout", "desc": "

A Readable Stream that represents the child process's stdout.\n\n

\n

If the child was not spawned with stdio[1] set to 'pipe', then this will\nnot be set.\n\n

\n

child.stdout is shorthand for child.stdio[1]. Both properties will refer\nto the same object, or null.\n\n

\n" } ], "methods": [ { "textRaw": "child.disconnect()", "type": "method", "name": "disconnect", "desc": "

Close the IPC channel between parent and child, allowing the child to exit\ngracefully once there are no other connections keeping it alive. After calling\nthis method the .connected flag will be set to false in both the parent and\nchild, and it is no longer possible to send messages.\n\n

\n

The 'disconnect' event will be emitted when there are no messages in the\nprocess of being received, most likely immediately.\n\n

\n

Note that you can also call process.disconnect() in the child process when the\nchild process has any open IPC channels with the parent (i.e [fork()][]).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "child.kill([signal])", "type": "method", "name": "kill", "signatures": [ { "params": [ { "textRaw": "`signal` {String} ", "name": "signal", "type": "String", "optional": true } ] }, { "params": [ { "name": "signal", "optional": true } ] } ], "desc": "

Send a signal to the child process. If no argument is given, the process will\nbe sent 'SIGTERM'. See signal(7) for a list of available signals.\n\n

\n
const spawn = require('child_process').spawn;\nconst grep = spawn('grep', ['ssh']);\n\ngrep.on('close', (code, signal) => {\n  console.log(\n    `child process terminated due to receipt of signal ${signal}`);\n});\n\n// send SIGHUP to process\ngrep.kill('SIGHUP');
\n

May emit an 'error' event when the signal cannot be delivered. Sending a\nsignal to a child process that has already exited is not an error but may\nhave unforeseen consequences. Specifically, if the process identifier (PID) has\nbeen reassigned to another process, the signal will be delivered to that\nprocess instead. What happens next is anyone's guess.\n\n

\n

Note that while the function is called kill, the signal delivered to the\nchild process may not actually kill it. kill really just sends a signal\nto a process.\n\n

\n

See kill(2)\n\n

\n" }, { "textRaw": "child.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

When using [child_process.fork()][] you can write to the child using\nchild.send(message[, sendHandle][, callback]) and messages are received by\na 'message' event on the child.\n\n

\n

For example:\n\n

\n
const cp = require('child_process');\nconst n = cp.fork(`${__dirname}/sub.js`);\n\nn.on('message', (m) => {\n  console.log('PARENT got message:', m);\n});\n\nn.send({ hello: 'world' });
\n

And then the child script, 'sub.js' might look like this:\n\n

\n
process.on('message', (m) => {\n  console.log('CHILD got message:', m);\n});\n\nprocess.send({ foo: 'bar' });
\n

In the child, the process object will have a send() method, and process\nwill emit objects each time it receives a message on its channel.\n\n

\n

There is a special case when sending a {cmd: 'NODE_foo'} message. All messages\ncontaining a NODE_ prefix in its cmd property will not be emitted in\nthe 'message' event, since they are internal messages used by Node.js core.\nMessages containing the prefix are emitted in the 'internalMessage' event.\nAvoid using this feature; it is subject to change without notice.\n\n

\n

The sendHandle option to child.send() is for sending a TCP server or\nsocket object to another process. The child will receive the object as its\nsecond argument to the 'message' event.\n\n

\n

The callback option is a function that is invoked after the message is\nsent but before the target may have received it. It is called with a single\nargument: null on success, or an [Error][] object on failure.\n\n

\n

child.send() emits an 'error' event if no callback was given and the message\ncannot be sent, for example because the child process has already exited.\n\n

\n

Returns true under normal circumstances or false when the backlog of\nunsent messages exceeds a threshold that makes it unwise to send more.\nUse the callback mechanism to implement flow control.\n\n

\n

Example: sending server object

\n

Here is an example of sending a server:\n\n

\n
const child = require('child_process').fork('child.js');\n\n// Open up the server object and send the handle.\nconst server = require('net').createServer();\nserver.on('connection', (socket) => {\n  socket.end('handled by parent');\n});\nserver.listen(1337, () => {\n  child.send('server', server);\n});
\n

And the child would then receive the server object as:\n\n

\n
process.on('message', (m, server) => {\n  if (m === 'server') {\n    server.on('connection', (socket) => {\n      socket.end('handled by child');\n    });\n  }\n});
\n

Note that the server is now shared between the parent and child, this means\nthat some connections will be handled by the parent and some by the child.\n\n

\n

For dgram servers the workflow is exactly the same. Here you listen on\na 'message' event instead of 'connection' and use server.bind instead of\nserver.listen. (Currently only supported on UNIX platforms.)\n\n

\n

Example: sending socket object

\n

Here is an example of sending a socket. It will spawn two children and handle\nconnections with the remote address 74.125.127.100 as VIP by sending the\nsocket to a "special" child process. Other sockets will go to a "normal"\nprocess.\n\n

\n
const normal = require('child_process').fork('child.js', ['normal']);\nconst special = require('child_process').fork('child.js', ['special']);\n\n// Open up the server and send sockets to child\nconst server = require('net').createServer();\nserver.on('connection', (socket) => {\n\n  // if this is a VIP\n  if (socket.remoteAddress === '74.125.127.100') {\n    special.send('socket', socket);\n    return;\n  }\n  // just the usual...\n  normal.send('socket', socket);\n});\nserver.listen(1337);
\n

The child.js could look like this:\n\n

\n
process.on('message', (m, socket) => {\n  if (m === 'socket') {\n    socket.end(`You were handled as a ${process.argv[2]} person`);\n  }\n});
\n

Note that once a single socket has been sent to a child the parent can no\nlonger keep track of when the socket is destroyed. To indicate this condition\nthe .connections property becomes null.\nIt is also recommended not to use .maxConnections in this condition.\n\n

\n" } ] } ], "modules": [ { "textRaw": "Asynchronous Process Creation", "name": "asynchronous_process_creation", "desc": "

These methods follow the common async programming patterns (accepting a\ncallback or returning an EventEmitter).\n\n

\n", "methods": [ { "textRaw": "child_process.exec(command[, options], callback)", "type": "method", "name": "exec", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`command` {String} The command to run, with space-separated arguments ", "name": "command", "type": "String", "desc": "The command to run, with space-separated arguments" }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`encoding` {String} (Default: 'utf8') ", "name": "encoding", "default": "utf8", "type": "String" }, { "textRaw": "`shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) ", "name": "shell", "type": "String", "desc": "Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.)" }, { "textRaw": "`timeout` {Number} (Default: 0) ", "name": "timeout", "default": "0", "type": "Number" }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: `200*1024`) ", "name": "maxBuffer", "default": "200*1024", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`killSignal` {String} (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true }, { "textRaw": "`callback` {Function} called with the output when process terminates ", "options": [ { "textRaw": "`error` {Error} ", "name": "error", "type": "Error" }, { "textRaw": "`stdout` {Buffer} ", "name": "stdout", "type": "Buffer" }, { "textRaw": "`stderr` {Buffer} ", "name": "stderr", "type": "Buffer" } ], "name": "callback", "type": "Function", "desc": "called with the output when process terminates" } ] }, { "params": [ { "name": "command" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Runs a command in a shell and buffers the output.\n\n

\n
const exec = require('child_process').exec;\nconst child = exec('cat *.js bad_file | wc -l',\n  (error, stdout, stderr) => {\n    console.log(`stdout: ${stdout}`);\n    console.log(`stderr: ${stderr}`);\n    if (error !== null) {\n      console.log(`exec error: ${error}`);\n    }\n});
\n

The callback gets the arguments (error, stdout, stderr). On success, error\nwill be null. On error, error will be an instance of [Error][] and error.code\nwill be the exit code of the child process, and error.signal will be set to the\nsignal that terminated the process.\n\n

\n

There is a second optional argument to specify several options. The\ndefault options are\n\n

\n
{ encoding: 'utf8',\n  timeout: 0,\n  maxBuffer: 200*1024,\n  killSignal: 'SIGTERM',\n  cwd: null,\n  env: null }
\n

If timeout is greater than 0, then it will kill the child process\nif it runs longer than timeout milliseconds. The child process is killed with\nkillSignal (default: 'SIGTERM'). maxBuffer specifies the largest\namount of data (in bytes) allowed on stdout or stderr - if this value is\nexceeded then the child process is killed.\n\n

\n

Note: Unlike the exec() POSIX system call, child_process.exec() does not replace\nthe existing process and uses a shell to execute the command.\n\n

\n" }, { "textRaw": "child_process.execFile(file[, args][, options][, callback])", "type": "method", "name": "execFile", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`file` {String} The filename of the program to run ", "name": "file", "type": "String", "desc": "The filename of the program to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`encoding` {String} (Default: 'utf8') ", "name": "encoding", "default": "utf8", "type": "String" }, { "textRaw": "`timeout` {Number} (Default: 0) ", "name": "timeout", "default": "0", "type": "Number" }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200\\*1024) ", "name": "maxBuffer", "default": "200\\*1024", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`killSignal` {String} (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true }, { "textRaw": "`callback` {Function} called with the output when process terminates ", "options": [ { "textRaw": "`error` {Error} ", "name": "error", "type": "Error" }, { "textRaw": "`stdout` {Buffer} ", "name": "stdout", "type": "Buffer" }, { "textRaw": "`stderr` {Buffer} ", "name": "stderr", "type": "Buffer" } ], "name": "callback", "type": "Function", "desc": "called with the output when process terminates", "optional": true } ] }, { "params": [ { "name": "file" }, { "name": "args", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This is similar to [child_process.exec()][] except it does not execute a\nsubshell but rather the specified file directly. This makes it slightly\nleaner than [child_process.exec()][]. It has the same options.\n\n\n

\n" }, { "textRaw": "child_process.fork(modulePath[, args][, options])", "type": "method", "name": "fork", "signatures": [ { "return": { "textRaw": "Return: ChildProcess object ", "name": "return", "desc": "ChildProcess object" }, "params": [ { "textRaw": "`modulePath` {String} The module to run in the child ", "name": "modulePath", "type": "String", "desc": "The module to run in the child" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`execPath` {String} Executable used to create the child process ", "name": "execPath", "type": "String", "desc": "Executable used to create the child process" }, { "textRaw": "`execArgv` {Array} List of string arguments passed to the executable (Default: `process.execArgv`) ", "name": "execArgv", "default": "process.execArgv", "type": "Array", "desc": "List of string arguments passed to the executable" }, { "textRaw": "`silent` {Boolean} If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`spawn()`][]'s [`stdio`][] for more details (default is false) ", "name": "silent", "type": "Boolean", "desc": "If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`spawn()`][]'s [`stdio`][] for more details (default is false)" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "modulePath" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

This is a special case of the [child_process.spawn()][] functionality for\nspawning Node.js processes. In addition to having all the methods in a normal\nChildProcess instance, the returned object has a communication channel built-in.\nSee [ChildProcess#send()][] for details.\n\n

\n

These child Node.js processes are still whole new instances of V8. Assume at\nleast 30ms startup and 10mb memory for each new Node.js. That is, you cannot\ncreate many thousands of them.\n\n

\n

The execPath property in the options object allows for a process to be\ncreated for the child rather than the current node executable. This should be\ndone with care and by default will talk over the fd represented an\nenvironmental variable NODE_CHANNEL_FD on the child process. The input and\noutput on this fd is expected to be line delimited JSON objects.\n\n

\n

Note: Unlike the fork() POSIX system call, [child_process.fork()][] does not clone the\ncurrent process.\n\n

\n" }, { "textRaw": "child_process.spawn(command[, args][, options])", "type": "method", "name": "spawn", "signatures": [ { "return": { "textRaw": "return: {ChildProcess object} ", "name": "return", "type": "ChildProcess object" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`stdio` {Array|String} Child's stdio configuration. (See [below](#child_process_options_stdio)) ", "name": "stdio", "type": "Array|String", "desc": "Child's stdio configuration. (See [below](#child_process_options_stdio))" }, { "textRaw": "`detached` {Boolean} Prepare child to run independently of its parent process. Specific behavior depends on the platform, see [below](#child_process_options_detached)) ", "name": "detached", "type": "Boolean", "desc": "Prepare child to run independently of its parent process. Specific behavior depends on the platform, see [below](#child_process_options_detached))" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

Launches a new process with the given command, with command line arguments in\nargs. If omitted, args defaults to an empty Array.\n\n

\n

The third argument is used to specify additional options, with these defaults:\n\n

\n
{ cwd: undefined,\n  env: process.env\n}
\n

Use cwd to specify the working directory from which the process is spawned.\nIf not given, the default is to inherit the current working directory.\n\n

\n

Use env to specify environment variables that will be visible to the new\nprocess, the default is process.env.\n\n

\n

Example of running ls -lh /usr, capturing stdout, stderr, and the exit code:\n\n

\n
const spawn = require('child_process').spawn;\nconst ls = spawn('ls', ['-lh', '/usr']);\n\nls.stdout.on('data', (data) => {\n  console.log(`stdout: ${data}`);\n});\n\nls.stderr.on('data', (data) => {\n  console.log(`stderr: ${data}`);\n});\n\nls.on('close', (code) => {\n  console.log(`child process exited with code ${code}`);\n});
\n

Example: A very elaborate way to run 'ps ax | grep ssh'\n\n

\n
const spawn = require('child_process').spawn;\nconst ps = spawn('ps', ['ax']);\nconst grep = spawn('grep', ['ssh']);\n\nps.stdout.on('data', (data) => {\n  grep.stdin.write(data);\n});\n\nps.stderr.on('data', (data) => {\n  console.log(`ps stderr: ${data}`);\n});\n\nps.on('close', (code) => {\n  if (code !== 0) {\n    console.log(`ps process exited with code ${code}`);\n  }\n  grep.stdin.end();\n});\n\ngrep.stdout.on('data', (data) => {\n  console.log(`${data}`);\n});\n\ngrep.stderr.on('data', (data) => {\n  console.log(`grep stderr: ${data}`);\n});\n\ngrep.on('close', (code) => {\n  if (code !== 0) {\n    console.log(`grep process exited with code ${code}`);\n  }\n});
\n

Example of checking for failed exec:\n\n

\n
const spawn = require('child_process').spawn;\nconst child = spawn('bad_command');\n\nchild.on('error', (err) => {\n  console.log('Failed to start child process.');\n});
\n", "properties": [ { "textRaw": "options.detached", "name": "detached", "desc": "

On Windows, this makes it possible for the child to continue running after the\nparent exits. The child will have a new console window (this cannot be\ndisabled).\n\n

\n

On non-Windows, if the detached option is set, the child process will be made\nthe leader of a new process group and session. Note that child processes may\ncontinue running after the parent exits whether they are detached or not. See\nsetsid(2) for more information.\n\n

\n

By default, the parent will wait for the detached child to exit. To prevent\nthe parent from waiting for a given child, use the child.unref() method,\nand the parent's event loop will not include the child in its reference count.\n\n

\n

Example of detaching a long-running process and redirecting its output to a\nfile:\n\n

\n
 const fs = require('fs');\n const spawn = require('child_process').spawn;\n const out = fs.openSync('./out.log', 'a');\n const err = fs.openSync('./out.log', 'a');\n\n const child = spawn('prg', [], {\n   detached: true,\n   stdio: [ 'ignore', out, err ]\n });\n\n child.unref();
\n

When using the detached option to start a long-running process, the process\nwill not stay running in the background after the parent exits unless it is\nprovided with a stdio configuration that is not connected to the parent.\nIf the parent's stdio is inherited, the child will remain attached to the\ncontrolling terminal.\n\n

\n" }, { "textRaw": "options.stdio", "name": "stdio", "desc": "

As a shorthand, the stdio argument may be one of the following strings:\n\n

\n
    \n
  • 'pipe' - ['pipe', 'pipe', 'pipe'], this is the default value
  • \n
  • 'ignore' - ['ignore', 'ignore', 'ignore']
  • \n
  • 'inherit' - [process.stdin, process.stdout, process.stderr] or [0,1,2]
  • \n
\n

Otherwise, the 'stdio' option to [child_process.spawn()][] is an array where each\nindex corresponds to a fd in the child. The value is one of the following:\n\n

\n
    \n
  1. 'pipe' - Create a pipe between the child process and the parent process.\nThe parent end of the pipe is exposed to the parent as a property on the\nchild_process object as ChildProcess.stdio[fd]. Pipes created for\nfds 0 - 2 are also available as ChildProcess.stdin, ChildProcess.stdout\nand ChildProcess.stderr, respectively.
  2. \n
  3. 'ipc' - Create an IPC channel for passing messages/file descriptors\nbetween parent and child. A ChildProcess may have at most one IPC stdio\nfile descriptor. Setting this option enables the ChildProcess.send() method.\nIf the child writes JSON messages to this file descriptor, then this will\ntrigger ChildProcess.on('message'). If the child is an Node.js program, then\nthe presence of an IPC channel will enable process.send() and\nprocess.on('message').
  4. \n
  5. 'ignore' - Do not set this file descriptor in the child. Note that Node.js\nwill always open fd 0 - 2 for the processes it spawns. When any of these is\nignored Node.js will open /dev/null and attach it to the child's fd.
  6. \n
  7. Stream object - Share a readable or writable stream that refers to a tty,\nfile, socket, or a pipe with the child process. The stream's underlying\nfile descriptor is duplicated in the child process to the fd that\ncorresponds to the index in the stdio array. Note that the stream must\nhave an underlying descriptor (file streams do not until the 'open'\nevent has occurred).
  8. \n
  9. Positive integer - The integer value is interpreted as a file descriptor\nthat is is currently open in the parent process. It is shared with the child\nprocess, similar to how Stream objects can be shared.
  10. \n
  11. null, undefined - Use default value. For stdio fds 0, 1 and 2 (in other\nwords, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the\ndefault is 'ignore'.
  12. \n
\n

Example:\n\n

\n
const spawn = require('child_process').spawn;\n\n// Child will use parent's stdios\nspawn('prg', [], { stdio: 'inherit' });\n\n// Spawn child sharing only stderr\nspawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] });\n\n// Open an extra fd=4, to interact with programs present a\n// startd-style interface.\nspawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] });
\n

See also: [child_process.exec()][] and [child_process.fork()][]\n\n

\n" } ] } ], "type": "module", "displayName": "Asynchronous Process Creation" }, { "textRaw": "Synchronous Process Creation", "name": "synchronous_process_creation", "desc": "

These methods are synchronous, meaning they WILL block the event loop,\npausing execution of your code until the spawned process exits.\n\n

\n

Blocking calls like these are mostly useful for simplifying general purpose\nscripting tasks and for simplifying the loading/processing of application\nconfiguration at startup.\n\n

\n", "methods": [ { "textRaw": "child_process.execFileSync(file[, args][, options])", "type": "method", "name": "execFileSync", "signatures": [ { "return": { "textRaw": "return: {Buffer|String} The stdout from the command ", "name": "return", "type": "Buffer|String", "desc": "The stdout from the command" }, "params": [ { "textRaw": "`file` {String} The filename of the program to run ", "name": "file", "type": "String", "desc": "The filename of the program to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. (Default: 'pipe') ", "options": [ { "textRaw": "`stderr` by default will be output to the parent process' stderr unless `stdio` is specified ", "name": "stderr", "desc": "by default will be output to the parent process' stderr unless `stdio` is specified" } ], "name": "stdio", "default": "pipe", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "file" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

execFileSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n

If the process times out, or has a non-zero exit code, this method will\nthrow. The [Error][] object will contain the entire result from\n[child_process.spawnSync()][]\n\n

\n" }, { "textRaw": "child_process.execSync(command[, options])", "type": "method", "name": "execSync", "signatures": [ { "return": { "textRaw": "return: {Buffer|String} The stdout from the command ", "name": "return", "type": "Buffer|String", "desc": "The stdout from the command" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. (Default: 'pipe') ", "options": [ { "textRaw": "`stderr` by default will be output to the parent process' stderr unless `stdio` is specified ", "name": "stderr", "desc": "by default will be output to the parent process' stderr unless `stdio` is specified" } ], "name": "stdio", "default": "pipe", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) ", "name": "shell", "type": "String", "desc": "Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.)" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "options", "optional": true } ] } ], "desc": "

execSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n

If the process times out, or has a non-zero exit code, this method will\nthrow. The [Error][] object will contain the entire result from\n[child_process.spawnSync()][]\n\n

\n" }, { "textRaw": "child_process.spawnSync(command[, args][, options])", "type": "method", "name": "spawnSync", "signatures": [ { "return": { "textRaw": "return: {Object} ", "options": [ { "textRaw": "`pid` {Number} Pid of the child process ", "name": "pid", "type": "Number", "desc": "Pid of the child process" }, { "textRaw": "`output` {Array} Array of results from stdio output ", "name": "output", "type": "Array", "desc": "Array of results from stdio output" }, { "textRaw": "`stdout` {Buffer|String} The contents of `output[1]` ", "name": "stdout", "type": "Buffer|String", "desc": "The contents of `output[1]`" }, { "textRaw": "`stderr` {Buffer|String} The contents of `output[2]` ", "name": "stderr", "type": "Buffer|String", "desc": "The contents of `output[2]`" }, { "textRaw": "`status` {Number} The exit code of the child process ", "name": "status", "type": "Number", "desc": "The exit code of the child process" }, { "textRaw": "`signal` {String} The signal used to kill the child process ", "name": "signal", "type": "String", "desc": "The signal used to kill the child process" }, { "textRaw": "`error` {Error} The error object if the child process failed or timed out ", "name": "error", "type": "Error", "desc": "The error object if the child process failed or timed out" } ], "name": "return", "type": "Object" }, "params": [ { "textRaw": "`command` {String} The command to run ", "name": "command", "type": "String", "desc": "The command to run" }, { "textRaw": "`args` {Array} List of string arguments ", "name": "args", "type": "Array", "desc": "List of string arguments", "optional": true }, { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`cwd` {String} Current working directory of the child process ", "name": "cwd", "type": "String", "desc": "Current working directory of the child process" }, { "textRaw": "`input` {String|Buffer} The value which will be passed as stdin to the spawned process ", "options": [ { "textRaw": "supplying this value will override `stdio[0]` ", "name": "supplying", "desc": "this value will override `stdio[0]`" } ], "name": "input", "type": "String|Buffer", "desc": "The value which will be passed as stdin to the spawned process" }, { "textRaw": "`stdio` {Array} Child's stdio configuration. ", "name": "stdio", "type": "Array", "desc": "Child's stdio configuration." }, { "textRaw": "`env` {Object} Environment key-value pairs ", "name": "env", "type": "Object", "desc": "Environment key-value pairs" }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" }, { "textRaw": "`timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) ", "name": "timeout", "default": "undefined", "type": "Number", "desc": "In milliseconds the maximum amount of time the process is allowed to run." }, { "textRaw": "`killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') ", "name": "killSignal", "default": "SIGTERM", "type": "String", "desc": "The signal value to be used when the spawned process will be killed." }, { "textRaw": "`maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed ", "name": "maxBuffer", "type": "Number", "desc": "largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed" }, { "textRaw": "`encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') ", "name": "encoding", "default": "buffer", "type": "String", "desc": "The encoding used for all stdio inputs and outputs." } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "command" }, { "name": "args", "optional": true }, { "name": "options", "optional": true } ] } ], "desc": "

spawnSync will not return until the child process has fully closed. When a\ntimeout has been encountered and killSignal is sent, the method won't return\nuntil the process has completely exited. That is to say, if the process handles\nthe SIGTERM signal and doesn't exit, your process will wait until the child\nprocess has exited.\n\n

\n" } ], "type": "module", "displayName": "Synchronous Process Creation" } ], "type": "module", "displayName": "Child Process" } ] } node-v4.2.6/doc/api/child_process.markdown000644 000766 000024 00000075007 12650222326 020662 0ustar00iojsstaff000000 000000 # Child Process Stability: 2 - Stable Node.js provides a tri-directional `popen(3)` facility through the `child_process` module. It is possible to stream data through a child's `stdin`, `stdout`, and `stderr` in a fully non-blocking way. (Note that some programs use line-buffered I/O internally. That doesn't affect Node.js but it means data you send to the child process may not be immediately consumed.) To create a child process, use `require('child_process').spawn()` or `require('child_process').fork()`. The semantics of each are slightly different as explained [below][]. For scripting purposes you may find the [synchronous counterparts][] more convenient. ## Class: ChildProcess `ChildProcess` is an [`EventEmitter`][]. Child processes always have three streams associated with them. `child.stdin`, `child.stdout`, and `child.stderr`. These may be shared with the stdio streams of the parent process, or they may be separate stream objects which can be piped to and from. The `ChildProcess` class is not intended to be used directly. Use the [`spawn()`][], [`exec()`][], [`execFile()`][], or [`fork()`][] methods to create an instance of `ChildProcess`. ### Event: 'close' * `code` {Number} the exit code, if it exited normally. * `signal` {String} the signal passed to kill the child process, if it was killed by the parent. This event is emitted when the stdio streams of a child process have all terminated. This is distinct from `'exit'`, since multiple processes might share the same stdio streams. ### Event: 'disconnect' This event is emitted after calling the `.disconnect()` method in the parent or in the child. After disconnecting it is no longer possible to send messages, and the `.connected` property is false. ### Event: 'error' * `err` {Error Object} the error. Emitted when: 1. The process could not be spawned, or 2. The process could not be killed, or 3. Sending a message to the child process failed. Note that the `'exit'` event may or may not fire after an error has occurred. If you are listening on both events to fire a function, remember to guard against calling your function twice. See also [`ChildProcess#kill()`][] and [`ChildProcess#send()`][]. ### Event: 'exit' * `code` {Number} the exit code, if it exited normally. * `signal` {String} the signal passed to kill the child process, if it was killed by the parent. This event is emitted after the child process ends. If the process terminated normally, `code` is the final exit code of the process, otherwise `null`. If the process terminated due to receipt of a signal, `signal` is the string name of the signal, otherwise `null`. Note that the child process stdio streams might still be open. Also, note that Node.js establishes signal handlers for `SIGINT` and `SIGTERM`. It will not terminate due to receipt of those signals. It will exit. See `waitpid(2)`. ### Event: 'message' * `message` {Object} a parsed JSON object or primitive value. * `sendHandle` {Handle object} a [`net.Socket`][] or [`net.Server`][] object, or undefined. Messages sent by `.send(message, [sendHandle])` are obtained using the `'message'` event. ### child.connected * {Boolean} Set to false after `.disconnect` is called If `.connected` is false, it is no longer possible to send messages. ### child.disconnect() Close the IPC channel between parent and child, allowing the child to exit gracefully once there are no other connections keeping it alive. After calling this method the `.connected` flag will be set to `false` in both the parent and child, and it is no longer possible to send messages. The `'disconnect'` event will be emitted when there are no messages in the process of being received, most likely immediately. Note that you can also call `process.disconnect()` in the child process when the child process has any open IPC channels with the parent (i.e [`fork()`][]). ### child.kill([signal]) * `signal` {String} Send a signal to the child process. If no argument is given, the process will be sent `'SIGTERM'`. See `signal(7)` for a list of available signals. const spawn = require('child_process').spawn; const grep = spawn('grep', ['ssh']); grep.on('close', (code, signal) => { console.log( `child process terminated due to receipt of signal ${signal}`); }); // send SIGHUP to process grep.kill('SIGHUP'); May emit an `'error'` event when the signal cannot be delivered. Sending a signal to a child process that has already exited is not an error but may have unforeseen consequences. Specifically, if the process identifier (PID) has been reassigned to another process, the signal will be delivered to that process instead. What happens next is anyone's guess. Note that while the function is called `kill`, the signal delivered to the child process may not actually kill it. `kill` really just sends a signal to a process. See `kill(2)` ### child.pid * {Integer} The process identifier (PID) of the child process. Example: const spawn = require('child_process').spawn; const grep = spawn('grep', ['ssh']); console.log(`Spawned child pid: ${grep.pid}`); grep.stdin.end(); ### child.send(message[, sendHandle][, callback]) * `message` {Object} * `sendHandle` {Handle object} * `callback` {Function} * Return: Boolean When using [`child_process.fork()`][] you can write to the child using `child.send(message[, sendHandle][, callback])` and messages are received by a `'message'` event on the child. For example: const cp = require('child_process'); const n = cp.fork(`${__dirname}/sub.js`); n.on('message', (m) => { console.log('PARENT got message:', m); }); n.send({ hello: 'world' }); And then the child script, `'sub.js'` might look like this: process.on('message', (m) => { console.log('CHILD got message:', m); }); process.send({ foo: 'bar' }); In the child, the `process` object will have a `send()` method, and `process` will emit objects each time it receives a message on its channel. There is a special case when sending a `{cmd: 'NODE_foo'}` message. All messages containing a `NODE_` prefix in its `cmd` property will not be emitted in the `'message'` event, since they are internal messages used by Node.js core. Messages containing the prefix are emitted in the `'internalMessage'` event. Avoid using this feature; it is subject to change without notice. The `sendHandle` option to `child.send()` is for sending a TCP server or socket object to another process. The child will receive the object as its second argument to the `'message'` event. The `callback` option is a function that is invoked after the message is sent but before the target may have received it. It is called with a single argument: `null` on success, or an [`Error`][] object on failure. `child.send()` emits an `'error'` event if no callback was given and the message cannot be sent, for example because the child process has already exited. Returns `true` under normal circumstances or `false` when the backlog of unsent messages exceeds a threshold that makes it unwise to send more. Use the callback mechanism to implement flow control. #### Example: sending server object Here is an example of sending a server: const child = require('child_process').fork('child.js'); // Open up the server object and send the handle. const server = require('net').createServer(); server.on('connection', (socket) => { socket.end('handled by parent'); }); server.listen(1337, () => { child.send('server', server); }); And the child would then receive the server object as: process.on('message', (m, server) => { if (m === 'server') { server.on('connection', (socket) => { socket.end('handled by child'); }); } }); Note that the server is now shared between the parent and child, this means that some connections will be handled by the parent and some by the child. For `dgram` servers the workflow is exactly the same. Here you listen on a `'message'` event instead of `'connection'` and use `server.bind` instead of `server.listen`. (Currently only supported on UNIX platforms.) #### Example: sending socket object Here is an example of sending a socket. It will spawn two children and handle connections with the remote address `74.125.127.100` as VIP by sending the socket to a "special" child process. Other sockets will go to a "normal" process. const normal = require('child_process').fork('child.js', ['normal']); const special = require('child_process').fork('child.js', ['special']); // Open up the server and send sockets to child const server = require('net').createServer(); server.on('connection', (socket) => { // if this is a VIP if (socket.remoteAddress === '74.125.127.100') { special.send('socket', socket); return; } // just the usual... normal.send('socket', socket); }); server.listen(1337); The `child.js` could look like this: process.on('message', (m, socket) => { if (m === 'socket') { socket.end(`You were handled as a ${process.argv[2]} person`); } }); Note that once a single socket has been sent to a child the parent can no longer keep track of when the socket is destroyed. To indicate this condition the `.connections` property becomes `null`. It is also recommended not to use `.maxConnections` in this condition. ### child.stderr * {Stream object} A `Readable Stream` that represents the child process's `stderr`. If the child was not spawned with `stdio[2]` set to `'pipe'`, then this will not be set. `child.stderr` is shorthand for `child.stdio[2]`. Both properties will refer to the same object, or null. ### child.stdin * {Stream object} A `Writable Stream` that represents the child process's `stdin`. If the child is waiting to read all its input, it will not continue until this stream has been closed via `end()`. If the child was not spawned with `stdio[0]` set to `'pipe'`, then this will not be set. `child.stdin` is shorthand for `child.stdio[0]`. Both properties will refer to the same object, or null. ### child.stdio * {Array} A sparse array of pipes to the child process, corresponding with positions in the [`stdio`][] option to [`spawn()`][] that have been set to `'pipe'`. Note that streams 0-2 are also available as ChildProcess.stdin, ChildProcess.stdout, and ChildProcess.stderr, respectively. In the following example, only the child's fd `1` is setup as a pipe, so only the parent's `child.stdio[1]` is a stream, all other values in the array are `null`. const assert = require('assert'); const fs = require('fs'); const child_process = require('child_process'); const child = child_process.spawn('ls', { stdio: [ 0, // use parents stdin for child 'pipe', // pipe child's stdout to parent fs.openSync('err.out', 'w') // direct child's stderr to a file ] }); assert.equal(child.stdio[0], null); assert.equal(child.stdio[0], child.stdin); assert(child.stdout); assert.equal(child.stdio[1], child.stdout); assert.equal(child.stdio[2], null); assert.equal(child.stdio[2], child.stderr); ### child.stdout * {Stream object} A `Readable Stream` that represents the child process's `stdout`. If the child was not spawned with `stdio[1]` set to `'pipe'`, then this will not be set. `child.stdout` is shorthand for `child.stdio[1]`. Both properties will refer to the same object, or null. ## Asynchronous Process Creation These methods follow the common async programming patterns (accepting a callback or returning an EventEmitter). ### child_process.exec(command[, options], callback) * `command` {String} The command to run, with space-separated arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `env` {Object} Environment key-value pairs * `encoding` {String} (Default: 'utf8') * `shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) * `timeout` {Number} (Default: 0) * `maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: `200*1024`) * `killSignal` {String} (Default: 'SIGTERM') * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * `callback` {Function} called with the output when process terminates * `error` {Error} * `stdout` {Buffer} * `stderr` {Buffer} * Return: ChildProcess object Runs a command in a shell and buffers the output. const exec = require('child_process').exec; const child = exec('cat *.js bad_file | wc -l', (error, stdout, stderr) => { console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); if (error !== null) { console.log(`exec error: ${error}`); } }); The callback gets the arguments `(error, stdout, stderr)`. On success, `error` will be `null`. On error, `error` will be an instance of [`Error`][] and `error.code` will be the exit code of the child process, and `error.signal` will be set to the signal that terminated the process. There is a second optional argument to specify several options. The default options are { encoding: 'utf8', timeout: 0, maxBuffer: 200*1024, killSignal: 'SIGTERM', cwd: null, env: null } If `timeout` is greater than 0, then it will kill the child process if it runs longer than `timeout` milliseconds. The child process is killed with `killSignal` (default: `'SIGTERM'`). `maxBuffer` specifies the largest amount of data (in bytes) allowed on stdout or stderr - if this value is exceeded then the child process is killed. *Note: Unlike the `exec()` POSIX system call, `child_process.exec()` does not replace the existing process and uses a shell to execute the command.* ### child_process.execFile(file[, args][, options][, callback]) * `file` {String} The filename of the program to run * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `env` {Object} Environment key-value pairs * `encoding` {String} (Default: 'utf8') * `timeout` {Number} (Default: 0) * `maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed (Default: 200\*1024) * `killSignal` {String} (Default: 'SIGTERM') * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * `callback` {Function} called with the output when process terminates * `error` {Error} * `stdout` {Buffer} * `stderr` {Buffer} * Return: ChildProcess object This is similar to [`child_process.exec()`][] except it does not execute a subshell but rather the specified file directly. This makes it slightly leaner than [`child_process.exec()`][]. It has the same options. ### child_process.fork(modulePath[, args][, options]) * `modulePath` {String} The module to run in the child * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `env` {Object} Environment key-value pairs * `execPath` {String} Executable used to create the child process * `execArgv` {Array} List of string arguments passed to the executable (Default: `process.execArgv`) * `silent` {Boolean} If true, stdin, stdout, and stderr of the child will be piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`spawn()`][]'s [`stdio`][] for more details (default is false) * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * Return: ChildProcess object This is a special case of the [`child_process.spawn()`][] functionality for spawning Node.js processes. In addition to having all the methods in a normal ChildProcess instance, the returned object has a communication channel built-in. See [`ChildProcess#send()`][] for details. These child Node.js processes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node.js. That is, you cannot create many thousands of them. The `execPath` property in the `options` object allows for a process to be created for the child rather than the current `node` executable. This should be done with care and by default will talk over the fd represented an environmental variable `NODE_CHANNEL_FD` on the child process. The input and output on this fd is expected to be line delimited JSON objects. *Note: Unlike the `fork()` POSIX system call, [`child_process.fork()`][] does not clone the current process.* ### child_process.spawn(command[, args][, options]) * `command` {String} The command to run * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `env` {Object} Environment key-value pairs * `stdio` {Array|String} Child's stdio configuration. (See [below](#child_process_options_stdio)) * `detached` {Boolean} Prepare child to run independently of its parent process. Specific behavior depends on the platform, see [below](#child_process_options_detached)) * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * return: {ChildProcess object} Launches a new process with the given `command`, with command line arguments in `args`. If omitted, `args` defaults to an empty Array. The third argument is used to specify additional options, with these defaults: { cwd: undefined, env: process.env } Use `cwd` to specify the working directory from which the process is spawned. If not given, the default is to inherit the current working directory. Use `env` to specify environment variables that will be visible to the new process, the default is `process.env`. Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code: const spawn = require('child_process').spawn; const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); ls.stderr.on('data', (data) => { console.log(`stderr: ${data}`); }); ls.on('close', (code) => { console.log(`child process exited with code ${code}`); }); Example: A very elaborate way to run 'ps ax | grep ssh' const spawn = require('child_process').spawn; const ps = spawn('ps', ['ax']); const grep = spawn('grep', ['ssh']); ps.stdout.on('data', (data) => { grep.stdin.write(data); }); ps.stderr.on('data', (data) => { console.log(`ps stderr: ${data}`); }); ps.on('close', (code) => { if (code !== 0) { console.log(`ps process exited with code ${code}`); } grep.stdin.end(); }); grep.stdout.on('data', (data) => { console.log(`${data}`); }); grep.stderr.on('data', (data) => { console.log(`grep stderr: ${data}`); }); grep.on('close', (code) => { if (code !== 0) { console.log(`grep process exited with code ${code}`); } }); Example of checking for failed exec: const spawn = require('child_process').spawn; const child = spawn('bad_command'); child.on('error', (err) => { console.log('Failed to start child process.'); }); #### options.detached On Windows, this makes it possible for the child to continue running after the parent exits. The child will have a new console window (this cannot be disabled). On non-Windows, if the `detached` option is set, the child process will be made the leader of a new process group and session. Note that child processes may continue running after the parent exits whether they are detached or not. See `setsid(2)` for more information. By default, the parent will wait for the detached child to exit. To prevent the parent from waiting for a given `child`, use the `child.unref()` method, and the parent's event loop will not include the child in its reference count. Example of detaching a long-running process and redirecting its output to a file: const fs = require('fs'); const spawn = require('child_process').spawn; const out = fs.openSync('./out.log', 'a'); const err = fs.openSync('./out.log', 'a'); const child = spawn('prg', [], { detached: true, stdio: [ 'ignore', out, err ] }); child.unref(); When using the `detached` option to start a long-running process, the process will not stay running in the background after the parent exits unless it is provided with a `stdio` configuration that is not connected to the parent. If the parent's `stdio` is inherited, the child will remain attached to the controlling terminal. #### options.stdio As a shorthand, the `stdio` argument may be one of the following strings: * `'pipe'` - `['pipe', 'pipe', 'pipe']`, this is the default value * `'ignore'` - `['ignore', 'ignore', 'ignore']` * `'inherit'` - `[process.stdin, process.stdout, process.stderr]` or `[0,1,2]` Otherwise, the `'stdio'` option to [`child_process.spawn()`][] is an array where each index corresponds to a fd in the child. The value is one of the following: 1. `'pipe'` - Create a pipe between the child process and the parent process. The parent end of the pipe is exposed to the parent as a property on the `child_process` object as `ChildProcess.stdio[fd]`. Pipes created for fds 0 - 2 are also available as ChildProcess.stdin, ChildProcess.stdout and ChildProcess.stderr, respectively. 2. `'ipc'` - Create an IPC channel for passing messages/file descriptors between parent and child. A ChildProcess may have at most *one* IPC stdio file descriptor. Setting this option enables the ChildProcess.send() method. If the child writes JSON messages to this file descriptor, then this will trigger ChildProcess.on('message'). If the child is an Node.js program, then the presence of an IPC channel will enable process.send() and process.on('message'). 3. `'ignore'` - Do not set this file descriptor in the child. Note that Node.js will always open fd 0 - 2 for the processes it spawns. When any of these is ignored Node.js will open `/dev/null` and attach it to the child's fd. 4. `Stream` object - Share a readable or writable stream that refers to a tty, file, socket, or a pipe with the child process. The stream's underlying file descriptor is duplicated in the child process to the fd that corresponds to the index in the `stdio` array. Note that the stream must have an underlying descriptor (file streams do not until the `'open'` event has occurred). 5. Positive integer - The integer value is interpreted as a file descriptor that is is currently open in the parent process. It is shared with the child process, similar to how `Stream` objects can be shared. 6. `null`, `undefined` - Use default value. For stdio fds 0, 1 and 2 (in other words, stdin, stdout, and stderr) a pipe is created. For fd 3 and up, the default is `'ignore'`. Example: const spawn = require('child_process').spawn; // Child will use parent's stdios spawn('prg', [], { stdio: 'inherit' }); // Spawn child sharing only stderr spawn('prg', [], { stdio: ['pipe', 'pipe', process.stderr] }); // Open an extra fd=4, to interact with programs present a // startd-style interface. spawn('prg', [], { stdio: ['pipe', null, null, null, 'pipe'] }); See also: [`child_process.exec()`][] and [`child_process.fork()`][] ## Synchronous Process Creation These methods are **synchronous**, meaning they **WILL** block the event loop, pausing execution of your code until the spawned process exits. Blocking calls like these are mostly useful for simplifying general purpose scripting tasks and for simplifying the loading/processing of application configuration at startup. ### child_process.execFileSync(file[, args][, options]) * `file` {String} The filename of the program to run * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `input` {String|Buffer} The value which will be passed as stdin to the spawned process - supplying this value will override `stdio[0]` * `stdio` {Array} Child's stdio configuration. (Default: 'pipe') - `stderr` by default will be output to the parent process' stderr unless `stdio` is specified * `env` {Object} Environment key-value pairs * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * `timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) * `killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') * `maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed * `encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') * return: {Buffer|String} The stdout from the command `execFileSync` will not return until the child process has fully closed. When a timeout has been encountered and `killSignal` is sent, the method won't return until the process has completely exited. That is to say, if the process handles the `SIGTERM` signal and doesn't exit, your process will wait until the child process has exited. If the process times out, or has a non-zero exit code, this method ***will*** throw. The [`Error`][] object will contain the entire result from [`child_process.spawnSync()`][] ### child_process.execSync(command[, options]) * `command` {String} The command to run * `options` {Object} * `cwd` {String} Current working directory of the child process * `input` {String|Buffer} The value which will be passed as stdin to the spawned process - supplying this value will override `stdio[0]` * `stdio` {Array} Child's stdio configuration. (Default: 'pipe') - `stderr` by default will be output to the parent process' stderr unless `stdio` is specified * `env` {Object} Environment key-value pairs * `shell` {String} Shell to execute the command with (Default: '/bin/sh' on UNIX, 'cmd.exe' on Windows, The shell should understand the `-c` switch on UNIX or `/s /c` on Windows. On Windows, command line parsing should be compatible with `cmd.exe`.) * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * `timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) * `killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') * `maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed * `encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') * return: {Buffer|String} The stdout from the command `execSync` will not return until the child process has fully closed. When a timeout has been encountered and `killSignal` is sent, the method won't return until the process has completely exited. That is to say, if the process handles the `SIGTERM` signal and doesn't exit, your process will wait until the child process has exited. If the process times out, or has a non-zero exit code, this method ***will*** throw. The [`Error`][] object will contain the entire result from [`child_process.spawnSync()`][] ### child_process.spawnSync(command[, args][, options]) * `command` {String} The command to run * `args` {Array} List of string arguments * `options` {Object} * `cwd` {String} Current working directory of the child process * `input` {String|Buffer} The value which will be passed as stdin to the spawned process - supplying this value will override `stdio[0]` * `stdio` {Array} Child's stdio configuration. * `env` {Object} Environment key-value pairs * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * `timeout` {Number} In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined) * `killSignal` {String} The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM') * `maxBuffer` {Number} largest amount of data (in bytes) allowed on stdout or stderr - if exceeded child process is killed * `encoding` {String} The encoding used for all stdio inputs and outputs. (Default: 'buffer') * return: {Object} * `pid` {Number} Pid of the child process * `output` {Array} Array of results from stdio output * `stdout` {Buffer|String} The contents of `output[1]` * `stderr` {Buffer|String} The contents of `output[2]` * `status` {Number} The exit code of the child process * `signal` {String} The signal used to kill the child process * `error` {Error} The error object if the child process failed or timed out `spawnSync` will not return until the child process has fully closed. When a timeout has been encountered and `killSignal` is sent, the method won't return until the process has completely exited. That is to say, if the process handles the `SIGTERM` signal and doesn't exit, your process will wait until the child process has exited. [`child_process.exec()`]: #child_process_child_process_exec_command_options_callback [`child_process.fork()`]: #child_process_child_process_fork_modulepath_args_options [`child_process.spawn()`]: #child_process_child_process_spawn_command_args_options [`child_process.spawnSync()`]: #child_process_child_process_spawnsync_command_args_options [`ChildProcess#kill()`]: #child_process_child_kill_signal [`ChildProcess#send()`]: #child_process_child_send_message_sendhandle_callback [`Error`]: errors.html#errors_class_error [`EventEmitter`]: events.html#events_class_events_eventemitter [`exec()`]: #child_process_child_process_exec_command_options_callback [`execFile()`]: #child_process_child_process_execfile_file_args_options_callback [`fork()`]: #child_process_child_process_fork_modulepath_args_options [`net.Server`]: net.html#net_class_net_server [`net.Socket`]: net.html#net_class_net_socket [`spawn()`]: #child_process_child_process_spawn_command_args_options [`stdio`]: #child_process_options_stdio [below]: #child_process_asynchronous_process_creation [synchronous counterparts]: #child_process_synchronous_process_creation node-v4.2.6/doc/api/cluster.html000644 000766 000024 00000105271 12650222331 016635 0ustar00iojsstaff000000 000000 Cluster Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Cluster#

Stability: 2 - Stable

A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load.

The cluster module allows you to easily create child processes that all share server ports.

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(8000);
}

Running Node.js will now share port 8000 between the workers:

% NODE_DEBUG=cluster node server.js
23521,Master Worker 23524 online
23521,Master Worker 23526 online
23521,Master Worker 23523 online
23521,Master Worker 23528 online

Please note that, on Windows, it is not yet possible to set up a named pipe server in a worker.

How It Works#

The worker processes are spawned using the [child_process.fork][] method, so that they can communicate with the parent via IPC and pass server handles back and forth.

The cluster module supports two methods of distributing incoming connections.

The first one (and the default one on all platforms except Windows), is the round-robin approach, where the master process listens on a port, accepts new connections and distributes them across the workers in a round-robin fashion, with some built-in smarts to avoid overloading a worker process.

The second approach is where the master process creates the listen socket and sends it to interested workers. The workers then accept incoming connections directly.

The second approach should, in theory, give the best performance. In practice however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight.

Because server.listen() hands off most of the work to the master process, there are three cases where the behavior between a normal Node.js process and a cluster worker differs:

  1. server.listen({fd: 7}) Because the message is passed to the master, file descriptor 7 in the parent will be listened on, and the handle passed to the worker, rather than listening to the worker's idea of what the number 7 file descriptor references.
  2. server.listen(handle) Listening on handles explicitly will cause the worker to use the supplied handle, rather than talk to the master process. If the worker already has the handle, then it's presumed that you know what you are doing.
  3. server.listen(0) Normally, this will cause servers to listen on a random port. However, in a cluster, each worker will receive the same "random" port each time they do listen(0). In essence, the port is random the first time, but predictable thereafter. If you want to listen on a unique port, generate a port number based on the cluster worker ID.

There is no routing logic in Node.js, or in your program, and no shared state between the workers. Therefore, it is important to design your program such that it does not rely too heavily on in-memory data objects for things like sessions and login.

Because workers are all separate processes, they can be killed or re-spawned depending on your program's needs, without affecting other workers. As long as there are some workers still alive, the server will continue to accept connections. If no workers are alive, existing connections will be dropped and new connections will be refused. Node.js does not automatically manage the number of workers for you, however. It is your responsibility to manage the worker pool for your application's needs.

Class: Worker#

A Worker object contains all public information and method about a worker. In the master it can be obtained using cluster.workers. In a worker it can be obtained using cluster.worker.

Event: 'disconnect'#

Similar to the cluster.on('disconnect') event, but specific to this worker.

cluster.fork().on('disconnect', () => {
  // Worker has disconnected
});

Event: 'error'#

This event is the same as the one provided by child_process.fork().

In a worker you can also use process.on('error').

Event: 'exit'#

  • code Number the exit code, if it exited normally.
  • signal String the name of the signal (eg. 'SIGHUP') that caused the process to be killed.

Similar to the cluster.on('exit') event, but specific to this worker.

const worker = cluster.fork();
worker.on('exit', (code, signal) => {
  if( signal ) {
    console.log(`worker was killed by signal: ${signal}`);
  } else if( code !== 0 ) {
    console.log(`worker exited with error code: ${code}`);
  } else {
    console.log('worker success!');
  }
});

Event: 'listening'#

  • address Object

Similar to the cluster.on('listening') event, but specific to this worker.

cluster.fork().on('listening', (address) => {
  // Worker is listening
});

It is not emitted in the worker.

Event: 'message'#

  • message Object

Similar to the cluster.on('message') event, but specific to this worker.

This event is the same as the one provided by child_process.fork().

In a worker you can also use process.on('message').

As an example, here is a cluster that keeps count of the number of requests in the master process using the message system:

const cluster = require('cluster');
const http = require('http');

if (cluster.isMaster) {

  // Keep track of http requests
  var numReqs = 0;
  setInterval(() => {
    console.log('numReqs =', numReqs);
  }, 1000);

  // Count requests
  function messageHandler(msg) {
    if (msg.cmd && msg.cmd == 'notifyRequest') {
      numReqs += 1;
    }
  }

  // Start workers and listen for messages containing notifyRequest
  const numCPUs = require('os').cpus().length;
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  Object.keys(cluster.workers).forEach((id) => {
    cluster.workers[id].on('message', messageHandler);
  });

} else {

  // Worker processes have a http server.
  http.Server((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');

    // notify master about the request
    process.send({ cmd: 'notifyRequest' });
  }).listen(8000);
}

Event: 'online'#

Similar to the cluster.on('online') event, but specific to this worker.

cluster.fork().on('online', () => {
  // Worker is online
});

It is not emitted in the worker.

worker.disconnect()#

In a worker, this function will close all servers, wait for the 'close' event on those servers, and then disconnect the IPC channel.

In the master, an internal message is sent to the worker causing it to call .disconnect() on itself.

Causes .suicide to be set.

Note that after a server is closed, it will no longer accept new connections, but connections may be accepted by any other listening worker. Existing connections will be allowed to close as usual. When no more connections exist, see [server.close()][], the IPC channel to the worker will close allowing it to die gracefully.

The above applies only to server connections, client connections are not automatically closed by workers, and disconnect does not wait for them to close before exiting.

Note that in a worker, process.disconnect exists, but it is not this function, it is disconnect.

Because long living server connections may block workers from disconnecting, it may be useful to send a message, so application specific actions may be taken to close them. It also may be useful to implement a timeout, killing a worker if the 'disconnect' event has not been emitted after some time.

if (cluster.isMaster) {
  var worker = cluster.fork();
  var timeout;

  worker.on('listening', (address) => {
    worker.send('shutdown');
    worker.disconnect();
    timeout = setTimeout(() => {
      worker.kill();
    }, 2000);
  });

  worker.on('disconnect', () => {
    clearTimeout(timeout);
  });

} else if (cluster.isWorker) {
  const net = require('net');
  var server = net.createServer((socket) => {
    // connections never end
  });

  server.listen(8000);

  process.on('message', (msg) => {
    if(msg === 'shutdown') {
      // initiate graceful close of any connections to server
    }
  });
}

worker.id#

  • Number

Each new worker is given its own unique id, this id is stored in the id.

While a worker is alive, this is the key that indexes it in cluster.workers

worker.isConnected()#

This function returns true if the worker is connected to its master via its IPC channel, false otherwise. A worker is connected to its master after it's been created. It is disconnected after the 'disconnect' event is emitted.

worker.isDead()#

This function returns true if the worker's process has terminated (either because of exiting or being signaled). Otherwise, it returns false.

worker.kill([signal='SIGTERM'])#

  • signal String Name of the kill signal to send to the worker process.

This function will kill the worker. In the master, it does this by disconnecting the worker.process, and once disconnected, killing with signal. In the worker, it does it by disconnecting the channel, and then exiting with code 0.

Causes .suicide to be set.

This method is aliased as worker.destroy() for backwards compatibility.

Note that in a worker, process.kill() exists, but it is not this function, it is kill.

worker.process#

  • ChildProcess object

All workers are created using child_process.fork(), the returned object from this function is stored as .process. In a worker, the global process is stored.

See: Child Process module

Note that workers will call process.exit(0) if the 'disconnect' event occurs on process and .suicide is not true. This protects against accidental disconnection.

worker.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object
  • callback Function
  • Return: Boolean

Send a message to a worker or master, optionally with a handle.

In the master this sends a message to a specific worker. It is identical to ChildProcess.send().

In a worker this sends a message to the master. It is identical to process.send().

This example will echo back all messages from the master:

if (cluster.isMaster) {
  var worker = cluster.fork();
  worker.send('hi there');

} else if (cluster.isWorker) {
  process.on('message', (msg) => {
    process.send(msg);
  });
}

worker.suicide#

  • Boolean

Set by calling .kill() or .disconnect(), until then it is undefined.

The boolean worker.suicide lets you distinguish between voluntary and accidental exit, the master may choose not to respawn a worker based on this value.

cluster.on('exit', (worker, code, signal) => {
  if (worker.suicide === true) {
    console.log('Oh, it was just suicide\' – no need to worry').
  }
});

// kill worker
worker.kill();

Event: 'disconnect'#

  • worker Worker object

Emitted after the worker IPC channel has disconnected. This can occur when a worker exits gracefully, is killed, or is disconnected manually (such as with worker.disconnect()).

There may be a delay between the 'disconnect' and 'exit' events. These events can be used to detect if the process is stuck in a cleanup or if there are long-living connections.

cluster.on('disconnect', (worker) => {
  console.log(`The worker #${worker.id} has disconnected`);
});

Event: 'exit'#

  • worker Worker object
  • code Number the exit code, if it exited normally.
  • signal String the name of the signal (eg. 'SIGHUP') that caused the process to be killed.

When any of the workers die the cluster module will emit the 'exit' event.

This can be used to restart the worker by calling .fork() again.

cluster.on('exit', (worker, code, signal) => {
  console.log('worker %d died (%s). restarting...',
    worker.process.pid, signal || code);
  cluster.fork();
});

See child_process event: 'exit'.

Event: 'fork'#

  • worker Worker object

When a new worker is forked the cluster module will emit a 'fork' event. This can be used to log worker activity, and create your own timeout.

var timeouts = [];
function errorMsg() {
  console.error('Something must be wrong with the connection ...');
}

cluster.on('fork', (worker) => {
  timeouts[worker.id] = setTimeout(errorMsg, 2000);
});
cluster.on('listening', (worker, address) => {
  clearTimeout(timeouts[worker.id]);
});
cluster.on('exit', (worker, code, signal) => {
  clearTimeout(timeouts[worker.id]);
  errorMsg();
});

Event: 'listening'#

  • worker Worker object
  • address Object

After calling listen() from a worker, when the 'listening' event is emitted on the server, a 'listening' event will also be emitted on cluster in the master.

The event handler is executed with two arguments, the worker contains the worker object and the address object contains the following connection properties: address, port and addressType. This is very useful if the worker is listening on more than one address.

cluster.on('listening', (worker, address) => {
  console.log(
    `A worker is now connected to ${address.address}:${address.port}`);
});

The addressType is one of:

  • 4 (TCPv4)
  • 6 (TCPv6)
  • -1 (unix domain socket)
  • "udp4" or "udp6" (UDP v4 or v6)

Event: 'message'#

  • worker Worker object
  • message Object

Emitted when any worker receives a message.

See child_process event: 'message'.

Event: 'online'#

  • worker Worker object

After forking a new worker, the worker should respond with an online message. When the master receives an online message it will emit this event. The difference between 'fork' and 'online' is that fork is emitted when the master forks a worker, and 'online' is emitted when the worker is running.

cluster.on('online', (worker) => {
  console.log('Yay, the worker responded after it was forked');
});

Event: 'setup'#

  • settings Object

Emitted every time .setupMaster() is called.

The settings object is the cluster.settings object at the time .setupMaster() was called and is advisory only, since multiple calls to .setupMaster() can be made in a single tick.

If accuracy is important, use cluster.settings.

cluster.disconnect([callback])#

  • callback Function called when all workers are disconnected and handles are closed

Calls .disconnect() on each worker in cluster.workers.

When they are disconnected all internal handles will be closed, allowing the master process to die gracefully if no other event is waiting.

The method takes an optional callback argument which will be called when finished.

This can only be called from the master process.

cluster.fork([env])#

  • env Object Key/value pairs to add to worker process environment.
  • return Worker object

Spawn a new worker process.

This can only be called from the master process.

cluster.isMaster#

  • Boolean

True if the process is a master. This is determined by the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is undefined, then isMaster is true.

cluster.isWorker#

  • Boolean

True if the process is not a master (it is the negation of cluster.isMaster).

cluster.schedulingPolicy#

The scheduling policy, either cluster.SCHED_RR for round-robin or cluster.SCHED_NONE to leave it to the operating system. This is a global setting and effectively frozen once you spawn the first worker or call cluster.setupMaster(), whatever comes first.

SCHED_RR is the default on all operating systems except Windows. Windows will change to SCHED_RR once libuv is able to effectively distribute IOCP handles without incurring a large performance hit.

cluster.schedulingPolicy can also be set through the NODE_CLUSTER_SCHED_POLICY environment variable. Valid values are "rr" and "none".

cluster.settings#

  • Object
    • execArgv Array list of string arguments passed to the Node.js executable. (Default=process.execArgv)
    • exec String file path to worker file. (Default=process.argv[1])
    • args Array string arguments passed to worker. (Default=process.argv.slice(2))
    • silent Boolean whether or not to send output to parent's stdio. (Default=false)
    • uid Number Sets the user identity of the process. (See setuid(2).)
    • gid Number Sets the group identity of the process. (See setgid(2).)

After calling .setupMaster() (or .fork()) this settings object will contain the settings, including the default values.

It is effectively frozen after being set, because .setupMaster() can only be called once.

This object is not supposed to be changed or set manually, by you.

cluster.setupMaster([settings])#

  • settings Object
    • exec String file path to worker file. (Default=process.argv[1])
    • args Array string arguments passed to worker. (Default=process.argv.slice(2))
    • silent Boolean whether or not to send output to parent's stdio. (Default=false)

setupMaster is used to change the default 'fork' behavior. Once called, the settings will be present in cluster.settings.

Note that:

  • any settings changes only affect future calls to .fork() and have no effect on workers that are already running
  • The only attribute of a worker that cannot be set via .setupMaster() is the env passed to .fork()
  • the defaults above apply to the first call only, the defaults for later calls is the current value at the time of cluster.setupMaster() is called

Example:

const cluster = require('cluster');
cluster.setupMaster({
  exec: 'worker.js',
  args: ['--use', 'https'],
  silent: true
});
cluster.fork(); // https worker
cluster.setupMaster({
  args: ['--use', 'http']
});
cluster.fork(); // http worker

This can only be called from the master process.

cluster.worker#

  • Object

A reference to the current worker object. Not available in the master process.

const cluster = require('cluster');

if (cluster.isMaster) {
  console.log('I am master');
  cluster.fork();
  cluster.fork();
} else if (cluster.isWorker) {
  console.log(`I am worker #${cluster.worker.id}`);
}

cluster.workers#

  • Object

A hash that stores the active worker objects, keyed by id field. Makes it easy to loop through all the workers. It is only available in the master process.

A worker is removed from cluster.workers after the worker has disconnected and exited. The order between these two events cannot be determined in advance. However, it is guaranteed that the removal from the cluster.workers list happens before last 'disconnect' or 'exit' event is emitted.

// Go through all workers
function eachWorker(callback) {
  for (var id in cluster.workers) {
    callback(cluster.workers[id]);
  }
}
eachWorker((worker) => {
  worker.send('big announcement to all workers');
});

Should you wish to reference a worker over a communication channel, using the worker's unique id is the easiest way to find the worker.

socket.on('data', (id) => {
  var worker = cluster.workers[id];
});
node-v4.2.6/doc/api/cluster.json000644 000766 000024 00000101243 12650222331 016635 0ustar00iojsstaff000000 000000 { "source": "doc/api/cluster.markdown", "modules": [ { "textRaw": "Cluster", "name": "cluster", "stability": 2, "stabilityText": "Stable", "desc": "

A single instance of Node.js runs in a single thread. To take advantage of\nmulti-core systems the user will sometimes want to launch a cluster of Node.js\nprocesses to handle the load.\n\n

\n

The cluster module allows you to easily create child processes that\nall share server ports.\n\n

\n
const cluster = require('cluster');\nconst http = require('http');\nconst numCPUs = require('os').cpus().length;\n\nif (cluster.isMaster) {\n  // Fork workers.\n  for (var i = 0; i < numCPUs; i++) {\n    cluster.fork();\n  }\n\n  cluster.on('exit', (worker, code, signal) => {\n    console.log(`worker ${worker.process.pid} died`);\n  });\n} else {\n  // Workers can share any TCP connection\n  // In this case it is an HTTP server\n  http.createServer((req, res) => {\n    res.writeHead(200);\n    res.end('hello world\\n');\n  }).listen(8000);\n}
\n

Running Node.js will now share port 8000 between the workers:\n\n

\n
% NODE_DEBUG=cluster node server.js\n23521,Master Worker 23524 online\n23521,Master Worker 23526 online\n23521,Master Worker 23523 online\n23521,Master Worker 23528 online
\n

Please note that, on Windows, it is not yet possible to set up a named pipe\nserver in a worker.\n\n

\n", "miscs": [ { "textRaw": "How It Works", "name": "How It Works", "type": "misc", "desc": "

The worker processes are spawned using the [child_process.fork][] method,\nso that they can communicate with the parent via IPC and pass server\nhandles back and forth.\n\n

\n

The cluster module supports two methods of distributing incoming\nconnections.\n\n

\n

The first one (and the default one on all platforms except Windows),\nis the round-robin approach, where the master process listens on a\nport, accepts new connections and distributes them across the workers\nin a round-robin fashion, with some built-in smarts to avoid\noverloading a worker process.\n\n

\n

The second approach is where the master process creates the listen\nsocket and sends it to interested workers. The workers then accept\nincoming connections directly.\n\n

\n

The second approach should, in theory, give the best performance.\nIn practice however, distribution tends to be very unbalanced due\nto operating system scheduler vagaries. Loads have been observed\nwhere over 70% of all connections ended up in just two processes,\nout of a total of eight.\n\n

\n

Because server.listen() hands off most of the work to the master\nprocess, there are three cases where the behavior between a normal\nNode.js process and a cluster worker differs:\n\n

\n
    \n
  1. server.listen({fd: 7}) Because the message is passed to the master,\nfile descriptor 7 in the parent will be listened on, and the\nhandle passed to the worker, rather than listening to the worker's\nidea of what the number 7 file descriptor references.
  2. \n
  3. server.listen(handle) Listening on handles explicitly will cause\nthe worker to use the supplied handle, rather than talk to the master\nprocess. If the worker already has the handle, then it's presumed\nthat you know what you are doing.
  4. \n
  5. server.listen(0) Normally, this will cause servers to listen on a\nrandom port. However, in a cluster, each worker will receive the\nsame "random" port each time they do listen(0). In essence, the\nport is random the first time, but predictable thereafter. If you\nwant to listen on a unique port, generate a port number based on the\ncluster worker ID.
  6. \n
\n

There is no routing logic in Node.js, or in your program, and no shared\nstate between the workers. Therefore, it is important to design your\nprogram such that it does not rely too heavily on in-memory data objects\nfor things like sessions and login.\n\n

\n

Because workers are all separate processes, they can be killed or\nre-spawned depending on your program's needs, without affecting other\nworkers. As long as there are some workers still alive, the server will\ncontinue to accept connections. If no workers are alive, existing connections\nwill be dropped and new connections will be refused. Node.js does not\nautomatically manage the number of workers for you, however. It is your\nresponsibility to manage the worker pool for your application's needs.\n\n\n\n

\n" } ], "classes": [ { "textRaw": "Class: Worker", "type": "class", "name": "Worker", "desc": "

A Worker object contains all public information and method about a worker.\nIn the master it can be obtained using cluster.workers. In a worker\nit can be obtained using cluster.worker.\n\n

\n", "events": [ { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "desc": "

Similar to the cluster.on('disconnect') event, but specific to this worker.\n\n

\n
cluster.fork().on('disconnect', () => {\n  // Worker has disconnected\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "desc": "

This event is the same as the one provided by [child_process.fork()][].\n\n

\n

In a worker you can also use process.on('error').\n\n

\n", "params": [] }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

Similar to the cluster.on('exit') event, but specific to this worker.\n\n

\n
const worker = cluster.fork();\nworker.on('exit', (code, signal) => {\n  if( signal ) {\n    console.log(`worker was killed by signal: ${signal}`);\n  } else if( code !== 0 ) {\n    console.log(`worker exited with error code: ${code}`);\n  } else {\n    console.log('worker success!');\n  }\n});
\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "params": [], "desc": "

Similar to the cluster.on('listening') event, but specific to this worker.\n\n

\n
cluster.fork().on('listening', (address) => {\n  // Worker is listening\n});
\n

It is not emitted in the worker.\n\n

\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Similar to the cluster.on('message') event, but specific to this worker.\n\n

\n

This event is the same as the one provided by [child_process.fork()][].\n\n

\n

In a worker you can also use process.on('message').\n\n

\n

As an example, here is a cluster that keeps count of the number of requests\nin the master process using the message system:\n\n

\n
const cluster = require('cluster');\nconst http = require('http');\n\nif (cluster.isMaster) {\n\n  // Keep track of http requests\n  var numReqs = 0;\n  setInterval(() => {\n    console.log('numReqs =', numReqs);\n  }, 1000);\n\n  // Count requests\n  function messageHandler(msg) {\n    if (msg.cmd && msg.cmd == 'notifyRequest') {\n      numReqs += 1;\n    }\n  }\n\n  // Start workers and listen for messages containing notifyRequest\n  const numCPUs = require('os').cpus().length;\n  for (var i = 0; i < numCPUs; i++) {\n    cluster.fork();\n  }\n\n  Object.keys(cluster.workers).forEach((id) => {\n    cluster.workers[id].on('message', messageHandler);\n  });\n\n} else {\n\n  // Worker processes have a http server.\n  http.Server((req, res) => {\n    res.writeHead(200);\n    res.end('hello world\\n');\n\n    // notify master about the request\n    process.send({ cmd: 'notifyRequest' });\n  }).listen(8000);\n}
\n" }, { "textRaw": "Event: 'online'", "type": "event", "name": "online", "desc": "

Similar to the cluster.on('online') event, but specific to this worker.\n\n

\n
cluster.fork().on('online', () => {\n  // Worker is online\n});
\n

It is not emitted in the worker.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "worker.disconnect()", "type": "method", "name": "disconnect", "desc": "

In a worker, this function will close all servers, wait for the 'close' event on\nthose servers, and then disconnect the IPC channel.\n\n

\n

In the master, an internal message is sent to the worker causing it to call\n.disconnect() on itself.\n\n

\n

Causes .suicide to be set.\n\n

\n

Note that after a server is closed, it will no longer accept new connections,\nbut connections may be accepted by any other listening worker. Existing\nconnections will be allowed to close as usual. When no more connections exist,\nsee [server.close()][], the IPC channel to the worker will close allowing it to\ndie gracefully.\n\n

\n

The above applies only to server connections, client connections are not\nautomatically closed by workers, and disconnect does not wait for them to close\nbefore exiting.\n\n

\n

Note that in a worker, process.disconnect exists, but it is not this function,\nit is [disconnect][].\n\n

\n

Because long living server connections may block workers from disconnecting, it\nmay be useful to send a message, so application specific actions may be taken to\nclose them. It also may be useful to implement a timeout, killing a worker if\nthe 'disconnect' event has not been emitted after some time.\n\n

\n
if (cluster.isMaster) {\n  var worker = cluster.fork();\n  var timeout;\n\n  worker.on('listening', (address) => {\n    worker.send('shutdown');\n    worker.disconnect();\n    timeout = setTimeout(() => {\n      worker.kill();\n    }, 2000);\n  });\n\n  worker.on('disconnect', () => {\n    clearTimeout(timeout);\n  });\n\n} else if (cluster.isWorker) {\n  const net = require('net');\n  var server = net.createServer((socket) => {\n    // connections never end\n  });\n\n  server.listen(8000);\n\n  process.on('message', (msg) => {\n    if(msg === 'shutdown') {\n      // initiate graceful close of any connections to server\n    }\n  });\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.isConnected()", "type": "method", "name": "isConnected", "desc": "

This function returns true if the worker is connected to its master via its IPC\nchannel, false otherwise. A worker is connected to its master after it's been\ncreated. It is disconnected after the 'disconnect' event is emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.isDead()", "type": "method", "name": "isDead", "desc": "

This function returns true if the worker's process has terminated (either\nbecause of exiting or being signaled). Otherwise, it returns false.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "worker.kill([signal='SIGTERM'])", "type": "method", "name": "kill", "signatures": [ { "params": [ { "textRaw": "`signal` {String} Name of the kill signal to send to the worker process. ", "name": "signal", "type": "String", "desc": "Name of the kill signal to send to the worker process.", "optional": true, "default": "'SIGTERM'" } ] }, { "params": [ { "name": "signal", "optional": true, "default": "'SIGTERM'" } ] } ], "desc": "

This function will kill the worker. In the master, it does this by disconnecting\nthe worker.process, and once disconnected, killing with signal. In the\nworker, it does it by disconnecting the channel, and then exiting with code 0.\n\n

\n

Causes .suicide to be set.\n\n

\n

This method is aliased as worker.destroy() for backwards compatibility.\n\n

\n

Note that in a worker, process.kill() exists, but it is not this function,\nit is [kill][].\n\n

\n" }, { "textRaw": "worker.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "return": { "textRaw": "Return: Boolean ", "name": "return", "desc": "Boolean" }, "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Send a message to a worker or master, optionally with a handle.\n\n

\n

In the master this sends a message to a specific worker. It is identical to\n[ChildProcess.send()][].\n\n

\n

In a worker this sends a message to the master. It is identical to\nprocess.send().\n\n

\n

This example will echo back all messages from the master:\n\n

\n
if (cluster.isMaster) {\n  var worker = cluster.fork();\n  worker.send('hi there');\n\n} else if (cluster.isWorker) {\n  process.on('message', (msg) => {\n    process.send(msg);\n  });\n}
\n" } ], "properties": [ { "textRaw": "`id` {Number} ", "name": "id", "desc": "

Each new worker is given its own unique id, this id is stored in the\nid.\n\n

\n

While a worker is alive, this is the key that indexes it in\ncluster.workers\n\n

\n" }, { "textRaw": "`process` {ChildProcess object} ", "name": "process", "desc": "

All workers are created using [child_process.fork()][], the returned object\nfrom this function is stored as .process. In a worker, the global process\nis stored.\n\n

\n

See: [Child Process module][]\n\n

\n

Note that workers will call process.exit(0) if the 'disconnect' event occurs\non process and .suicide is not true. This protects against accidental\ndisconnection.\n\n

\n" }, { "textRaw": "`suicide` {Boolean} ", "name": "suicide", "desc": "

Set by calling .kill() or .disconnect(), until then it is undefined.\n\n

\n

The boolean worker.suicide lets you distinguish between voluntary and accidental\nexit, the master may choose not to respawn a worker based on this value.\n\n

\n
cluster.on('exit', (worker, code, signal) => {\n  if (worker.suicide === true) {\n    console.log('Oh, it was just suicide\\' – no need to worry').\n  }\n});\n\n// kill worker\nworker.kill();
\n" } ] } ], "events": [ { "textRaw": "Event: 'disconnect'", "type": "event", "name": "disconnect", "params": [], "desc": "

Emitted after the worker IPC channel has disconnected. This can occur when a\nworker exits gracefully, is killed, or is disconnected manually (such as with\nworker.disconnect()).\n\n

\n

There may be a delay between the 'disconnect' and 'exit' events. These events\ncan be used to detect if the process is stuck in a cleanup or if there are\nlong-living connections.\n\n

\n
cluster.on('disconnect', (worker) => {\n  console.log(`The worker #${worker.id} has disconnected`);\n});
\n" }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "params": [], "desc": "

When any of the workers die the cluster module will emit the 'exit' event.\n\n

\n

This can be used to restart the worker by calling .fork() again.\n\n

\n
cluster.on('exit', (worker, code, signal) => {\n  console.log('worker %d died (%s). restarting...',\n    worker.process.pid, signal || code);\n  cluster.fork();\n});
\n

See [child_process event: 'exit'][].\n\n

\n" }, { "textRaw": "Event: 'fork'", "type": "event", "name": "fork", "params": [], "desc": "

When a new worker is forked the cluster module will emit a 'fork' event.\nThis can be used to log worker activity, and create your own timeout.\n\n

\n
var timeouts = [];\nfunction errorMsg() {\n  console.error('Something must be wrong with the connection ...');\n}\n\ncluster.on('fork', (worker) => {\n  timeouts[worker.id] = setTimeout(errorMsg, 2000);\n});\ncluster.on('listening', (worker, address) => {\n  clearTimeout(timeouts[worker.id]);\n});\ncluster.on('exit', (worker, code, signal) => {\n  clearTimeout(timeouts[worker.id]);\n  errorMsg();\n});
\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "params": [], "desc": "

After calling listen() from a worker, when the 'listening' event is emitted on\nthe server, a 'listening' event will also be emitted on cluster in the master.\n\n

\n

The event handler is executed with two arguments, the worker contains the worker\nobject and the address object contains the following connection properties:\naddress, port and addressType. This is very useful if the worker is listening\non more than one address.\n\n

\n
cluster.on('listening', (worker, address) => {\n  console.log(\n    `A worker is now connected to ${address.address}:${address.port}`);\n});
\n

The addressType is one of:\n\n

\n
    \n
  • 4 (TCPv4)
  • \n
  • 6 (TCPv6)
  • \n
  • -1 (unix domain socket)
  • \n
  • "udp4" or "udp6" (UDP v4 or v6)
  • \n
\n" }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Emitted when any worker receives a message.\n\n

\n

See [child_process event: 'message'][].\n\n

\n" }, { "textRaw": "Event: 'online'", "type": "event", "name": "online", "params": [], "desc": "

After forking a new worker, the worker should respond with an online message.\nWhen the master receives an online message it will emit this event.\nThe difference between 'fork' and 'online' is that fork is emitted when the\nmaster forks a worker, and 'online' is emitted when the worker is running.\n\n

\n
cluster.on('online', (worker) => {\n  console.log('Yay, the worker responded after it was forked');\n});
\n" }, { "textRaw": "Event: 'setup'", "type": "event", "name": "setup", "params": [], "desc": "

Emitted every time .setupMaster() is called.\n\n

\n

The settings object is the cluster.settings object at the time\n.setupMaster() was called and is advisory only, since multiple calls to\n.setupMaster() can be made in a single tick.\n\n

\n

If accuracy is important, use cluster.settings.\n\n

\n" } ], "methods": [ { "textRaw": "cluster.disconnect([callback])", "type": "method", "name": "disconnect", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} called when all workers are disconnected and handles are closed ", "name": "callback", "type": "Function", "desc": "called when all workers are disconnected and handles are closed", "optional": true } ] }, { "params": [ { "name": "callback", "optional": true } ] } ], "desc": "

Calls .disconnect() on each worker in cluster.workers.\n\n

\n

When they are disconnected all internal handles will be closed, allowing the\nmaster process to die gracefully if no other event is waiting.\n\n

\n

The method takes an optional callback argument which will be called when finished.\n\n

\n

This can only be called from the master process.\n\n

\n" }, { "textRaw": "cluster.fork([env])", "type": "method", "name": "fork", "signatures": [ { "return": { "textRaw": "return {Worker object} ", "name": "return", "type": "Worker object" }, "params": [ { "textRaw": "`env` {Object} Key/value pairs to add to worker process environment. ", "name": "env", "type": "Object", "desc": "Key/value pairs to add to worker process environment.", "optional": true } ] }, { "params": [ { "name": "env", "optional": true } ] } ], "desc": "

Spawn a new worker process.\n\n

\n

This can only be called from the master process.\n\n

\n" }, { "textRaw": "cluster.setupMaster([settings])", "type": "method", "name": "setupMaster", "signatures": [ { "params": [ { "textRaw": "`settings` {Object} ", "options": [ { "textRaw": "`exec` {String} file path to worker file. (Default=`process.argv[1]`) ", "name": "exec", "default": "process.argv[1]", "type": "String", "desc": "file path to worker file." }, { "textRaw": "`args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) ", "name": "args", "default": "process.argv.slice(2)", "type": "Array", "desc": "string arguments passed to worker." }, { "textRaw": "`silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) ", "name": "silent", "default": "false", "type": "Boolean", "desc": "whether or not to send output to parent's stdio." } ], "name": "settings", "type": "Object", "optional": true } ] }, { "params": [ { "name": "settings", "optional": true } ] } ], "desc": "

setupMaster is used to change the default 'fork' behavior. Once called,\nthe settings will be present in cluster.settings.\n\n

\n

Note that:\n\n

\n
    \n
  • any settings changes only affect future calls to .fork() and have no\neffect on workers that are already running
  • \n
  • The only attribute of a worker that cannot be set via .setupMaster() is\nthe env passed to .fork()
  • \n
  • the defaults above apply to the first call only, the defaults for later\ncalls is the current value at the time of cluster.setupMaster() is called
  • \n
\n

Example:\n\n

\n
const cluster = require('cluster');\ncluster.setupMaster({\n  exec: 'worker.js',\n  args: ['--use', 'https'],\n  silent: true\n});\ncluster.fork(); // https worker\ncluster.setupMaster({\n  args: ['--use', 'http']\n});\ncluster.fork(); // http worker
\n

This can only be called from the master process.\n\n

\n" } ], "properties": [ { "textRaw": "`isMaster` {Boolean} ", "name": "isMaster", "desc": "

True if the process is a master. This is determined\nby the process.env.NODE_UNIQUE_ID. If process.env.NODE_UNIQUE_ID is\nundefined, then isMaster is true.\n\n

\n" }, { "textRaw": "`isWorker` {Boolean} ", "name": "isWorker", "desc": "

True if the process is not a master (it is the negation of cluster.isMaster).\n\n

\n" }, { "textRaw": "cluster.schedulingPolicy", "name": "schedulingPolicy", "desc": "

The scheduling policy, either cluster.SCHED_RR for round-robin or\ncluster.SCHED_NONE to leave it to the operating system. This is a\nglobal setting and effectively frozen once you spawn the first worker\nor call cluster.setupMaster(), whatever comes first.\n\n

\n

SCHED_RR is the default on all operating systems except Windows.\nWindows will change to SCHED_RR once libuv is able to effectively\ndistribute IOCP handles without incurring a large performance hit.\n\n

\n

cluster.schedulingPolicy can also be set through the\nNODE_CLUSTER_SCHED_POLICY environment variable. Valid\nvalues are "rr" and "none".\n\n

\n" }, { "textRaw": "`settings` {Object} ", "name": "settings", "options": [ { "textRaw": "`execArgv` {Array} list of string arguments passed to the Node.js executable. (Default=`process.execArgv`) ", "name": "execArgv", "default": "process.execArgv", "type": "Array", "desc": "list of string arguments passed to the Node.js executable." }, { "textRaw": "`exec` {String} file path to worker file. (Default=`process.argv[1]`) ", "name": "exec", "default": "process.argv[1]", "type": "String", "desc": "file path to worker file." }, { "textRaw": "`args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) ", "name": "args", "default": "process.argv.slice(2)", "type": "Array", "desc": "string arguments passed to worker." }, { "textRaw": "`silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) ", "name": "silent", "default": "false", "type": "Boolean", "desc": "whether or not to send output to parent's stdio." }, { "textRaw": "`uid` {Number} Sets the user identity of the process. (See setuid(2).) ", "name": "uid", "type": "Number", "desc": "Sets the user identity of the process. (See setuid(2).)" }, { "textRaw": "`gid` {Number} Sets the group identity of the process. (See setgid(2).) ", "name": "gid", "type": "Number", "desc": "Sets the group identity of the process. (See setgid(2).)" } ], "desc": "

After calling .setupMaster() (or .fork()) this settings object will contain\nthe settings, including the default values.\n\n

\n

It is effectively frozen after being set, because .setupMaster() can\nonly be called once.\n\n

\n

This object is not supposed to be changed or set manually, by you.\n\n

\n" }, { "textRaw": "`worker` {Object} ", "name": "worker", "desc": "

A reference to the current worker object. Not available in the master process.\n\n

\n
const cluster = require('cluster');\n\nif (cluster.isMaster) {\n  console.log('I am master');\n  cluster.fork();\n  cluster.fork();\n} else if (cluster.isWorker) {\n  console.log(`I am worker #${cluster.worker.id}`);\n}
\n" }, { "textRaw": "`workers` {Object} ", "name": "workers", "desc": "

A hash that stores the active worker objects, keyed by id field. Makes it\neasy to loop through all the workers. It is only available in the master\nprocess.\n\n

\n

A worker is removed from cluster.workers after the worker has disconnected and\nexited. The order between these two events cannot be determined in advance.\nHowever, it is guaranteed that the removal from the cluster.workers list happens\nbefore last 'disconnect' or 'exit' event is emitted.\n\n

\n
// Go through all workers\nfunction eachWorker(callback) {\n  for (var id in cluster.workers) {\n    callback(cluster.workers[id]);\n  }\n}\neachWorker((worker) => {\n  worker.send('big announcement to all workers');\n});
\n

Should you wish to reference a worker over a communication channel, using\nthe worker's unique id is the easiest way to find the worker.\n\n

\n
socket.on('data', (id) => {\n  var worker = cluster.workers[id];\n});
\n" } ], "type": "module", "displayName": "Cluster" } ] } node-v4.2.6/doc/api/cluster.markdown000644 000766 000024 00000050503 12650222326 017514 0ustar00iojsstaff000000 000000 # Cluster Stability: 2 - Stable A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js processes to handle the load. The cluster module allows you to easily create child processes that all share server ports. const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server http.createServer((req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); } Running Node.js will now share port 8000 between the workers: % NODE_DEBUG=cluster node server.js 23521,Master Worker 23524 online 23521,Master Worker 23526 online 23521,Master Worker 23523 online 23521,Master Worker 23528 online Please note that, on Windows, it is not yet possible to set up a named pipe server in a worker. ## How It Works The worker processes are spawned using the [`child_process.fork`][] method, so that they can communicate with the parent via IPC and pass server handles back and forth. The cluster module supports two methods of distributing incoming connections. The first one (and the default one on all platforms except Windows), is the round-robin approach, where the master process listens on a port, accepts new connections and distributes them across the workers in a round-robin fashion, with some built-in smarts to avoid overloading a worker process. The second approach is where the master process creates the listen socket and sends it to interested workers. The workers then accept incoming connections directly. The second approach should, in theory, give the best performance. In practice however, distribution tends to be very unbalanced due to operating system scheduler vagaries. Loads have been observed where over 70% of all connections ended up in just two processes, out of a total of eight. Because `server.listen()` hands off most of the work to the master process, there are three cases where the behavior between a normal Node.js process and a cluster worker differs: 1. `server.listen({fd: 7})` Because the message is passed to the master, file descriptor 7 **in the parent** will be listened on, and the handle passed to the worker, rather than listening to the worker's idea of what the number 7 file descriptor references. 2. `server.listen(handle)` Listening on handles explicitly will cause the worker to use the supplied handle, rather than talk to the master process. If the worker already has the handle, then it's presumed that you know what you are doing. 3. `server.listen(0)` Normally, this will cause servers to listen on a random port. However, in a cluster, each worker will receive the same "random" port each time they do `listen(0)`. In essence, the port is random the first time, but predictable thereafter. If you want to listen on a unique port, generate a port number based on the cluster worker ID. There is no routing logic in Node.js, or in your program, and no shared state between the workers. Therefore, it is important to design your program such that it does not rely too heavily on in-memory data objects for things like sessions and login. Because workers are all separate processes, they can be killed or re-spawned depending on your program's needs, without affecting other workers. As long as there are some workers still alive, the server will continue to accept connections. If no workers are alive, existing connections will be dropped and new connections will be refused. Node.js does not automatically manage the number of workers for you, however. It is your responsibility to manage the worker pool for your application's needs. ## Class: Worker A Worker object contains all public information and method about a worker. In the master it can be obtained using `cluster.workers`. In a worker it can be obtained using `cluster.worker`. ### Event: 'disconnect' Similar to the `cluster.on('disconnect')` event, but specific to this worker. cluster.fork().on('disconnect', () => { // Worker has disconnected }); ### Event: 'error' This event is the same as the one provided by [`child_process.fork()`][]. In a worker you can also use `process.on('error')`. ### Event: 'exit' * `code` {Number} the exit code, if it exited normally. * `signal` {String} the name of the signal (eg. `'SIGHUP'`) that caused the process to be killed. Similar to the `cluster.on('exit')` event, but specific to this worker. const worker = cluster.fork(); worker.on('exit', (code, signal) => { if( signal ) { console.log(`worker was killed by signal: ${signal}`); } else if( code !== 0 ) { console.log(`worker exited with error code: ${code}`); } else { console.log('worker success!'); } }); ### Event: 'listening' * `address` {Object} Similar to the `cluster.on('listening')` event, but specific to this worker. cluster.fork().on('listening', (address) => { // Worker is listening }); It is not emitted in the worker. ### Event: 'message' * `message` {Object} Similar to the `cluster.on('message')` event, but specific to this worker. This event is the same as the one provided by [`child_process.fork()`][]. In a worker you can also use `process.on('message')`. As an example, here is a cluster that keeps count of the number of requests in the master process using the message system: const cluster = require('cluster'); const http = require('http'); if (cluster.isMaster) { // Keep track of http requests var numReqs = 0; setInterval(() => { console.log('numReqs =', numReqs); }, 1000); // Count requests function messageHandler(msg) { if (msg.cmd && msg.cmd == 'notifyRequest') { numReqs += 1; } } // Start workers and listen for messages containing notifyRequest const numCPUs = require('os').cpus().length; for (var i = 0; i < numCPUs; i++) { cluster.fork(); } Object.keys(cluster.workers).forEach((id) => { cluster.workers[id].on('message', messageHandler); }); } else { // Worker processes have a http server. http.Server((req, res) => { res.writeHead(200); res.end('hello world\n'); // notify master about the request process.send({ cmd: 'notifyRequest' }); }).listen(8000); } ### Event: 'online' Similar to the `cluster.on('online')` event, but specific to this worker. cluster.fork().on('online', () => { // Worker is online }); It is not emitted in the worker. ### worker.disconnect() In a worker, this function will close all servers, wait for the `'close'` event on those servers, and then disconnect the IPC channel. In the master, an internal message is sent to the worker causing it to call `.disconnect()` on itself. Causes `.suicide` to be set. Note that after a server is closed, it will no longer accept new connections, but connections may be accepted by any other listening worker. Existing connections will be allowed to close as usual. When no more connections exist, see [server.close()][], the IPC channel to the worker will close allowing it to die gracefully. The above applies *only* to server connections, client connections are not automatically closed by workers, and disconnect does not wait for them to close before exiting. Note that in a worker, `process.disconnect` exists, but it is not this function, it is [`disconnect`][]. Because long living server connections may block workers from disconnecting, it may be useful to send a message, so application specific actions may be taken to close them. It also may be useful to implement a timeout, killing a worker if the `'disconnect'` event has not been emitted after some time. if (cluster.isMaster) { var worker = cluster.fork(); var timeout; worker.on('listening', (address) => { worker.send('shutdown'); worker.disconnect(); timeout = setTimeout(() => { worker.kill(); }, 2000); }); worker.on('disconnect', () => { clearTimeout(timeout); }); } else if (cluster.isWorker) { const net = require('net'); var server = net.createServer((socket) => { // connections never end }); server.listen(8000); process.on('message', (msg) => { if(msg === 'shutdown') { // initiate graceful close of any connections to server } }); } ### worker.id * {Number} Each new worker is given its own unique id, this id is stored in the `id`. While a worker is alive, this is the key that indexes it in cluster.workers ### worker.isConnected() This function returns `true` if the worker is connected to its master via its IPC channel, `false` otherwise. A worker is connected to its master after it's been created. It is disconnected after the `'disconnect'` event is emitted. ### worker.isDead() This function returns `true` if the worker's process has terminated (either because of exiting or being signaled). Otherwise, it returns `false`. ### worker.kill([signal='SIGTERM']) * `signal` {String} Name of the kill signal to send to the worker process. This function will kill the worker. In the master, it does this by disconnecting the `worker.process`, and once disconnected, killing with `signal`. In the worker, it does it by disconnecting the channel, and then exiting with code `0`. Causes `.suicide` to be set. This method is aliased as `worker.destroy()` for backwards compatibility. Note that in a worker, `process.kill()` exists, but it is not this function, it is [`kill`][]. ### worker.process * {ChildProcess object} All workers are created using [`child_process.fork()`][], the returned object from this function is stored as `.process`. In a worker, the global `process` is stored. See: [Child Process module][] Note that workers will call `process.exit(0)` if the `'disconnect'` event occurs on `process` and `.suicide` is not `true`. This protects against accidental disconnection. ### worker.send(message[, sendHandle][, callback]) * `message` {Object} * `sendHandle` {Handle object} * `callback` {Function} * Return: Boolean Send a message to a worker or master, optionally with a handle. In the master this sends a message to a specific worker. It is identical to [`ChildProcess.send()`][]. In a worker this sends a message to the master. It is identical to `process.send()`. This example will echo back all messages from the master: if (cluster.isMaster) { var worker = cluster.fork(); worker.send('hi there'); } else if (cluster.isWorker) { process.on('message', (msg) => { process.send(msg); }); } ### worker.suicide * {Boolean} Set by calling `.kill()` or `.disconnect()`, until then it is `undefined`. The boolean `worker.suicide` lets you distinguish between voluntary and accidental exit, the master may choose not to respawn a worker based on this value. cluster.on('exit', (worker, code, signal) => { if (worker.suicide === true) { console.log('Oh, it was just suicide\' – no need to worry'). } }); // kill worker worker.kill(); ## Event: 'disconnect' * `worker` {Worker object} Emitted after the worker IPC channel has disconnected. This can occur when a worker exits gracefully, is killed, or is disconnected manually (such as with worker.disconnect()). There may be a delay between the `'disconnect'` and `'exit'` events. These events can be used to detect if the process is stuck in a cleanup or if there are long-living connections. cluster.on('disconnect', (worker) => { console.log(`The worker #${worker.id} has disconnected`); }); ## Event: 'exit' * `worker` {Worker object} * `code` {Number} the exit code, if it exited normally. * `signal` {String} the name of the signal (eg. `'SIGHUP'`) that caused the process to be killed. When any of the workers die the cluster module will emit the `'exit'` event. This can be used to restart the worker by calling `.fork()` again. cluster.on('exit', (worker, code, signal) => { console.log('worker %d died (%s). restarting...', worker.process.pid, signal || code); cluster.fork(); }); See [child_process event: 'exit'][]. ## Event: 'fork' * `worker` {Worker object} When a new worker is forked the cluster module will emit a `'fork'` event. This can be used to log worker activity, and create your own timeout. var timeouts = []; function errorMsg() { console.error('Something must be wrong with the connection ...'); } cluster.on('fork', (worker) => { timeouts[worker.id] = setTimeout(errorMsg, 2000); }); cluster.on('listening', (worker, address) => { clearTimeout(timeouts[worker.id]); }); cluster.on('exit', (worker, code, signal) => { clearTimeout(timeouts[worker.id]); errorMsg(); }); ## Event: 'listening' * `worker` {Worker object} * `address` {Object} After calling `listen()` from a worker, when the `'listening'` event is emitted on the server, a `'listening'` event will also be emitted on `cluster` in the master. The event handler is executed with two arguments, the `worker` contains the worker object and the `address` object contains the following connection properties: `address`, `port` and `addressType`. This is very useful if the worker is listening on more than one address. cluster.on('listening', (worker, address) => { console.log( `A worker is now connected to ${address.address}:${address.port}`); }); The `addressType` is one of: * `4` (TCPv4) * `6` (TCPv6) * `-1` (unix domain socket) * `"udp4"` or `"udp6"` (UDP v4 or v6) ## Event: 'message' * `worker` {Worker object} * `message` {Object} Emitted when any worker receives a message. See [child_process event: 'message'][]. ## Event: 'online' * `worker` {Worker object} After forking a new worker, the worker should respond with an online message. When the master receives an online message it will emit this event. The difference between `'fork'` and `'online'` is that fork is emitted when the master forks a worker, and 'online' is emitted when the worker is running. cluster.on('online', (worker) => { console.log('Yay, the worker responded after it was forked'); }); ## Event: 'setup' * `settings` {Object} Emitted every time `.setupMaster()` is called. The `settings` object is the `cluster.settings` object at the time `.setupMaster()` was called and is advisory only, since multiple calls to `.setupMaster()` can be made in a single tick. If accuracy is important, use `cluster.settings`. ## cluster.disconnect([callback]) * `callback` {Function} called when all workers are disconnected and handles are closed Calls `.disconnect()` on each worker in `cluster.workers`. When they are disconnected all internal handles will be closed, allowing the master process to die gracefully if no other event is waiting. The method takes an optional callback argument which will be called when finished. This can only be called from the master process. ## cluster.fork([env]) * `env` {Object} Key/value pairs to add to worker process environment. * return {Worker object} Spawn a new worker process. This can only be called from the master process. ## cluster.isMaster * {Boolean} True if the process is a master. This is determined by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID` is undefined, then `isMaster` is `true`. ## cluster.isWorker * {Boolean} True if the process is not a master (it is the negation of `cluster.isMaster`). ## cluster.schedulingPolicy The scheduling policy, either `cluster.SCHED_RR` for round-robin or `cluster.SCHED_NONE` to leave it to the operating system. This is a global setting and effectively frozen once you spawn the first worker or call `cluster.setupMaster()`, whatever comes first. `SCHED_RR` is the default on all operating systems except Windows. Windows will change to `SCHED_RR` once libuv is able to effectively distribute IOCP handles without incurring a large performance hit. `cluster.schedulingPolicy` can also be set through the `NODE_CLUSTER_SCHED_POLICY` environment variable. Valid values are `"rr"` and `"none"`. ## cluster.settings * {Object} * `execArgv` {Array} list of string arguments passed to the Node.js executable. (Default=`process.execArgv`) * `exec` {String} file path to worker file. (Default=`process.argv[1]`) * `args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) * `silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) After calling `.setupMaster()` (or `.fork()`) this settings object will contain the settings, including the default values. It is effectively frozen after being set, because `.setupMaster()` can only be called once. This object is not supposed to be changed or set manually, by you. ## cluster.setupMaster([settings]) * `settings` {Object} * `exec` {String} file path to worker file. (Default=`process.argv[1]`) * `args` {Array} string arguments passed to worker. (Default=`process.argv.slice(2)`) * `silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) `setupMaster` is used to change the default 'fork' behavior. Once called, the settings will be present in `cluster.settings`. Note that: * any settings changes only affect future calls to `.fork()` and have no effect on workers that are already running * The *only* attribute of a worker that cannot be set via `.setupMaster()` is the `env` passed to `.fork()` * the defaults above apply to the first call only, the defaults for later calls is the current value at the time of `cluster.setupMaster()` is called Example: const cluster = require('cluster'); cluster.setupMaster({ exec: 'worker.js', args: ['--use', 'https'], silent: true }); cluster.fork(); // https worker cluster.setupMaster({ args: ['--use', 'http'] }); cluster.fork(); // http worker This can only be called from the master process. ## cluster.worker * {Object} A reference to the current worker object. Not available in the master process. const cluster = require('cluster'); if (cluster.isMaster) { console.log('I am master'); cluster.fork(); cluster.fork(); } else if (cluster.isWorker) { console.log(`I am worker #${cluster.worker.id}`); } ## cluster.workers * {Object} A hash that stores the active worker objects, keyed by `id` field. Makes it easy to loop through all the workers. It is only available in the master process. A worker is removed from cluster.workers after the worker has disconnected _and_ exited. The order between these two events cannot be determined in advance. However, it is guaranteed that the removal from the cluster.workers list happens before last `'disconnect'` or `'exit'` event is emitted. // Go through all workers function eachWorker(callback) { for (var id in cluster.workers) { callback(cluster.workers[id]); } } eachWorker((worker) => { worker.send('big announcement to all workers'); }); Should you wish to reference a worker over a communication channel, using the worker's unique id is the easiest way to find the worker. socket.on('data', (id) => { var worker = cluster.workers[id]; }); [`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options [`ChildProcess.send()`]: child_process.html#child_process_child_send_message_sendhandle_callback [`disconnect`]: child_process.html#child_process_child_disconnect [`kill`]: process.html#process_process_kill_pid_signal [`server.close()`]: net.html#net_event_close [Child Process module]: child_process.html#child_process_child_process_fork_modulepath_args_options [child_process event: 'exit']: child_process.html#child_process_event_exit [child_process event: 'message']: child_process.html#child_process_event_message node-v4.2.6/doc/api/console.html000644 000766 000024 00000036623 12650222331 016622 0ustar00iojsstaff000000 000000 Console Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Console#

Stability: 2 - Stable

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to stdout and stderr. Because this object is global, it can be used without calling require('console').

Example using the global console:

console.log('hello world');
  // Prints: hello world, to stdout
console.log('hello %s', 'world');
  // Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
  // Prints: [Error: Whoops, something bad happened], to stderr

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
  // Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
  // Prints: hello world, to out
myConsole.log('hello %s', 'world');
  // Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
  // Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
  // Prints: Danger Will Robinson! Danger!, to err

While the API for the Console class is designed fundamentally around the Web browser console object, the Console is Node.js is not intended to duplicate the browsers functionality exactly.

Asynchronous vs Synchronous Consoles#

The console functions are synchronous when the destination is a terminal or a file (to avoid lost messages in case of premature exit) and asynchronous when the destination is a pipe (to avoid blocking for long periods of time).

In the following example, stdout is non-blocking while stderr is blocking:

$ node script.js 2> error.log | tee info.log

Typically, the distinction between blocking/non-blocking is not important unless an application is logging significant amounts of data. High volume logging should use a Console instance that writes to a pipe.

Class: Console#

The Console class can be used to create a simple logger with configurable output streams and can be accessed using either require('console').Console or console.Console:

const Console = require('console').Console;
const Console = console.Console;

new Console(stdout[, stderr])#

Creates a new Console by passing one or two writable stream instances. stdout is a writable stream to print log or info output. stderr is used for warning or error output. If stderr isn't passed, the warning and error output will be sent to the stdout.

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
var count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5

The global console is a special Console whose output is sent to process.stdout and process.stderr. It is equivalent to calling:

new Console(process.stdout, process.stderr);

console.assert(value[, message][, ...])#

A simple assertion test that verifies whether value is truthy. If it is not, an AssertionError is throw. If provided, the error message is formatted using util.format() and used as the error message.

console.assert(true, 'does nothing');
  // OK
console.assert(false, 'Whoops %s', 'didn\'t work');
  // AssertionError: Whoops didn't work

console.dir(obj[, options])#

Uses util.inspect() on obj and prints the resulting string to stdout. This function bypasses any custom inspect() function defined on obj. An optional options object may be passed that alters certain aspects of the formatted string:

  • showHidden - if true then the object's non-enumerable and symbol properties will be shown too. Defaults to false.

  • depth - tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely, pass null.

  • colors - if true, then the output will be styled with ANSI color codes. Defaults to false. Colors are customizable; see [customizing util.inspect() colors][].

console.error([data][, ...])#

Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf() (the arguments are all passed to util.format()).

const code = 5;
console.error('error #%d', code);
  // Prints: error #5, to stderr
console.error('error', code);
  // Prints: error 5, to stderr

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

console.info([data][, ...])#

The console.info() function is an alias for console.log().

console.log([data][, ...])#

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf() (the arguments are all passed to util.format()).

var count = 5;
console.log('count: %d', count);
  // Prints: count: 5, to stdout
console.log('count: ', count);
  // Prints: count: 5, to stdout

If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.

console.time(label)#

Used to calculate the duration of a specific operation. To start a timer, call the console.time() method, giving it a unique label as the only parameter. To stop the timer, and to get the elapsed time in milliseconds, just call the console.timeEnd() method, again passing the timer's unique label as the parameter.

console.timeEnd(label)#

Stops a timer that was previously started by calling console.time() and prints the result to stdout:

console.time('100-elements');
for (var i = 0; i < 100; i++) {
  ;
}
console.timeEnd('100-elements');
// prints 100-elements: 262ms

console.trace(message[, ...])#

Prints to stderr the string 'Trace :', followed by the util.format() formatted message and stack trace to the current position in the code.

console.trace('Show me');
  // Prints: (stack trace will vary based on where trace is called)
  //  Trace: Show me
  //    at repl:2:9
  //    at REPLServer.defaultEval (repl.js:248:27)
  //    at bound (domain.js:287:14)
  //    at REPLServer.runBound [as eval] (domain.js:300:12)
  //    at REPLServer.<anonymous> (repl.js:412:12)
  //    at emitOne (events.js:82:20)
  //    at REPLServer.emit (events.js:169:7)
  //    at REPLServer.Interface._onLine (readline.js:210:10)
  //    at REPLServer.Interface._line (readline.js:549:8)
  //    at REPLServer.Interface._ttyWrite (readline.js:826:14)

console.warn([data][, ...])#

The console.warn() function is an alias for console.error().

node-v4.2.6/doc/api/console.json000644 000766 000024 00000033747 12650222331 016633 0ustar00iojsstaff000000 000000 { "source": "doc/api/console.markdown", "modules": [ { "textRaw": "Console", "name": "console", "stability": 2, "stabilityText": "Stable", "desc": "

The console module provides a simple debugging console that is similar to the\nJavaScript console mechanism provided by web browsers.\n\n

\n

The module exports two specific components:\n\n

\n
    \n
  • A Console class with methods such as console.log(), console.error() and\nconsole.warn() that can be used to write to any Node.js stream.
  • \n
  • A global console instance configured to write to stdout and stderr.\nBecause this object is global, it can be used without calling\nrequire('console').
  • \n
\n

Example using the global console:\n\n

\n
console.log('hello world');\n  // Prints: hello world, to stdout\nconsole.log('hello %s', 'world');\n  // Prints: hello world, to stdout\nconsole.error(new Error('Whoops, something bad happened'));\n  // Prints: [Error: Whoops, something bad happened], to stderr\n\nconst name = 'Will Robinson';\nconsole.warn(`Danger ${name}! Danger!`);\n  // Prints: Danger Will Robinson! Danger!, to stderr
\n

Example using the Console class:\n\n

\n
const out = getStreamSomehow();\nconst err = getStreamSomehow();\nconst myConsole = new console.Console(out, err);\n\nmyConsole.log('hello world');\n  // Prints: hello world, to out\nmyConsole.log('hello %s', 'world');\n  // Prints: hello world, to out\nmyConsole.error(new Error('Whoops, something bad happened'));\n  // Prints: [Error: Whoops, something bad happened], to err\n\nconst name = 'Will Robinson';\nmyConsole.warn(`Danger ${name}! Danger!`);\n  // Prints: Danger Will Robinson! Danger!, to err
\n

While the API for the Console class is designed fundamentally around the\nWeb browser console object, the Console is Node.js is not intended to\nduplicate the browsers functionality exactly.\n\n

\n", "modules": [ { "textRaw": "Asynchronous vs Synchronous Consoles", "name": "asynchronous_vs_synchronous_consoles", "desc": "

The console functions are synchronous when the destination is a terminal or\na file (to avoid lost messages in case of premature exit) and asynchronous\nwhen the destination is a pipe (to avoid blocking for long periods of time).\n\n

\n

In the following example, stdout is non-blocking while stderr is blocking:\n\n

\n
$ node script.js 2> error.log | tee info.log
\n

Typically, the distinction between blocking/non-blocking is not important\nunless an application is logging significant amounts of data. High volume\nlogging should use a Console instance that writes to a pipe.\n\n

\n", "type": "module", "displayName": "Asynchronous vs Synchronous Consoles" } ], "classes": [ { "textRaw": "Class: Console", "type": "class", "name": "Console", "desc": "

The Console class can be used to create a simple logger with configurable\noutput streams and can be accessed using either require('console').Console\nor console.Console:\n\n

\n
const Console = require('console').Console;\nconst Console = console.Console;
\n", "methods": [ { "textRaw": "console.assert(value[, message][, ...])", "type": "method", "name": "assert", "desc": "

A simple assertion test that verifies whether value is truthy. If it is not,\nan AssertionError is throw. If provided, the error message is formatted\nusing [util.format()][] and used as the error message.\n\n

\n
console.assert(true, 'does nothing');\n  // OK\nconsole.assert(false, 'Whoops %s', 'didn\\'t work');\n  // AssertionError: Whoops didn't work
\n", "signatures": [ { "params": [ { "name": "value" }, { "name": "message", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.dir(obj[, options])", "type": "method", "name": "dir", "desc": "

Uses [util.inspect()][] on obj and prints the resulting string to stdout.\nThis function bypasses any custom inspect() function defined on obj. An\noptional options object may be passed that alters certain aspects of the\nformatted string:\n\n

\n
    \n
  • showHidden - if true then the object's non-enumerable and symbol\nproperties will be shown too. Defaults to false.

    \n
  • \n
  • depth - tells inspect how many times to recurse while formatting the\nobject. This is useful for inspecting large complicated objects. Defaults to\n2. To make it recurse indefinitely, pass null.

    \n
  • \n
  • colors - if true, then the output will be styled with ANSI color codes.\nDefaults to false. Colors are customizable; see\n[customizing util.inspect() colors][].

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "obj" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "console.error([data][, ...])", "type": "method", "name": "error", "desc": "

Prints to stderr with newline. Multiple arguments can be passed, with the first\nused as the primary message and all additional used as substitution\nvalues similar to printf() (the arguments are all passed to\n[util.format()][]).\n\n

\n
const code = 5;\nconsole.error('error #%d', code);\n  // Prints: error #5, to stderr\nconsole.error('error', code);\n  // Prints: error 5, to stderr
\n

If formatting elements (e.g. %d) are not found in the first string then\n[util.inspect()][] is called on each argument and the resulting string\nvalues are concatenated. See [util.format()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.info([data][, ...])", "type": "method", "name": "info", "desc": "

The console.info() function is an alias for [console.log()][].\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.log([data][, ...])", "type": "method", "name": "log", "desc": "

Prints to stdout with newline. Multiple arguments can be passed, with the first\nused as the primary message and all additional used as substitution\nvalues similar to printf() (the arguments are all passed to\n[util.format()][]).\n\n

\n
var count = 5;\nconsole.log('count: %d', count);\n  // Prints: count: 5, to stdout\nconsole.log('count: ', count);\n  // Prints: count: 5, to stdout
\n

If formatting elements (e.g. %d) are not found in the first string then\n[util.inspect()][] is called on each argument and the resulting string\nvalues are concatenated. See [util.format()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.time(label)", "type": "method", "name": "time", "desc": "

Used to calculate the duration of a specific operation. To start a timer, call\nthe console.time() method, giving it a unique label as the only parameter. To stop the\ntimer, and to get the elapsed time in milliseconds, just call the\n[console.timeEnd()][] method, again passing the\ntimer's unique label as the parameter.\n\n

\n", "signatures": [ { "params": [ { "name": "label" } ] } ] }, { "textRaw": "console.timeEnd(label)", "type": "method", "name": "timeEnd", "desc": "

Stops a timer that was previously started by calling [console.time()][] and\nprints the result to stdout:\n\n

\n
console.time('100-elements');\nfor (var i = 0; i < 100; i++) {\n  ;\n}\nconsole.timeEnd('100-elements');\n// prints 100-elements: 262ms
\n", "signatures": [ { "params": [ { "name": "label" } ] } ] }, { "textRaw": "console.trace(message[, ...])", "type": "method", "name": "trace", "desc": "

Prints to stderr the string 'Trace :', followed by the [util.format()][]\nformatted message and stack trace to the current position in the code.\n\n

\n
console.trace('Show me');\n  // Prints: (stack trace will vary based on where trace is called)\n  //  Trace: Show me\n  //    at repl:2:9\n  //    at REPLServer.defaultEval (repl.js:248:27)\n  //    at bound (domain.js:287:14)\n  //    at REPLServer.runBound [as eval] (domain.js:300:12)\n  //    at REPLServer.<anonymous> (repl.js:412:12)\n  //    at emitOne (events.js:82:20)\n  //    at REPLServer.emit (events.js:169:7)\n  //    at REPLServer.Interface._onLine (readline.js:210:10)\n  //    at REPLServer.Interface._line (readline.js:549:8)\n  //    at REPLServer.Interface._ttyWrite (readline.js:826:14)
\n", "signatures": [ { "params": [ { "name": "message" }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "console.warn([data][, ...])", "type": "method", "name": "warn", "desc": "

The console.warn() function is an alias for [console.error()][].\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "...", "optional": true } ] } ] } ], "signatures": [ { "params": [ { "name": "stdout" }, { "name": "stderr", "optional": true } ], "desc": "

Creates a new Console by passing one or two writable stream instances.\nstdout is a writable stream to print log or info output. stderr\nis used for warning or error output. If stderr isn't passed, the warning\nand error output will be sent to the stdout.\n\n

\n
const output = fs.createWriteStream('./stdout.log');\nconst errorOutput = fs.createWriteStream('./stderr.log');\n// custom simple logger\nconst logger = new Console(output, errorOutput);\n// use it like console\nvar count = 5;\nlogger.log('count: %d', count);\n// in stdout.log: count 5
\n

The global console is a special Console whose output is sent to\nprocess.stdout and process.stderr. It is equivalent to calling:\n\n

\n
new Console(process.stdout, process.stderr);
\n" } ] } ], "type": "module", "displayName": "Console" } ] } node-v4.2.6/doc/api/console.markdown000644 000766 000024 00000017436 12650222326 017505 0ustar00iojsstaff000000 000000 # Console Stability: 2 - Stable The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to `stdout` and `stderr`. Because this object is global, it can be used without calling `require('console')`. Example using the global `console`: console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to stderr const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr Example using the `Console` class: const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err While the API for the `Console` class is designed fundamentally around the Web browser `console` object, the `Console` is Node.js is *not* intended to duplicate the browsers functionality exactly. ## Asynchronous vs Synchronous Consoles The console functions are synchronous when the destination is a terminal or a file (to avoid lost messages in case of premature exit) and asynchronous when the destination is a pipe (to avoid blocking for long periods of time). In the following example, stdout is non-blocking while stderr is blocking: $ node script.js 2> error.log | tee info.log Typically, the distinction between blocking/non-blocking is not important unless an application is logging significant amounts of data. High volume logging *should* use a `Console` instance that writes to a pipe. ## Class: Console The `Console` class can be used to create a simple logger with configurable output streams and can be accessed using either `require('console').Console` or `console.Console`: const Console = require('console').Console; const Console = console.Console; ### new Console(stdout[, stderr]) Creates a new `Console` by passing one or two writable stream instances. `stdout` is a writable stream to print log or info output. `stderr` is used for warning or error output. If `stderr` isn't passed, the warning and error output will be sent to the `stdout`. const output = fs.createWriteStream('./stdout.log'); const errorOutput = fs.createWriteStream('./stderr.log'); // custom simple logger const logger = new Console(output, errorOutput); // use it like console var count = 5; logger.log('count: %d', count); // in stdout.log: count 5 The global `console` is a special `Console` whose output is sent to `process.stdout` and `process.stderr`. It is equivalent to calling: new Console(process.stdout, process.stderr); ### console.assert(value[, message][, ...]) A simple assertion test that verifies whether `value` is truthy. If it is not, an `AssertionError` is throw. If provided, the error `message` is formatted using [`util.format()`][] and used as the error message. console.assert(true, 'does nothing'); // OK console.assert(false, 'Whoops %s', 'didn\'t work'); // AssertionError: Whoops didn't work ### console.dir(obj[, options]) Uses [`util.inspect()`][] on `obj` and prints the resulting string to stdout. This function bypasses any custom `inspect()` function defined on `obj`. An optional `options` object may be passed that alters certain aspects of the formatted string: - `showHidden` - if `true` then the object's non-enumerable and symbol properties will be shown too. Defaults to `false`. - `depth` - tells `inspect` how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to `2`. To make it recurse indefinitely, pass `null`. - `colors` - if `true`, then the output will be styled with ANSI color codes. Defaults to `false`. Colors are customizable; see [customizing `util.inspect()` colors][]. ### console.error([data][, ...]) Prints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to `printf()` (the arguments are all passed to [`util.format()`][]). const code = 5; console.error('error #%d', code); // Prints: error #5, to stderr console.error('error', code); // Prints: error 5, to stderr If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`][] is called on each argument and the resulting string values are concatenated. See [`util.format()`][] for more information. ### console.info([data][, ...]) The `console.info()` function is an alias for [`console.log()`][]. ### console.log([data][, ...]) Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to `printf()` (the arguments are all passed to [`util.format()`][]). var count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count: ', count); // Prints: count: 5, to stdout If formatting elements (e.g. `%d`) are not found in the first string then [`util.inspect()`][] is called on each argument and the resulting string values are concatenated. See [`util.format()`][] for more information. ### console.time(label) Used to calculate the duration of a specific operation. To start a timer, call the `console.time()` method, giving it a unique `label` as the only parameter. To stop the timer, and to get the elapsed time in milliseconds, just call the [`console.timeEnd()`][] method, again passing the timer's unique `label` as the parameter. ### console.timeEnd(label) Stops a timer that was previously started by calling [`console.time()`][] and prints the result to stdout: console.time('100-elements'); for (var i = 0; i < 100; i++) { ; } console.timeEnd('100-elements'); // prints 100-elements: 262ms ### console.trace(message[, ...]) Prints to stderr the string `'Trace :'`, followed by the [`util.format()`][] formatted message and stack trace to the current position in the code. console.trace('Show me'); // Prints: (stack trace will vary based on where trace is called) // Trace: Show me // at repl:2:9 // at REPLServer.defaultEval (repl.js:248:27) // at bound (domain.js:287:14) // at REPLServer.runBound [as eval] (domain.js:300:12) // at REPLServer. (repl.js:412:12) // at emitOne (events.js:82:20) // at REPLServer.emit (events.js:169:7) // at REPLServer.Interface._onLine (readline.js:210:10) // at REPLServer.Interface._line (readline.js:549:8) // at REPLServer.Interface._ttyWrite (readline.js:826:14) ### console.warn([data][, ...]) The `console.warn()` function is an alias for [`console.error()`][]. [`console.error()`]: #console_console_error_data [`console.log()`]: #console_console_log_data [`console.time()`]: #console_console_time_label [`console.timeEnd()`]: #console_console_timeend_label [`util.format()`]: util.html#util_util_format_format [`util.inspect()`]: util.html#util_util_inspect_object_options node-v4.2.6/doc/api/crypto.html000644 000766 000024 00000155640 12650222331 016501 0ustar00iojsstaff000000 000000 Crypto Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

Crypto#

Stability: 2 - Stable

Use require('crypto') to access this module.

The crypto module offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection.

It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.

Class: Certificate#

The class used for working with signed public key & challenges. The most common usage for this series of functions is when dealing with the <keygen> element. https://www.openssl.org/docs/apps/spkac.html

Returned by crypto.Certificate.

Certificate.exportChallenge(spkac)#

Exports the encoded challenge associated with the SPKAC.

Certificate.exportPublicKey(spkac)#

Exports the encoded public key from the supplied SPKAC.

Certificate.verifySpkac(spkac)#

Returns true of false based on the validity of the SPKAC.

Class: Cipher#

Class for encrypting data.

Returned by crypto.createCipher and crypto.createCipheriv.

Cipher objects are streams that are both readable and writable. The written plain text data is used to produce the encrypted data on the readable side. The legacy update and final methods are also supported.

cipher.final([output_encoding])#

Returns any remaining enciphered contents, with output_encoding being one of: 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is returned.

Note: cipher object can not be used after final() method has been called.

cipher.getAuthTag()#

For authenticated encryption modes (currently supported: GCM), this method returns a Buffer that represents the authentication tag that has been computed from the given data. Should be called after encryption has been completed using the final method!

cipher.setAAD(buffer)#

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

cipher.setAutoPadding(auto_padding=true)#

You can disable automatic padding of the input data to block size. If auto_padding is false, the length of the entire input data must be a multiple of the cipher's block size or final will fail. Useful for non-standard padding, e.g. using 0x0 instead of PKCS padding. You must call this before cipher.final.

cipher.update(data[, input_encoding][, output_encoding])#

Updates the cipher with data, the encoding of which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'. If no encoding is provided, then a buffer is expected. If data is a Buffer then input_encoding is ignored.

The output_encoding specifies the output format of the enciphered data, and can be 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is returned.

Returns the enciphered contents, and can be called many times with new data as it is streamed.

Class: Decipher#

Class for decrypting data.

Returned by crypto.createDecipher and crypto.createDecipheriv.

Decipher objects are streams that are both readable and writable. The written enciphered data is used to produce the plain-text data on the the readable side. The legacy update and final methods are also supported.

decipher.final([output_encoding])#

Returns any remaining plaintext which is deciphered, with output_encoding being one of: 'binary', 'ascii' or 'utf8'. If no encoding is provided, then a buffer is returned.

Note: decipher object can not be used after final() method has been called.

decipher.setAAD(buffer)#

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

decipher.setAuthTag(buffer)#

For authenticated encryption modes (currently supported: GCM), this method must be used to pass in the received authentication tag. If no tag is provided or if the ciphertext has been tampered with, final will throw, thus indicating that the ciphertext should be discarded due to failed authentication.

decipher.setAutoPadding(auto_padding=true)#

You can disable auto padding if the data has been encrypted without standard block padding to prevent decipher.final from checking and removing it. This will only work if the input data's length is a multiple of the ciphers block size. You must call this before streaming data to decipher.update.

decipher.update(data[, input_encoding][, output_encoding])#

Updates the decipher with data, which is encoded in 'binary', 'base64' or 'hex'. If no encoding is provided, then a buffer is expected. If data is a Buffer then input_encoding is ignored.

The output_decoding specifies in what format to return the deciphered plaintext: 'binary', 'ascii' or 'utf8'. If no encoding is provided, then a buffer is returned.

Class: DiffieHellman#

The class for creating Diffie-Hellman key exchanges.

Returned by crypto.createDiffieHellman.

diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])#

Computes the shared secret using other_public_key as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified input_encoding, and secret is encoded using specified output_encoding. Encodings can be 'binary', 'hex', or 'base64'. If the input encoding is not provided, then a buffer is expected.

If no output encoding is given, then a buffer is returned.

diffieHellman.generateKeys([encoding])#

Generates private and public Diffie-Hellman key values, and returns the public key in the specified encoding. This key should be transferred to the other party. Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getGenerator([encoding])#

Returns the Diffie-Hellman generator in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPrime([encoding])#

Returns the Diffie-Hellman prime in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPrivateKey([encoding])#

Returns the Diffie-Hellman private key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.getPublicKey([encoding])#

Returns the Diffie-Hellman public key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

diffieHellman.setPrivateKey(private_key[, encoding])#

Sets the Diffie-Hellman private key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

diffieHellman.setPublicKey(public_key[, encoding])#

Sets the Diffie-Hellman public key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

diffieHellman.verifyError#

A bit field containing any warnings and/or errors as a result of a check performed during initialization. The following values are valid for this property (defined in constants module):

  • DH_CHECK_P_NOT_SAFE_PRIME
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

Class: ECDH#

The class for creating EC Diffie-Hellman key exchanges.

Returned by crypto.createECDH.

ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding])#

Computes the shared secret using other_public_key as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified input_encoding, and secret is encoded using specified output_encoding. Encodings can be 'binary', 'hex', or 'base64'. If the input encoding is not provided, then a buffer is expected.

If no output encoding is given, then a buffer is returned.

ECDH.generateKeys([encoding[, format]])#

Generates private and public EC Diffie-Hellman key values, and returns the public key in the specified format and encoding. This key should be transferred to the other party.

Format specifies point encoding and can be 'compressed', 'uncompressed', or 'hybrid'. If no format is provided - the point will be returned in 'uncompressed' format.

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.getPrivateKey([encoding])#

Returns the EC Diffie-Hellman private key in the specified encoding, which can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.getPublicKey([encoding[, format]])#

Returns the EC Diffie-Hellman public key in the specified encoding and format.

Format specifies point encoding and can be 'compressed', 'uncompressed', or 'hybrid'. If no format is provided - the point will be returned in 'uncompressed' format.

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided, then a buffer is returned.

ECDH.setPrivateKey(private_key[, encoding])#

Sets the EC Diffie-Hellman private key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

Example (obtaining a shared secret):

const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');

alice.generateKeys();
bob.generateKeys();

const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);

ECDH.setPublicKey(public_key[, encoding])#

Sets the EC Diffie-Hellman public key. Key encoding can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is expected.

Class: Hash#

The class for creating hash digests of data.

It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the computed hash digest. The legacy update and digest methods are also supported.

Returned by crypto.createHash.

hash.digest([encoding])#

Calculates the digest of all of the passed data to be hashed. The encoding can be 'hex', 'binary' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: hash object can not be used after digest() method has been called.

hash.update(data[, input_encoding])#

Updates the hash content with the given data, the encoding of which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'. If no encoding is provided, and the input is a string, an encoding of 'binary' is enforced. If data is a Buffer then input_encoding is ignored.

This can be called many times with new data as it is streamed.

Class: Hmac#

Class for creating cryptographic hmac content.

Returned by crypto.createHmac.

hmac.digest([encoding])#

Calculates the digest of all of the passed data to the hmac. The encoding can be 'hex', 'binary' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: hmac object can not be used after digest() method has been called.

hmac.update(data)#

Update the hmac content with the given data. This can be called many times with new data as it is streamed.

Class: Sign#

Class for generating signatures.

Returned by crypto.createSign.

Sign objects are writable streams. The written data is used to generate the signature. Once all of the data has been written, the sign method will return the signature. The legacy update method is also supported.

sign.sign(private_key[, output_format])#

Calculates the signature on all the updated data passed through the sign.

private_key can be an object or a string. If private_key is a string, it is treated as the key with no passphrase.

private_key:

  • key : A string holding the PEM encoded private key
  • passphrase : A string of passphrase for the private key

Returns the signature in output_format which can be 'binary', 'hex' or 'base64'. If no encoding is provided, then a buffer is returned.

Note: sign object can not be used after sign() method has been called.

sign.update(data)#

Updates the sign object with data. This can be called many times with new data as it is streamed.

Class: Verify#

Class for verifying signatures.

Returned by crypto.createVerify.

Verify objects are writable streams. The written data is used to validate against the supplied signature. Once all of the data has been written, the verify method will return true if the supplied signature is valid. The legacy update method is also supported.

verifier.update(data)#

Updates the verifier object with data. This can be called many times with new data as it is streamed.

verifier.verify(object, signature[, signature_format])#

Verifies the signed data by using the object and signature. object is a string containing a PEM encoded object, which can be one of RSA public key, DSA public key, or X.509 certificate. signature is the previously calculated signature for the data, in the signature_format which can be 'binary', 'hex' or 'base64'. If no encoding is specified, then a buffer is expected.

Returns true or false depending on the validity of the signature for the data and public key.

Note: verifier object can not be used after verify() method has been called.

crypto.DEFAULT_ENCODING#

The default encoding to use for functions that can take either strings or buffers. The default value is 'buffer', which makes it default to using Buffer objects. This is here to make the crypto module more easily compatible with legacy programs that expected 'binary' to be the default encoding.

Note that new programs will probably expect buffers, so only use this as a temporary measure.

crypto.createCipher(algorithm, password)#

Creates and returns a cipher object, with the given algorithm and password.

algorithm is dependent on OpenSSL, examples are 'aes192', etc. On recent releases, openssl list-cipher-algorithms will display the available cipher algorithms. password is used to derive key and IV, which must be a 'binary' encoded string or a buffer.

It is a stream that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the read() method to get the enciphered contents. The legacy update and final methods are also supported.

Note: createCipher derives keys with the OpenSSL function EVP_BytesToKey with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same password always creates the same key. The low iteration count and non-cryptographically secure hash algorithm allow passwords to be tested very rapidly.

In line with OpenSSL's recommendation to use pbkdf2 instead of EVP_BytesToKey it is recommended you derive a key and iv yourself with crypto.pbkdf2 and to then use createCipheriv() to create the cipher stream.

crypto.createCipheriv(algorithm, key, iv)#

Creates and returns a cipher object, with the given algorithm, key and iv.

algorithm is the same as the argument to createCipher(). key is the raw key used by the algorithm. iv is an initialization vector.

key and iv must be 'binary' encoded strings or buffers.

crypto.createCredentials(details)#

Stability: 0 - Deprecated: Use tls.createSecureContext instead.

Creates a credentials object, with the optional details being a dictionary with keys:

  • pfx : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
  • key : A string holding the PEM encoded private key
  • passphrase : A string of passphrase for the private key or pfx
  • cert : A string holding the PEM encoded certificate
  • ca : Either a string or list of strings of PEM encoded CA certificates to trust.
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.

If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.

crypto.createDecipher(algorithm, password)#

Creates and returns a decipher object, with the given algorithm and key. This is the mirror of the createCipher() above.

crypto.createDecipheriv(algorithm, key, iv)#

Creates and returns a decipher object, with the given algorithm, key and iv. This is the mirror of the createCipheriv() above.

crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])#

Creates a Diffie-Hellman key exchange object using the supplied prime and an optional specific generator. generator can be a number, string, or Buffer. If no generator is specified, then 2 is used. prime_encoding and generator_encoding can be 'binary', 'hex', or 'base64'. If no prime_encoding is specified, then a Buffer is expected for prime. If no generator_encoding is specified, then a Buffer is expected for generator.

crypto.createDiffieHellman(prime_length[, generator])#

Creates a Diffie-Hellman key exchange object and generates a prime of prime_length bits and using an optional specific numeric generator. If no generator is specified, then 2 is used.

crypto.createECDH(curve_name)#

Creates an Elliptic Curve (EC) Diffie-Hellman key exchange object using a predefined curve specified by the curve_name string. Use getCurves() to obtain a list of available curve names. On recent releases, openssl ecparam -list_curves will also display the name and description of each available elliptic curve.

crypto.createHash(algorithm)#

Creates and returns a hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests.

algorithm is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are 'sha256', 'sha512', etc. On recent releases, openssl list-message-digest-algorithms will display the available digest algorithms.

Example: this program that takes the sha256 sum of a file

const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');

const shasum = crypto.createHash('sha256');

const s = fs.ReadStream(filename);
s.on('data', (d) => {
  shasum.update(d);
});

s.on('end', () => {
  var d = shasum.digest('hex');
  console.log(`${d}  ${filename}`);
});

crypto.createHmac(algorithm, key)#

Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key.

It is a stream that is both readable and writable. The written data is used to compute the hmac. Once the writable side of the stream is ended, use the read() method to get the computed digest. The legacy update and digest methods are also supported.

algorithm is dependent on the available algorithms supported by OpenSSL - see createHash above. key is the hmac key to be used.

crypto.createSign(algorithm)#

Creates and returns a signing object, with the given algorithm. On recent OpenSSL releases, openssl list-public-key-algorithms will display the available signing algorithms. Examples are 'RSA-SHA256'.

crypto.createVerify(algorithm)#

Creates and returns a verification object, with the given algorithm. This is the mirror of the signing object above.

crypto.getCiphers()#

Returns an array with the names of the supported ciphers.

Example:

const ciphers = crypto.getCiphers();
console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]

crypto.getCurves()#

Returns an array with the names of the supported elliptic curves.

Example:

const curves = crypto.getCurves();
console.log(curves); // ['secp256k1', 'secp384r1', ...]

crypto.getDiffieHellman(group_name)#

Creates a predefined Diffie-Hellman key exchange object. The supported groups are: 'modp1', 'modp2', 'modp5' (defined in RFC 2412, but see Caveats) and 'modp14', 'modp15', 'modp16', 'modp17', 'modp18' (defined in RFC 3526). The returned object mimics the interface of objects created by crypto.createDiffieHellman() above, but will not allow changing the keys (with diffieHellman.setPublicKey() for example). The advantage of using this routine is that the parties do not have to generate nor exchange group modulus beforehand, saving both processor and communication time.

Example (obtaining a shared secret):

const crypto = require('crypto');
const alice = crypto.getDiffieHellman('modp14');
const bob = crypto.getDiffieHellman('modp14');

alice.generateKeys();
bob.generateKeys();

const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');

/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);

crypto.getHashes()#

Returns an array with the names of the supported hash algorithms.

Example:

const hashes = crypto.getHashes();
console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]

crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)#

Asynchronous PBKDF2 function. Applies the selected HMAC digest function (default: SHA1) to derive a key of the requested byte length from the password, salt and number of iterations. The callback gets two arguments: (err, derivedKey).

The number of iterations passed to pbkdf2 should be as high as possible, the higher the number, the more secure it will be, but will take a longer amount of time to complete.

Chosen salts should also be unique. It is recommended that the salts are random and their length is greater than 16 bytes. See NIST SP 800-132 for details.

Example:

crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', function(err, key) {
  if (err)
    throw err;
  console.log(key.toString('hex'));  // 'c5e478d...1469e50'
});

You can get a list of supported digest functions with crypto.getHashes().

crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest])#

Synchronous PBKDF2 function. Returns derivedKey or throws error.

crypto.privateDecrypt(private_key, buffer)#

Decrypts buffer with private_key.

private_key can be an object or a string. If private_key is a string, it is treated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.

private_key:

  • key : A string holding the PEM encoded private key
  • passphrase : An optional string of passphrase for the private key
  • padding : An optional padding value, one of the following:
    • constants.RSA_NO_PADDING
    • constants.RSA_PKCS1_PADDING
    • constants.RSA_PKCS1_OAEP_PADDING

NOTE: All paddings are defined in constants module.

crypto.privateEncrypt(private_key, buffer)#

See above for details. Has the same API as crypto.privateDecrypt. Default padding is RSA_PKCS1_PADDING.

crypto.publicDecrypt(public_key, buffer)#

See above for details. Has the same API as crypto.publicEncrypt. Default padding is RSA_PKCS1_PADDING.

crypto.publicEncrypt(public_key, buffer)#

Encrypts buffer with public_key. Only RSA is currently supported.

public_key can be an object or a string. If public_key is a string, it is treated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING. Since RSA public keys may be derived from private keys you may pass a private key to this method.

public_key:

  • key : A string holding the PEM encoded private key
  • passphrase : An optional string of passphrase for the private key
  • padding : An optional padding value, one of the following:
    • constants.RSA_NO_PADDING
    • constants.RSA_PKCS1_PADDING
    • constants.RSA_PKCS1_OAEP_PADDING

NOTE: All paddings are defined in constants module.

crypto.randomBytes(size[, callback])#

Generates cryptographically strong pseudo-random data. Usage:

// async
crypto.randomBytes(256, (ex, buf) => {
  if (ex) throw ex;
  console.log('Have %d bytes of random data: %s', buf.length, buf);
});

// sync
const buf = crypto.randomBytes(256);
console.log('Have %d bytes of random data: %s', buf.length, buf);

NOTE: This will block if there is insufficient entropy, although it should normally never take longer than a few milliseconds. The only time when this may conceivably block is right after boot, when the whole system is still low on entropy.

crypto.setEngine(engine[, flags])#

Load and set engine for some/all OpenSSL functions (selected by flags).

engine could be either an id or a path to the engine's shared library.

flags is optional and has ENGINE_METHOD_ALL value by default. It could take one of or mix of following flags (defined in constants module):

  • ENGINE_METHOD_RSA
  • ENGINE_METHOD_DSA
  • ENGINE_METHOD_DH
  • ENGINE_METHOD_RAND
  • ENGINE_METHOD_ECDH
  • ENGINE_METHOD_ECDSA
  • ENGINE_METHOD_CIPHERS
  • ENGINE_METHOD_DIGESTS
  • ENGINE_METHOD_STORE
  • ENGINE_METHOD_PKEY_METH
  • ENGINE_METHOD_PKEY_ASN1_METH
  • ENGINE_METHOD_ALL
  • ENGINE_METHOD_NONE

Recent API Changes#

The Crypto module was added to Node.js before there was the concept of a unified Stream API, and before there were Buffer objects for handling binary data.

As such, the streaming classes don't have the typical methods found on other Node.js classes, and many methods accepted and returned Binary-encoded strings by default rather than Buffers. This was changed to use Buffers by default instead.

This is a breaking change for some use cases, but not all.

For example, if you currently use the default arguments to the Sign class, and then pass the results to the Verify class, without ever inspecting the data, then it will continue to work as before. Where you once got a binary string and then presented the binary string to the Verify object, you'll now get a Buffer, and present the Buffer to the Verify object.

However, if you were doing things with the string data that will not work properly on Buffers (such as, concatenating them, storing in databases, etc.), or you are passing binary strings to the crypto functions without an encoding argument, then you will need to start providing encoding arguments to specify which encoding you'd like to use. To switch to the previous style of using binary strings by default, set the crypto.DEFAULT_ENCODING field to 'binary'. Note that new programs will probably expect buffers, so only use this as a temporary measure.

Caveats#

The crypto module still supports some algorithms which are already compromised. And the API also allows the use of ciphers and hashes with a small key size that are considered to be too weak for safe use.

Users should take full responsibility for selecting the crypto algorithm and key size according to their security requirements.

Based on the recommendations of NIST SP 800-131A:

  • MD5 and SHA-1 are no longer acceptable where collision resistance is required such as digital signatures.
  • The key used with RSA, DSA and DH algorithms is recommended to have at least 2048 bits and that of the curve of ECDSA and ECDH at least 224 bits, to be safe to use for several years.
  • The DH groups of modp1, modp2 and modp5 have a key size smaller than 2048 bits and are not recommended.

See the reference for other recommendations and details.

node-v4.2.6/doc/api/crypto.json000644 000766 000024 00000171131 12650222331 016477 0ustar00iojsstaff000000 000000 { "source": "doc/api/crypto.markdown", "modules": [ { "textRaw": "Crypto", "name": "crypto", "stability": 2, "stabilityText": "Stable", "desc": "

Use require('crypto') to access this module.\n\n

\n

The crypto module offers a way of encapsulating secure credentials to be\nused as part of a secure HTTPS net or http connection.\n\n

\n

It also offers a set of wrappers for OpenSSL's hash, hmac, cipher,\ndecipher, sign and verify methods.\n\n

\n", "classes": [ { "textRaw": "Class: Certificate", "type": "class", "name": "Certificate", "desc": "

The class used for working with signed public key & challenges. The most\ncommon usage for this series of functions is when dealing with the <keygen>\nelement. https://www.openssl.org/docs/apps/spkac.html\n\n

\n

Returned by crypto.Certificate.\n\n

\n", "methods": [ { "textRaw": "Certificate.exportChallenge(spkac)", "type": "method", "name": "exportChallenge", "desc": "

Exports the encoded challenge associated with the SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] }, { "textRaw": "Certificate.exportPublicKey(spkac)", "type": "method", "name": "exportPublicKey", "desc": "

Exports the encoded public key from the supplied SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] }, { "textRaw": "Certificate.verifySpkac(spkac)", "type": "method", "name": "verifySpkac", "desc": "

Returns true of false based on the validity of the SPKAC.\n\n

\n", "signatures": [ { "params": [ { "name": "spkac" } ] } ] } ] }, { "textRaw": "Class: Cipher", "type": "class", "name": "Cipher", "desc": "

Class for encrypting data.\n\n

\n

Returned by crypto.createCipher and crypto.createCipheriv.\n\n

\n

Cipher objects are [streams][] that are both readable and writable.\nThe written plain text data is used to produce the encrypted data on\nthe readable side. The legacy update and final methods are also\nsupported.\n\n

\n", "methods": [ { "textRaw": "cipher.final([output_encoding])", "type": "method", "name": "final", "desc": "

Returns any remaining enciphered contents, with output_encoding\nbeing one of: 'binary', 'base64' or 'hex'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n

Note: cipher object can not be used after final() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "cipher.getAuthTag()", "type": "method", "name": "getAuthTag", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod returns a Buffer that represents the authentication tag that\nhas been computed from the given data. Should be called after\nencryption has been completed using the final method!\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "cipher.setAAD(buffer)", "type": "method", "name": "setAAD", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod sets the value used for the additional authenticated data (AAD) input\nparameter.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "cipher.setAutoPadding(auto_padding=true)", "type": "method", "name": "setAutoPadding", "desc": "

You can disable automatic padding of the input data to block size. If\nauto_padding is false, the length of the entire input data must be a\nmultiple of the cipher's block size or final will fail. Useful for\nnon-standard padding, e.g. using 0x0 instead of PKCS padding. You\nmust call this before cipher.final.\n\n

\n", "signatures": [ { "params": [ { "name": "auto_padding", "default": "true" } ] } ] }, { "textRaw": "cipher.update(data[, input_encoding][, output_encoding])", "type": "method", "name": "update", "desc": "

Updates the cipher with data, the encoding of which is given in\ninput_encoding and can be 'utf8', 'ascii' or 'binary'. If no\nencoding is provided, then a buffer is expected.\nIf data is a Buffer then input_encoding is ignored.\n\n

\n

The output_encoding specifies the output format of the enciphered\ndata, and can be 'binary', 'base64' or 'hex'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n

Returns the enciphered contents, and can be called many times with new\ndata as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Decipher", "type": "class", "name": "Decipher", "desc": "

Class for decrypting data.\n\n

\n

Returned by [crypto.createDecipher][] and [crypto.createDecipheriv][].\n\n

\n

Decipher objects are [streams][] that are both readable and writable.\nThe written enciphered data is used to produce the plain-text data on\nthe the readable side. The legacy update and final methods are also\nsupported.\n\n

\n", "methods": [ { "textRaw": "decipher.final([output_encoding])", "type": "method", "name": "final", "desc": "

Returns any remaining plaintext which is deciphered, with\noutput_encoding being one of: 'binary', 'ascii' or 'utf8'. If\nno encoding is provided, then a buffer is returned.\n\n

\n

Note: decipher object can not be used after final() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "decipher.setAAD(buffer)", "type": "method", "name": "setAAD", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod sets the value used for the additional authenticated data (AAD) input\nparameter.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "decipher.setAuthTag(buffer)", "type": "method", "name": "setAuthTag", "desc": "

For authenticated encryption modes (currently supported: GCM), this\nmethod must be used to pass in the received authentication tag.\nIf no tag is provided or if the ciphertext has been tampered with,\nfinal will throw, thus indicating that the ciphertext should\nbe discarded due to failed authentication.\n\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] }, { "textRaw": "decipher.setAutoPadding(auto_padding=true)", "type": "method", "name": "setAutoPadding", "desc": "

You can disable auto padding if the data has been encrypted without\nstandard block padding to prevent decipher.final from checking and\nremoving it. This will only work if the input data's length is a multiple of\nthe ciphers block size. You must call this before streaming data to\n[decipher.update][].\n\n

\n", "signatures": [ { "params": [ { "name": "auto_padding", "default": "true" } ] } ] }, { "textRaw": "decipher.update(data[, input_encoding][, output_encoding])", "type": "method", "name": "update", "desc": "

Updates the decipher with data, which is encoded in 'binary',\n'base64' or 'hex'. If no encoding is provided, then a buffer is\nexpected.\nIf data is a Buffer then input_encoding is ignored.\n\n

\n

The output_decoding specifies in what format to return the\ndeciphered plaintext: 'binary', 'ascii' or 'utf8'. If no\nencoding is provided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: DiffieHellman", "type": "class", "name": "DiffieHellman", "desc": "

The class for creating Diffie-Hellman key exchanges.\n\n

\n

Returned by crypto.createDiffieHellman.\n\n

\n", "methods": [ { "textRaw": "diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])", "type": "method", "name": "computeSecret", "desc": "

Computes the shared secret using other_public_key as the other\nparty's public key and returns the computed shared secret. Supplied\nkey is interpreted using specified input_encoding, and secret is\nencoded using specified output_encoding. Encodings can be\n'binary', 'hex', or 'base64'. If the input encoding is not\nprovided, then a buffer is expected.\n\n

\n

If no output encoding is given, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "other_public_key" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.generateKeys([encoding])", "type": "method", "name": "generateKeys", "desc": "

Generates private and public Diffie-Hellman key values, and returns\nthe public key in the specified encoding. This key should be\ntransferred to the other party. Encoding can be 'binary', 'hex',\nor 'base64'. If no encoding is provided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getGenerator([encoding])", "type": "method", "name": "getGenerator", "desc": "

Returns the Diffie-Hellman generator in the specified encoding, which can\nbe 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPrime([encoding])", "type": "method", "name": "getPrime", "desc": "

Returns the Diffie-Hellman prime in the specified encoding, which can\nbe 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPrivateKey([encoding])", "type": "method", "name": "getPrivateKey", "desc": "

Returns the Diffie-Hellman private key in the specified encoding,\nwhich can be 'binary', 'hex', or 'base64'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.getPublicKey([encoding])", "type": "method", "name": "getPublicKey", "desc": "

Returns the Diffie-Hellman public key in the specified encoding, which\ncan be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.setPrivateKey(private_key[, encoding])", "type": "method", "name": "setPrivateKey", "desc": "

Sets the Diffie-Hellman private key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "diffieHellman.setPublicKey(public_key[, encoding])", "type": "method", "name": "setPublicKey", "desc": "

Sets the Diffie-Hellman public key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "encoding", "optional": true } ] } ] } ], "properties": [ { "textRaw": "diffieHellman.verifyError", "name": "verifyError", "desc": "

A bit field containing any warnings and/or errors as a result of a check performed\nduring initialization. The following values are valid for this property\n(defined in constants module):\n\n

\n
    \n
  • DH_CHECK_P_NOT_SAFE_PRIME
  • \n
  • DH_CHECK_P_NOT_PRIME
  • \n
  • DH_UNABLE_TO_CHECK_GENERATOR
  • \n
  • DH_NOT_SUITABLE_GENERATOR
  • \n
\n" } ] }, { "textRaw": "Class: ECDH", "type": "class", "name": "ECDH", "desc": "

The class for creating EC Diffie-Hellman key exchanges.\n\n

\n

Returned by crypto.createECDH.\n\n

\n", "methods": [ { "textRaw": "ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding])", "type": "method", "name": "computeSecret", "desc": "

Computes the shared secret using other_public_key as the other\nparty's public key and returns the computed shared secret. Supplied\nkey is interpreted using specified input_encoding, and secret is\nencoded using specified output_encoding. Encodings can be\n'binary', 'hex', or 'base64'. If the input encoding is not\nprovided, then a buffer is expected.\n\n

\n

If no output encoding is given, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "other_public_key" }, { "name": "input_encoding", "optional": true }, { "name": "output_encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.generateKeys([encoding[, format]])", "type": "method", "name": "generateKeys", "desc": "

Generates private and public EC Diffie-Hellman key values, and returns\nthe public key in the specified format and encoding. This key should be\ntransferred to the other party.\n\n

\n

Format specifies point encoding and can be 'compressed', 'uncompressed', or\n'hybrid'. If no format is provided - the point will be returned in\n'uncompressed' format.\n\n

\n

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding" }, { "name": "format]", "optional": true } ] } ] }, { "textRaw": "ECDH.getPrivateKey([encoding])", "type": "method", "name": "getPrivateKey", "desc": "

Returns the EC Diffie-Hellman private key in the specified encoding,\nwhich can be 'binary', 'hex', or 'base64'. If no encoding is\nprovided, then a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.getPublicKey([encoding[, format]])", "type": "method", "name": "getPublicKey", "desc": "

Returns the EC Diffie-Hellman public key in the specified encoding and format.\n\n

\n

Format specifies point encoding and can be 'compressed', 'uncompressed', or\n'hybrid'. If no format is provided - the point will be returned in\n'uncompressed' format.\n\n

\n

Encoding can be 'binary', 'hex', or 'base64'. If no encoding is provided,\nthen a buffer is returned.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding" }, { "name": "format]", "optional": true } ] } ] }, { "textRaw": "ECDH.setPrivateKey(private_key[, encoding])", "type": "method", "name": "setPrivateKey", "desc": "

Sets the EC Diffie-Hellman private key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n

Example (obtaining a shared secret):\n\n

\n
const crypto = require('crypto');\nconst alice = crypto.createECDH('secp256k1');\nconst bob = crypto.createECDH('secp256k1');\n\nalice.generateKeys();\nbob.generateKeys();\n\nconst alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');\nconst bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');\n\n/* alice_secret and bob_secret should be the same */\nconsole.log(alice_secret == bob_secret);
\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "ECDH.setPublicKey(public_key[, encoding])", "type": "method", "name": "setPublicKey", "desc": "

Sets the EC Diffie-Hellman public key. Key encoding can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nexpected.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Hash", "type": "class", "name": "Hash", "desc": "

The class for creating hash digests of data.\n\n

\n

It is a [stream][] that is both readable and writable. The written data\nis used to compute the hash. Once the writable side of the stream is ended,\nuse the read() method to get the computed hash digest. The legacy update\nand digest methods are also supported.\n\n

\n

Returned by crypto.createHash.\n\n

\n", "methods": [ { "textRaw": "hash.digest([encoding])", "type": "method", "name": "digest", "desc": "

Calculates the digest of all of the passed data to be hashed. The\nencoding can be 'hex', 'binary' or 'base64'. If no encoding\nis provided, then a buffer is returned.\n\n

\n

Note: hash object can not be used after digest() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "hash.update(data[, input_encoding])", "type": "method", "name": "update", "desc": "

Updates the hash content with the given data, the encoding of which\nis given in input_encoding and can be 'utf8', 'ascii' or\n'binary'. If no encoding is provided, and the input is a string, an\nencoding of 'binary' is enforced. If data is a Buffer then\ninput_encoding is ignored.\n\n

\n

This can be called many times with new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "input_encoding", "optional": true } ] } ] } ] }, { "textRaw": "Class: Hmac", "type": "class", "name": "Hmac", "desc": "

Class for creating cryptographic hmac content.\n\n

\n

Returned by crypto.createHmac.\n\n

\n", "methods": [ { "textRaw": "hmac.digest([encoding])", "type": "method", "name": "digest", "desc": "

Calculates the digest of all of the passed data to the hmac. The\nencoding can be 'hex', 'binary' or 'base64'. If no encoding\nis provided, then a buffer is returned.\n\n

\n

Note: hmac object can not be used after digest() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "hmac.update(data)", "type": "method", "name": "update", "desc": "

Update the hmac content with the given data. This can be called\nmany times with new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] } ] }, { "textRaw": "Class: Sign", "type": "class", "name": "Sign", "desc": "

Class for generating signatures.\n\n

\n

Returned by crypto.createSign.\n\n

\n

Sign objects are writable [streams][]. The written data is used to\ngenerate the signature. Once all of the data has been written, the\nsign method will return the signature. The legacy update method\nis also supported.\n\n

\n", "methods": [ { "textRaw": "sign.sign(private_key[, output_format])", "type": "method", "name": "sign", "desc": "

Calculates the signature on all the updated data passed through the\nsign.\n\n

\n

private_key can be an object or a string. If private_key is a string, it is\ntreated as the key with no passphrase.\n\n

\n

private_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : A string of passphrase for the private key
  • \n
\n

Returns the signature in output_format which can be 'binary',\n'hex' or 'base64'. If no encoding is provided, then a buffer is\nreturned.\n\n

\n

Note: sign object can not be used after sign() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "output_format", "optional": true } ] } ] }, { "textRaw": "sign.update(data)", "type": "method", "name": "update", "desc": "

Updates the sign object with data. This can be called many times\nwith new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] } ] }, { "textRaw": "Class: Verify", "type": "class", "name": "Verify", "desc": "

Class for verifying signatures.\n\n

\n

Returned by crypto.createVerify.\n\n

\n

Verify objects are writable [streams][]. The written data is used to\nvalidate against the supplied signature. Once all of the data has been\nwritten, the verify method will return true if the supplied signature\nis valid. The legacy update method is also supported.\n\n

\n", "methods": [ { "textRaw": "verifier.update(data)", "type": "method", "name": "update", "desc": "

Updates the verifier object with data. This can be called many times\nwith new data as it is streamed.\n\n

\n", "signatures": [ { "params": [ { "name": "data" } ] } ] }, { "textRaw": "verifier.verify(object, signature[, signature_format])", "type": "method", "name": "verify", "desc": "

Verifies the signed data by using the object and signature.\nobject is a string containing a PEM encoded object, which can be\none of RSA public key, DSA public key, or X.509 certificate.\nsignature is the previously calculated signature for the data, in\nthe signature_format which can be 'binary', 'hex' or 'base64'.\nIf no encoding is specified, then a buffer is expected.\n\n

\n

Returns true or false depending on the validity of the signature for\nthe data and public key.\n\n

\n

Note: verifier object can not be used after verify() method has been\ncalled.\n\n

\n", "signatures": [ { "params": [ { "name": "object" }, { "name": "signature" }, { "name": "signature_format", "optional": true } ] } ] } ] } ], "properties": [ { "textRaw": "crypto.DEFAULT_ENCODING", "name": "DEFAULT_ENCODING", "desc": "

The default encoding to use for functions that can take either strings\nor buffers. The default value is 'buffer', which makes it default\nto using Buffer objects. This is here to make the crypto module more\neasily compatible with legacy programs that expected 'binary' to be\nthe default encoding.\n\n

\n

Note that new programs will probably expect buffers, so only use this\nas a temporary measure.\n\n

\n" } ], "methods": [ { "textRaw": "crypto.createCipher(algorithm, password)", "type": "method", "name": "createCipher", "desc": "

Creates and returns a cipher object, with the given algorithm and\npassword.\n\n

\n

algorithm is dependent on OpenSSL, examples are 'aes192', etc. On\nrecent releases, openssl list-cipher-algorithms will display the\navailable cipher algorithms. password is used to derive key and IV,\nwhich must be a 'binary' encoded string or a [buffer][].\n\n

\n

It is a [stream][] that is both readable and writable. The written data\nis used to compute the hash. Once the writable side of the stream is ended,\nuse the read() method to get the enciphered contents. The legacy update\nand final methods are also supported.\n\n

\n

Note: createCipher derives keys with the OpenSSL function [EVP_BytesToKey][]\nwith the digest algorithm set to MD5, one iteration, and no salt. The lack of\nsalt allows dictionary attacks as the same password always creates the same key.\nThe low iteration count and non-cryptographically secure hash algorithm allow\npasswords to be tested very rapidly.\n\n

\n

In line with OpenSSL's recommendation to use pbkdf2 instead of [EVP_BytesToKey][] it\nis recommended you derive a key and iv yourself with [crypto.pbkdf2][] and to\nthen use [createCipheriv()][] to create the cipher stream.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "password" } ] } ] }, { "textRaw": "crypto.createCipheriv(algorithm, key, iv)", "type": "method", "name": "createCipheriv", "desc": "

Creates and returns a cipher object, with the given algorithm, key and\niv.\n\n

\n

algorithm is the same as the argument to createCipher(). key is\nthe raw key used by the algorithm. iv is an [initialization vector][].\n\n

\n

key and iv must be 'binary' encoded strings or [buffers][].\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" }, { "name": "iv" } ] } ] }, { "textRaw": "crypto.createCredentials(details)", "type": "method", "name": "createCredentials", "stability": 0, "stabilityText": "Deprecated: Use [`tls.createSecureContext`][] instead.", "desc": "

Creates a credentials object, with the optional details being a\ndictionary with keys:\n\n

\n
    \n
  • pfx : A string or buffer holding the PFX or PKCS12 encoded private\nkey, certificate and CA certificates
  • \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : A string of passphrase for the private key or pfx
  • \n
  • cert : A string holding the PEM encoded certificate
  • \n
  • ca : Either a string or list of strings of PEM encoded CA\ncertificates to trust.
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs\n(Certificate Revocation List)
  • \n
  • ciphers: A string describing the ciphers to use or exclude.\nConsult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT\nfor details on the format.
  • \n
\n

If no 'ca' details are given, then Node.js will use the default\npublicly trusted list of CAs as given in\n

\n

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.\n\n

\n", "signatures": [ { "params": [ { "name": "details" } ] } ] }, { "textRaw": "crypto.createDecipher(algorithm, password)", "type": "method", "name": "createDecipher", "desc": "

Creates and returns a decipher object, with the given algorithm and\nkey. This is the mirror of the [createCipher()][] above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "password" } ] } ] }, { "textRaw": "crypto.createDecipheriv(algorithm, key, iv)", "type": "method", "name": "createDecipheriv", "desc": "

Creates and returns a decipher object, with the given algorithm, key\nand iv. This is the mirror of the [createCipheriv()][] above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" }, { "name": "iv" } ] } ] }, { "textRaw": "crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])", "type": "method", "name": "createDiffieHellman", "desc": "

Creates a Diffie-Hellman key exchange object using the supplied prime and an\noptional specific generator.\ngenerator can be a number, string, or Buffer.\nIf no generator is specified, then 2 is used.\nprime_encoding and generator_encoding can be 'binary', 'hex', or 'base64'.\nIf no prime_encoding is specified, then a Buffer is expected for prime.\nIf no generator_encoding is specified, then a Buffer is expected for generator.\n\n

\n", "signatures": [ { "params": [ { "name": "prime" }, { "name": "prime_encoding", "optional": true }, { "name": "generator", "optional": true }, { "name": "generator_encoding", "optional": true } ] } ] }, { "textRaw": "crypto.createDiffieHellman(prime_length[, generator])", "type": "method", "name": "createDiffieHellman", "desc": "

Creates a Diffie-Hellman key exchange object and generates a prime of\nprime_length bits and using an optional specific numeric generator.\nIf no generator is specified, then 2 is used.\n\n

\n", "signatures": [ { "params": [ { "name": "prime_length" }, { "name": "generator", "optional": true } ] } ] }, { "textRaw": "crypto.createECDH(curve_name)", "type": "method", "name": "createECDH", "desc": "

Creates an Elliptic Curve (EC) Diffie-Hellman key exchange object using a\npredefined curve specified by the curve_name string. Use [getCurves()][] to\nobtain a list of available curve names. On recent releases,\nopenssl ecparam -list_curves will also display the name and description of\neach available elliptic curve.\n\n

\n", "signatures": [ { "params": [ { "name": "curve_name" } ] } ] }, { "textRaw": "crypto.createHash(algorithm)", "type": "method", "name": "createHash", "desc": "

Creates and returns a hash object, a cryptographic hash with the given\nalgorithm which can be used to generate hash digests.\n\n

\n

algorithm is dependent on the available algorithms supported by the\nversion of OpenSSL on the platform. Examples are 'sha256',\n'sha512', etc. On recent releases, openssl\nlist-message-digest-algorithms will display the available digest\nalgorithms.\n\n

\n

Example: this program that takes the sha256 sum of a file\n\n

\n
const filename = process.argv[2];\nconst crypto = require('crypto');\nconst fs = require('fs');\n\nconst shasum = crypto.createHash('sha256');\n\nconst s = fs.ReadStream(filename);\ns.on('data', (d) => {\n  shasum.update(d);\n});\n\ns.on('end', () => {\n  var d = shasum.digest('hex');\n  console.log(`${d}  ${filename}`);\n});
\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.createHmac(algorithm, key)", "type": "method", "name": "createHmac", "desc": "

Creates and returns a hmac object, a cryptographic hmac with the given\nalgorithm and key.\n\n

\n

It is a [stream][] that is both readable and writable. The written\ndata is used to compute the hmac. Once the writable side of the\nstream is ended, use the read() method to get the computed digest.\nThe legacy update and digest methods are also supported.\n\n

\n

algorithm is dependent on the available algorithms supported by\nOpenSSL - see createHash above. key is the hmac key to be used.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" }, { "name": "key" } ] } ] }, { "textRaw": "crypto.createSign(algorithm)", "type": "method", "name": "createSign", "desc": "

Creates and returns a signing object, with the given algorithm. On\nrecent OpenSSL releases, openssl list-public-key-algorithms will\ndisplay the available signing algorithms. Examples are 'RSA-SHA256'.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.createVerify(algorithm)", "type": "method", "name": "createVerify", "desc": "

Creates and returns a verification object, with the given algorithm.\nThis is the mirror of the signing object above.\n\n

\n", "signatures": [ { "params": [ { "name": "algorithm" } ] } ] }, { "textRaw": "crypto.getCiphers()", "type": "method", "name": "getCiphers", "desc": "

Returns an array with the names of the supported ciphers.\n\n

\n

Example:\n\n

\n
const ciphers = crypto.getCiphers();\nconsole.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.getCurves()", "type": "method", "name": "getCurves", "desc": "

Returns an array with the names of the supported elliptic curves.\n\n

\n

Example:\n\n

\n
const curves = crypto.getCurves();\nconsole.log(curves); // ['secp256k1', 'secp384r1', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.getDiffieHellman(group_name)", "type": "method", "name": "getDiffieHellman", "desc": "

Creates a predefined Diffie-Hellman key exchange object. The\nsupported groups are: 'modp1', 'modp2', 'modp5' (defined in\n[RFC 2412][], but see [Caveats][]) and 'modp14', 'modp15',\n'modp16', 'modp17', 'modp18' (defined in [RFC 3526][]). The\nreturned object mimics the interface of objects created by\n[crypto.createDiffieHellman()][] above, but will not allow changing\nthe keys (with [diffieHellman.setPublicKey()][] for example). The\nadvantage of using this routine is that the parties do not have to\ngenerate nor exchange group modulus beforehand, saving both processor\nand communication time.\n\n

\n

Example (obtaining a shared secret):\n\n

\n
const crypto = require('crypto');\nconst alice = crypto.getDiffieHellman('modp14');\nconst bob = crypto.getDiffieHellman('modp14');\n\nalice.generateKeys();\nbob.generateKeys();\n\nconst alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');\nconst bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');\n\n/* alice_secret and bob_secret should be the same */\nconsole.log(alice_secret == bob_secret);
\n", "signatures": [ { "params": [ { "name": "group_name" } ] } ] }, { "textRaw": "crypto.getHashes()", "type": "method", "name": "getHashes", "desc": "

Returns an array with the names of the supported hash algorithms.\n\n

\n

Example:\n\n

\n
const hashes = crypto.getHashes();\nconsole.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)", "type": "method", "name": "pbkdf2", "desc": "

Asynchronous PBKDF2 function. Applies the selected HMAC digest function\n(default: SHA1) to derive a key of the requested byte length from the password,\nsalt and number of iterations. The callback gets two arguments:\n(err, derivedKey).\n\n

\n

The number of iterations passed to pbkdf2 should be as high as possible, the\nhigher the number, the more secure it will be, but will take a longer amount of\ntime to complete.\n\n

\n

Chosen salts should also be unique. It is recommended that the salts are random\nand their length is greater than 16 bytes. See [NIST SP 800-132] for details.\n\n

\n

Example:\n\n

\n
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', function(err, key) {\n  if (err)\n    throw err;\n  console.log(key.toString('hex'));  // 'c5e478d...1469e50'\n});
\n

You can get a list of supported digest functions with [crypto.getHashes()][].\n\n

\n", "signatures": [ { "params": [ { "name": "password" }, { "name": "salt" }, { "name": "iterations" }, { "name": "keylen" }, { "name": "digest", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest])", "type": "method", "name": "pbkdf2Sync", "desc": "

Synchronous PBKDF2 function. Returns derivedKey or throws error.\n\n

\n", "signatures": [ { "params": [ { "name": "password" }, { "name": "salt" }, { "name": "iterations" }, { "name": "keylen" }, { "name": "digest", "optional": true } ] } ] }, { "textRaw": "crypto.privateDecrypt(private_key, buffer)", "type": "method", "name": "privateDecrypt", "desc": "

Decrypts buffer with private_key.\n\n

\n

private_key can be an object or a string. If private_key is a string, it is\ntreated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.\n\n

\n

private_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : An optional string of passphrase for the private key
  • \n
  • padding : An optional padding value, one of the following:
      \n
    • constants.RSA_NO_PADDING
    • \n
    • constants.RSA_PKCS1_PADDING
    • \n
    • constants.RSA_PKCS1_OAEP_PADDING
    • \n
    \n
  • \n
\n

NOTE: All paddings are defined in constants module.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.privateEncrypt(private_key, buffer)", "type": "method", "name": "privateEncrypt", "desc": "

See above for details. Has the same API as crypto.privateDecrypt.\nDefault padding is RSA_PKCS1_PADDING.\n\n

\n", "signatures": [ { "params": [ { "name": "private_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.publicDecrypt(public_key, buffer)", "type": "method", "name": "publicDecrypt", "desc": "

See above for details. Has the same API as crypto.publicEncrypt. Default\npadding is RSA_PKCS1_PADDING.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.publicEncrypt(public_key, buffer)", "type": "method", "name": "publicEncrypt", "desc": "

Encrypts buffer with public_key. Only RSA is currently supported.\n\n

\n

public_key can be an object or a string. If public_key is a string, it is\ntreated as the key with no passphrase and will use RSA_PKCS1_OAEP_PADDING.\nSince RSA public keys may be derived from private keys you may pass a private\nkey to this method.\n\n

\n

public_key:\n\n

\n
    \n
  • key : A string holding the PEM encoded private key
  • \n
  • passphrase : An optional string of passphrase for the private key
  • \n
  • padding : An optional padding value, one of the following:
      \n
    • constants.RSA_NO_PADDING
    • \n
    • constants.RSA_PKCS1_PADDING
    • \n
    • constants.RSA_PKCS1_OAEP_PADDING
    • \n
    \n
  • \n
\n

NOTE: All paddings are defined in constants module.\n\n

\n", "signatures": [ { "params": [ { "name": "public_key" }, { "name": "buffer" } ] } ] }, { "textRaw": "crypto.randomBytes(size[, callback])", "type": "method", "name": "randomBytes", "desc": "

Generates cryptographically strong pseudo-random data. Usage:\n\n

\n
// async\ncrypto.randomBytes(256, (ex, buf) => {\n  if (ex) throw ex;\n  console.log('Have %d bytes of random data: %s', buf.length, buf);\n});\n\n// sync\nconst buf = crypto.randomBytes(256);\nconsole.log('Have %d bytes of random data: %s', buf.length, buf);
\n

NOTE: This will block if there is insufficient entropy, although it should\nnormally never take longer than a few milliseconds. The only time when this\nmay conceivably block is right after boot, when the whole system is still\nlow on entropy.\n\n

\n", "signatures": [ { "params": [ { "name": "size" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "crypto.setEngine(engine[, flags])", "type": "method", "name": "setEngine", "desc": "

Load and set engine for some/all OpenSSL functions (selected by flags).\n\n

\n

engine could be either an id or a path to the engine's shared library.\n\n

\n

flags is optional and has ENGINE_METHOD_ALL value by default. It could take\none of or mix of following flags (defined in constants module):\n\n

\n
    \n
  • ENGINE_METHOD_RSA
  • \n
  • ENGINE_METHOD_DSA
  • \n
  • ENGINE_METHOD_DH
  • \n
  • ENGINE_METHOD_RAND
  • \n
  • ENGINE_METHOD_ECDH
  • \n
  • ENGINE_METHOD_ECDSA
  • \n
  • ENGINE_METHOD_CIPHERS
  • \n
  • ENGINE_METHOD_DIGESTS
  • \n
  • ENGINE_METHOD_STORE
  • \n
  • ENGINE_METHOD_PKEY_METH
  • \n
  • ENGINE_METHOD_PKEY_ASN1_METH
  • \n
  • ENGINE_METHOD_ALL
  • \n
  • ENGINE_METHOD_NONE
  • \n
\n", "signatures": [ { "params": [ { "name": "engine" }, { "name": "flags", "optional": true } ] } ] } ], "modules": [ { "textRaw": "Recent API Changes", "name": "recent_api_changes", "desc": "

The Crypto module was added to Node.js before there was the concept of a\nunified Stream API, and before there were Buffer objects for handling\nbinary data.\n\n

\n

As such, the streaming classes don't have the typical methods found on\nother Node.js classes, and many methods accepted and returned\nBinary-encoded strings by default rather than Buffers. This was\nchanged to use Buffers by default instead.\n\n

\n

This is a breaking change for some use cases, but not all.\n\n

\n

For example, if you currently use the default arguments to the Sign\nclass, and then pass the results to the Verify class, without ever\ninspecting the data, then it will continue to work as before. Where\nyou once got a binary string and then presented the binary string to\nthe Verify object, you'll now get a Buffer, and present the Buffer to\nthe Verify object.\n\n

\n

However, if you were doing things with the string data that will not\nwork properly on Buffers (such as, concatenating them, storing in\ndatabases, etc.), or you are passing binary strings to the crypto\nfunctions without an encoding argument, then you will need to start\nproviding encoding arguments to specify which encoding you'd like to\nuse. To switch to the previous style of using binary strings by\ndefault, set the crypto.DEFAULT_ENCODING field to 'binary'. Note\nthat new programs will probably expect buffers, so only use this as a\ntemporary measure.\n\n

\n", "type": "module", "displayName": "Recent API Changes" }, { "textRaw": "Caveats", "name": "caveats", "desc": "

The crypto module still supports some algorithms which are already\ncompromised. And the API also allows the use of ciphers and hashes\nwith a small key size that are considered to be too weak for safe use.\n\n

\n

Users should take full responsibility for selecting the crypto\nalgorithm and key size according to their security requirements.\n\n

\n

Based on the recommendations of [NIST SP 800-131A]:\n\n

\n
    \n
  • MD5 and SHA-1 are no longer acceptable where collision resistance is\nrequired such as digital signatures.
  • \n
  • The key used with RSA, DSA and DH algorithms is recommended to have\nat least 2048 bits and that of the curve of ECDSA and ECDH at least\n224 bits, to be safe to use for several years.
  • \n
  • The DH groups of modp1, modp2 and modp5 have a key size\nsmaller than 2048 bits and are not recommended.
  • \n
\n

See the reference for other recommendations and details.\n\n

\n", "type": "module", "displayName": "Caveats" } ], "type": "module", "displayName": "Crypto" } ] } node-v4.2.6/doc/api/crypto.markdown000644 000766 000024 00000071442 12650222326 017360 0ustar00iojsstaff000000 000000 # Crypto Stability: 2 - Stable Use `require('crypto')` to access this module. The crypto module offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection. It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods. ## Class: Certificate The class used for working with signed public key & challenges. The most common usage for this series of functions is when dealing with the `` element. https://www.openssl.org/docs/apps/spkac.html Returned by `crypto.Certificate`. ### Certificate.exportChallenge(spkac) Exports the encoded challenge associated with the SPKAC. ### Certificate.exportPublicKey(spkac) Exports the encoded public key from the supplied SPKAC. ### Certificate.verifySpkac(spkac) Returns true of false based on the validity of the SPKAC. ## Class: Cipher Class for encrypting data. Returned by `crypto.createCipher` and `crypto.createCipheriv`. Cipher objects are [streams][] that are both readable and writable. The written plain text data is used to produce the encrypted data on the readable side. The legacy `update` and `final` methods are also supported. ### cipher.final([output_encoding]) Returns any remaining enciphered contents, with `output_encoding` being one of: `'binary'`, `'base64'` or `'hex'`. If no encoding is provided, then a buffer is returned. Note: `cipher` object can not be used after `final()` method has been called. ### cipher.getAuthTag() For authenticated encryption modes (currently supported: GCM), this method returns a `Buffer` that represents the _authentication tag_ that has been computed from the given data. Should be called after encryption has been completed using the `final` method! ### cipher.setAAD(buffer) For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter. ### cipher.setAutoPadding(auto_padding=true) You can disable automatic padding of the input data to block size. If `auto_padding` is false, the length of the entire input data must be a multiple of the cipher's block size or `final` will fail. Useful for non-standard padding, e.g. using `0x0` instead of PKCS padding. You must call this before `cipher.final`. ### cipher.update(data[, input_encoding][, output_encoding]) Updates the cipher with `data`, the encoding of which is given in `input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. If no encoding is provided, then a buffer is expected. If `data` is a `Buffer` then `input_encoding` is ignored. The `output_encoding` specifies the output format of the enciphered data, and can be `'binary'`, `'base64'` or `'hex'`. If no encoding is provided, then a buffer is returned. Returns the enciphered contents, and can be called many times with new data as it is streamed. ## Class: Decipher Class for decrypting data. Returned by [`crypto.createDecipher`][] and [`crypto.createDecipheriv`][]. Decipher objects are [streams][] that are both readable and writable. The written enciphered data is used to produce the plain-text data on the the readable side. The legacy `update` and `final` methods are also supported. ### decipher.final([output_encoding]) Returns any remaining plaintext which is deciphered, with `output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`. If no encoding is provided, then a buffer is returned. Note: `decipher` object can not be used after `final()` method has been called. ### decipher.setAAD(buffer) For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter. ### decipher.setAuthTag(buffer) For authenticated encryption modes (currently supported: GCM), this method must be used to pass in the received _authentication tag_. If no tag is provided or if the ciphertext has been tampered with, `final` will throw, thus indicating that the ciphertext should be discarded due to failed authentication. ### decipher.setAutoPadding(auto_padding=true) You can disable auto padding if the data has been encrypted without standard block padding to prevent `decipher.final` from checking and removing it. This will only work if the input data's length is a multiple of the ciphers block size. You must call this before streaming data to [`decipher.update`][]. ### decipher.update(data[, input_encoding][, output_encoding]) Updates the decipher with `data`, which is encoded in `'binary'`, `'base64'` or `'hex'`. If no encoding is provided, then a buffer is expected. If `data` is a `Buffer` then `input_encoding` is ignored. The `output_decoding` specifies in what format to return the deciphered plaintext: `'binary'`, `'ascii'` or `'utf8'`. If no encoding is provided, then a buffer is returned. ## Class: DiffieHellman The class for creating Diffie-Hellman key exchanges. Returned by `crypto.createDiffieHellman`. ### diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding]) Computes the shared secret using `other_public_key` as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified `input_encoding`, and secret is encoded using specified `output_encoding`. Encodings can be `'binary'`, `'hex'`, or `'base64'`. If the input encoding is not provided, then a buffer is expected. If no output encoding is given, then a buffer is returned. ### diffieHellman.generateKeys([encoding]) Generates private and public Diffie-Hellman key values, and returns the public key in the specified encoding. This key should be transferred to the other party. Encoding can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### diffieHellman.getGenerator([encoding]) Returns the Diffie-Hellman generator in the specified encoding, which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### diffieHellman.getPrime([encoding]) Returns the Diffie-Hellman prime in the specified encoding, which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### diffieHellman.getPrivateKey([encoding]) Returns the Diffie-Hellman private key in the specified encoding, which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### diffieHellman.getPublicKey([encoding]) Returns the Diffie-Hellman public key in the specified encoding, which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### diffieHellman.setPrivateKey(private_key[, encoding]) Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'` or `'base64'`. If no encoding is provided, then a buffer is expected. ### diffieHellman.setPublicKey(public_key[, encoding]) Sets the Diffie-Hellman public key. Key encoding can be `'binary'`, `'hex'` or `'base64'`. If no encoding is provided, then a buffer is expected. ### diffieHellman.verifyError A bit field containing any warnings and/or errors as a result of a check performed during initialization. The following values are valid for this property (defined in `constants` module): * `DH_CHECK_P_NOT_SAFE_PRIME` * `DH_CHECK_P_NOT_PRIME` * `DH_UNABLE_TO_CHECK_GENERATOR` * `DH_NOT_SUITABLE_GENERATOR` ## Class: ECDH The class for creating EC Diffie-Hellman key exchanges. Returned by `crypto.createECDH`. ### ECDH.computeSecret(other_public_key[, input_encoding][, output_encoding]) Computes the shared secret using `other_public_key` as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified `input_encoding`, and secret is encoded using specified `output_encoding`. Encodings can be `'binary'`, `'hex'`, or `'base64'`. If the input encoding is not provided, then a buffer is expected. If no output encoding is given, then a buffer is returned. ### ECDH.generateKeys([encoding[, format]]) Generates private and public EC Diffie-Hellman key values, and returns the public key in the specified format and encoding. This key should be transferred to the other party. Format specifies point encoding and can be `'compressed'`, `'uncompressed'`, or `'hybrid'`. If no format is provided - the point will be returned in `'uncompressed'` format. Encoding can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### ECDH.getPrivateKey([encoding]) Returns the EC Diffie-Hellman private key in the specified encoding, which can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### ECDH.getPublicKey([encoding[, format]]) Returns the EC Diffie-Hellman public key in the specified encoding and format. Format specifies point encoding and can be `'compressed'`, `'uncompressed'`, or `'hybrid'`. If no format is provided - the point will be returned in `'uncompressed'` format. Encoding can be `'binary'`, `'hex'`, or `'base64'`. If no encoding is provided, then a buffer is returned. ### ECDH.setPrivateKey(private_key[, encoding]) Sets the EC Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'` or `'base64'`. If no encoding is provided, then a buffer is expected. Example (obtaining a shared secret): const crypto = require('crypto'); const alice = crypto.createECDH('secp256k1'); const bob = crypto.createECDH('secp256k1'); alice.generateKeys(); bob.generateKeys(); const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); /* alice_secret and bob_secret should be the same */ console.log(alice_secret == bob_secret); ### ECDH.setPublicKey(public_key[, encoding]) Sets the EC Diffie-Hellman public key. Key encoding can be `'binary'`, `'hex'` or `'base64'`. If no encoding is provided, then a buffer is expected. ## Class: Hash The class for creating hash digests of data. It is a [stream][] that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the `read()` method to get the computed hash digest. The legacy `update` and `digest` methods are also supported. Returned by `crypto.createHash`. ### hash.digest([encoding]) Calculates the digest of all of the passed data to be hashed. The `encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding is provided, then a buffer is returned. Note: `hash` object can not be used after `digest()` method has been called. ### hash.update(data[, input_encoding]) Updates the hash content with the given `data`, the encoding of which is given in `input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. If no encoding is provided, and the input is a string, an encoding of `'binary'` is enforced. If `data` is a `Buffer` then `input_encoding` is ignored. This can be called many times with new data as it is streamed. ## Class: Hmac Class for creating cryptographic hmac content. Returned by `crypto.createHmac`. ### hmac.digest([encoding]) Calculates the digest of all of the passed data to the hmac. The `encoding` can be `'hex'`, `'binary'` or `'base64'`. If no encoding is provided, then a buffer is returned. Note: `hmac` object can not be used after `digest()` method has been called. ### hmac.update(data) Update the hmac content with the given `data`. This can be called many times with new data as it is streamed. ## Class: Sign Class for generating signatures. Returned by `crypto.createSign`. Sign objects are writable [streams][]. The written data is used to generate the signature. Once all of the data has been written, the `sign` method will return the signature. The legacy `update` method is also supported. ### sign.sign(private_key[, output_format]) Calculates the signature on all the updated data passed through the sign. `private_key` can be an object or a string. If `private_key` is a string, it is treated as the key with no passphrase. `private_key`: * `key` : A string holding the PEM encoded private key * `passphrase` : A string of passphrase for the private key Returns the signature in `output_format` which can be `'binary'`, `'hex'` or `'base64'`. If no encoding is provided, then a buffer is returned. Note: `sign` object can not be used after `sign()` method has been called. ### sign.update(data) Updates the sign object with data. This can be called many times with new data as it is streamed. ## Class: Verify Class for verifying signatures. Returned by `crypto.createVerify`. Verify objects are writable [streams][]. The written data is used to validate against the supplied signature. Once all of the data has been written, the `verify` method will return true if the supplied signature is valid. The legacy `update` method is also supported. ### verifier.update(data) Updates the verifier object with data. This can be called many times with new data as it is streamed. ### verifier.verify(object, signature[, signature_format]) Verifies the signed data by using the `object` and `signature`. `object` is a string containing a PEM encoded object, which can be one of RSA public key, DSA public key, or X.509 certificate. `signature` is the previously calculated signature for the data, in the `signature_format` which can be `'binary'`, `'hex'` or `'base64'`. If no encoding is specified, then a buffer is expected. Returns true or false depending on the validity of the signature for the data and public key. Note: `verifier` object can not be used after `verify()` method has been called. ## crypto.DEFAULT_ENCODING The default encoding to use for functions that can take either strings or buffers. The default value is `'buffer'`, which makes it default to using Buffer objects. This is here to make the crypto module more easily compatible with legacy programs that expected `'binary'` to be the default encoding. Note that new programs will probably expect buffers, so only use this as a temporary measure. ## crypto.createCipher(algorithm, password) Creates and returns a cipher object, with the given algorithm and password. `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On recent releases, `openssl list-cipher-algorithms` will display the available cipher algorithms. `password` is used to derive key and IV, which must be a `'binary'` encoded string or a [buffer][]. It is a [stream][] that is both readable and writable. The written data is used to compute the hash. Once the writable side of the stream is ended, use the `read()` method to get the enciphered contents. The legacy `update` and `final` methods are also supported. Note: `createCipher` derives keys with the OpenSSL function [`EVP_BytesToKey`][] with the digest algorithm set to MD5, one iteration, and no salt. The lack of salt allows dictionary attacks as the same password always creates the same key. The low iteration count and non-cryptographically secure hash algorithm allow passwords to be tested very rapidly. In line with OpenSSL's recommendation to use pbkdf2 instead of [`EVP_BytesToKey`][] it is recommended you derive a key and iv yourself with [`crypto.pbkdf2`][] and to then use [`createCipheriv()`][] to create the cipher stream. ## crypto.createCipheriv(algorithm, key, iv) Creates and returns a cipher object, with the given algorithm, key and iv. `algorithm` is the same as the argument to `createCipher()`. `key` is the raw key used by the algorithm. `iv` is an [initialization vector][]. `key` and `iv` must be `'binary'` encoded strings or [buffers][]. ## crypto.createCredentials(details) Stability: 0 - Deprecated: Use [`tls.createSecureContext`][] instead. Creates a credentials object, with the optional details being a dictionary with keys: * `pfx` : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates * `key` : A string holding the PEM encoded private key * `passphrase` : A string of passphrase for the private key or pfx * `cert` : A string holding the PEM encoded certificate * `ca` : Either a string or list of strings of PEM encoded CA certificates to trust. * `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List) * `ciphers`: A string describing the ciphers to use or exclude. Consult for details on the format. If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in . ## crypto.createDecipher(algorithm, password) Creates and returns a decipher object, with the given algorithm and key. This is the mirror of the [`createCipher()`][] above. ## crypto.createDecipheriv(algorithm, key, iv) Creates and returns a decipher object, with the given algorithm, key and iv. This is the mirror of the [`createCipheriv()`][] above. ## crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding]) Creates a Diffie-Hellman key exchange object using the supplied `prime` and an optional specific `generator`. `generator` can be a number, string, or Buffer. If no `generator` is specified, then `2` is used. `prime_encoding` and `generator_encoding` can be `'binary'`, `'hex'`, or `'base64'`. If no `prime_encoding` is specified, then a Buffer is expected for `prime`. If no `generator_encoding` is specified, then a Buffer is expected for `generator`. ## crypto.createDiffieHellman(prime_length[, generator]) Creates a Diffie-Hellman key exchange object and generates a prime of `prime_length` bits and using an optional specific numeric `generator`. If no `generator` is specified, then `2` is used. ## crypto.createECDH(curve_name) Creates an Elliptic Curve (EC) Diffie-Hellman key exchange object using a predefined curve specified by the `curve_name` string. Use [`getCurves()`][] to obtain a list of available curve names. On recent releases, `openssl ecparam -list_curves` will also display the name and description of each available elliptic curve. ## crypto.createHash(algorithm) Creates and returns a hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests. `algorithm` is dependent on the available algorithms supported by the version of OpenSSL on the platform. Examples are `'sha256'`, `'sha512'`, etc. On recent releases, `openssl list-message-digest-algorithms` will display the available digest algorithms. Example: this program that takes the sha256 sum of a file const filename = process.argv[2]; const crypto = require('crypto'); const fs = require('fs'); const shasum = crypto.createHash('sha256'); const s = fs.ReadStream(filename); s.on('data', (d) => { shasum.update(d); }); s.on('end', () => { var d = shasum.digest('hex'); console.log(`${d} ${filename}`); }); ## crypto.createHmac(algorithm, key) Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key. It is a [stream][] that is both readable and writable. The written data is used to compute the hmac. Once the writable side of the stream is ended, use the `read()` method to get the computed digest. The legacy `update` and `digest` methods are also supported. `algorithm` is dependent on the available algorithms supported by OpenSSL - see createHash above. `key` is the hmac key to be used. ## crypto.createSign(algorithm) Creates and returns a signing object, with the given algorithm. On recent OpenSSL releases, `openssl list-public-key-algorithms` will display the available signing algorithms. Examples are `'RSA-SHA256'`. ## crypto.createVerify(algorithm) Creates and returns a verification object, with the given algorithm. This is the mirror of the signing object above. ## crypto.getCiphers() Returns an array with the names of the supported ciphers. Example: const ciphers = crypto.getCiphers(); console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...] ## crypto.getCurves() Returns an array with the names of the supported elliptic curves. Example: const curves = crypto.getCurves(); console.log(curves); // ['secp256k1', 'secp384r1', ...] ## crypto.getDiffieHellman(group_name) Creates a predefined Diffie-Hellman key exchange object. The supported groups are: `'modp1'`, `'modp2'`, `'modp5'` (defined in [RFC 2412][], but see [Caveats][]) and `'modp14'`, `'modp15'`, `'modp16'`, `'modp17'`, `'modp18'` (defined in [RFC 3526][]). The returned object mimics the interface of objects created by [`crypto.createDiffieHellman()`][] above, but will not allow changing the keys (with [`diffieHellman.setPublicKey()`][] for example). The advantage of using this routine is that the parties do not have to generate nor exchange group modulus beforehand, saving both processor and communication time. Example (obtaining a shared secret): const crypto = require('crypto'); const alice = crypto.getDiffieHellman('modp14'); const bob = crypto.getDiffieHellman('modp14'); alice.generateKeys(); bob.generateKeys(); const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex'); const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex'); /* alice_secret and bob_secret should be the same */ console.log(alice_secret == bob_secret); ## crypto.getHashes() Returns an array with the names of the supported hash algorithms. Example: const hashes = crypto.getHashes(); console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...] ## crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback) Asynchronous PBKDF2 function. Applies the selected HMAC digest function (default: SHA1) to derive a key of the requested byte length from the password, salt and number of iterations. The callback gets two arguments: `(err, derivedKey)`. The number of iterations passed to pbkdf2 should be as high as possible, the higher the number, the more secure it will be, but will take a longer amount of time to complete. Chosen salts should also be unique. It is recommended that the salts are random and their length is greater than 16 bytes. See [NIST SP 800-132] for details. Example: crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', function(err, key) { if (err) throw err; console.log(key.toString('hex')); // 'c5e478d...1469e50' }); You can get a list of supported digest functions with [`crypto.getHashes()`][]. ## crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest]) Synchronous PBKDF2 function. Returns derivedKey or throws error. ## crypto.privateDecrypt(private_key, buffer) Decrypts `buffer` with `private_key`. `private_key` can be an object or a string. If `private_key` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. `private_key`: * `key` : A string holding the PEM encoded private key * `passphrase` : An optional string of passphrase for the private key * `padding` : An optional padding value, one of the following: * `constants.RSA_NO_PADDING` * `constants.RSA_PKCS1_PADDING` * `constants.RSA_PKCS1_OAEP_PADDING` NOTE: All paddings are defined in `constants` module. ## crypto.privateEncrypt(private_key, buffer) See above for details. Has the same API as `crypto.privateDecrypt`. Default padding is `RSA_PKCS1_PADDING`. ## crypto.publicDecrypt(public_key, buffer) See above for details. Has the same API as `crypto.publicEncrypt`. Default padding is `RSA_PKCS1_PADDING`. ## crypto.publicEncrypt(public_key, buffer) Encrypts `buffer` with `public_key`. Only RSA is currently supported. `public_key` can be an object or a string. If `public_key` is a string, it is treated as the key with no passphrase and will use `RSA_PKCS1_OAEP_PADDING`. Since RSA public keys may be derived from private keys you may pass a private key to this method. `public_key`: * `key` : A string holding the PEM encoded private key * `passphrase` : An optional string of passphrase for the private key * `padding` : An optional padding value, one of the following: * `constants.RSA_NO_PADDING` * `constants.RSA_PKCS1_PADDING` * `constants.RSA_PKCS1_OAEP_PADDING` NOTE: All paddings are defined in `constants` module. ## crypto.randomBytes(size[, callback]) Generates cryptographically strong pseudo-random data. Usage: // async crypto.randomBytes(256, (ex, buf) => { if (ex) throw ex; console.log('Have %d bytes of random data: %s', buf.length, buf); }); // sync const buf = crypto.randomBytes(256); console.log('Have %d bytes of random data: %s', buf.length, buf); NOTE: This will block if there is insufficient entropy, although it should normally never take longer than a few milliseconds. The only time when this may conceivably block is right after boot, when the whole system is still low on entropy. ## crypto.setEngine(engine[, flags]) Load and set engine for some/all OpenSSL functions (selected by flags). `engine` could be either an id or a path to the engine's shared library. `flags` is optional and has `ENGINE_METHOD_ALL` value by default. It could take one of or mix of following flags (defined in `constants` module): * `ENGINE_METHOD_RSA` * `ENGINE_METHOD_DSA` * `ENGINE_METHOD_DH` * `ENGINE_METHOD_RAND` * `ENGINE_METHOD_ECDH` * `ENGINE_METHOD_ECDSA` * `ENGINE_METHOD_CIPHERS` * `ENGINE_METHOD_DIGESTS` * `ENGINE_METHOD_STORE` * `ENGINE_METHOD_PKEY_METH` * `ENGINE_METHOD_PKEY_ASN1_METH` * `ENGINE_METHOD_ALL` * `ENGINE_METHOD_NONE` ## Recent API Changes The Crypto module was added to Node.js before there was the concept of a unified Stream API, and before there were Buffer objects for handling binary data. As such, the streaming classes don't have the typical methods found on other Node.js classes, and many methods accepted and returned Binary-encoded strings by default rather than Buffers. This was changed to use Buffers by default instead. This is a breaking change for some use cases, but not all. For example, if you currently use the default arguments to the Sign class, and then pass the results to the Verify class, without ever inspecting the data, then it will continue to work as before. Where you once got a binary string and then presented the binary string to the Verify object, you'll now get a Buffer, and present the Buffer to the Verify object. However, if you were doing things with the string data that will not work properly on Buffers (such as, concatenating them, storing in databases, etc.), or you are passing binary strings to the crypto functions without an encoding argument, then you will need to start providing encoding arguments to specify which encoding you'd like to use. To switch to the previous style of using binary strings by default, set the `crypto.DEFAULT_ENCODING` field to 'binary'. Note that new programs will probably expect buffers, so only use this as a temporary measure. ## Caveats The crypto module still supports some algorithms which are already compromised. And the API also allows the use of ciphers and hashes with a small key size that are considered to be too weak for safe use. Users should take full responsibility for selecting the crypto algorithm and key size according to their security requirements. Based on the recommendations of [NIST SP 800-131A]: - MD5 and SHA-1 are no longer acceptable where collision resistance is required such as digital signatures. - The key used with RSA, DSA and DH algorithms is recommended to have at least 2048 bits and that of the curve of ECDSA and ECDH at least 224 bits, to be safe to use for several years. - The DH groups of `modp1`, `modp2` and `modp5` have a key size smaller than 2048 bits and are not recommended. See the reference for other recommendations and details. [`createCipher()`]: #crypto_crypto_createcipher_algorithm_password [`createCipheriv()`]: #crypto_crypto_createcipheriv_algorithm_key_iv [`crypto.createDecipher`]: #crypto_crypto_createdecipher_algorithm_password [`crypto.createDecipheriv`]: #crypto_crypto_createdecipheriv_algorithm_key_iv [`crypto.createDiffieHellman()`]: #crypto_crypto_creatediffiehellman_prime_prime_encoding_generator_generator_encoding [`crypto.getHashes()`]: #crypto_crypto_gethashes [`crypto.pbkdf2`]: #crypto_crypto_pbkdf2_password_salt_iterations_keylen_digest_callback [`decipher.update`]: #crypto_decipher_update_data_input_encoding_output_encoding [`diffieHellman.setPublicKey()`]: #crypto_diffiehellman_setpublickey_public_key_encoding [`EVP_BytesToKey`]: https://www.openssl.org/docs/crypto/EVP_BytesToKey.html [`getCurves()`]: #crypto_crypto_getcurves [`tls.createSecureContext`]: tls.html#tls_tls_createsecurecontext_details [buffer]: buffer.html [buffers]: buffer.html [Caveats]: #crypto_caveats [initialization vector]: https://en.wikipedia.org/wiki/Initialization_vector [NIST SP 800-131A]: http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf [NIST SP 800-132]: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf [RFC 2412]: https://www.rfc-editor.org/rfc/rfc2412.txt [RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt [stream]: stream.html [streams]: stream.html node-v4.2.6/doc/api/debugger.html000644 000766 000024 00000026130 12650222331 016734 0ustar00iojsstaff000000 000000 Debugger Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Debugger#

Stability: 2 - Stable

Node.js includes a full-featured out-of-process debugging utility accessible via a simple TCP-based protocol and built-in debugging client. To use it, start Node.js with the debug argument followed by the path to the script to debug; a prompt will be displayed indicating successful launch of the debugger:

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug>

Node.js's debugger client does not yet support the full range of commands, but simple step and inspection are possible.

Inserting the statement debugger; into the source code of a script will enable a breakpoint at that position in the code.

For example, suppose myscript.js is written as:

// myscript.js
x = 5;
setTimeout(function () {
  debugger;
  console.log('world');
}, 1000);
console.log('hello');

Once the debugger is run, a breakpoint will occur at line 4:

% node debug myscript.js
< debugger listening on port 5858
connecting... ok
break in /home/indutny/Code/git/indutny/myscript.js:1
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
debug> cont
< hello
break in /home/indutny/Code/git/indutny/myscript.js:3
  1 x = 5;
  2 setTimeout(function () {
  3   debugger;
  4   console.log('world');
  5 }, 1000);
debug> next
break in /home/indutny/Code/git/indutny/myscript.js:4
  2 setTimeout(function () {
  3   debugger;
  4   console.log('world');
  5 }, 1000);
  6 console.log('hello');
debug> repl
Press Ctrl + C to leave debug repl
> x
5
> 2+2
4
debug> next
< world
break in /home/indutny/Code/git/indutny/myscript.js:5
  3   debugger;
  4   console.log('world');
  5 }, 1000);
  6 console.log('hello');
  7
debug> quit
%

The repl command allows code to be evaluated remotely. The next command steps over to the next line. Type help to see what other commands are available.

Watchers#

It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's source code listing.

To begin watching an expression, type watch('my_expression'). The command watchers will print the active watchers. To remove a watcher, type unwatch('my_expression').

Commands reference#

Stepping#

  • cont, c - Continue execution
  • next, n - Step next
  • step, s - Step in
  • out, o - Step out
  • pause - Pause running code (like pause button in Developer Tools)

Breakpoints#

  • setBreakpoint(), sb() - Set breakpoint on current line
  • setBreakpoint(line), sb(line) - Set breakpoint on specific line
  • setBreakpoint('fn()'), sb(...) - Set breakpoint on a first statement in functions body
  • setBreakpoint('script.js', 1), sb(...) - Set breakpoint on first line of script.js
  • clearBreakpoint('script.js', 1), cb(...) - Clear breakpoint in script.js on line 1

It is also possible to set a breakpoint in a file (module) that isn't loaded yet:

% ./node debug test/fixtures/break-in-module/main.js
< debugger listening on port 5858
connecting to port 5858... ok
break in test/fixtures/break-in-module/main.js:1
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> setBreakpoint('mod.js', 23)
Warning: script 'mod.js' was not loaded yet.
  1 var mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> c
break in test/fixtures/break-in-module/mod.js:23
 21
 22 exports.hello = function() {
 23   return 'hello from module';
 24 };
 25
debug>

Info#

  • backtrace, bt - Print backtrace of current execution frame
  • list(5) - List scripts source code with 5 line context (5 lines before and after)
  • watch(expr) - Add expression to watch list
  • unwatch(expr) - Remove expression from watch list
  • watchers - List all watchers and their values (automatically listed on each breakpoint)
  • repl - Open debugger's repl for evaluation in debugging script's context

Execution control#

  • run - Run script (automatically runs on debugger's start)
  • restart - Restart script
  • kill - Kill script

Various#

  • scripts - List all loaded scripts
  • version - Display V8's version

Advanced Usage#

An alternative way of enabling and accessing the debugger is to start Node.js with the --debug command-line flag or by signaling an existing Node.js process with SIGUSR1.

Once a process has been set in debug mode this way, it can be connected to using the Node.js debugger by either connecting to the pid of the running process or via URI reference to the listening debugger:

  • node debug -p <pid> - Connects to the process via the pid
  • node debug <URI> - Connects to the process via the URI such as localhost:5858
node-v4.2.6/doc/api/debugger.json000644 000766 000024 00000014564 12650222331 016751 0ustar00iojsstaff000000 000000 { "source": "doc/api/debugger.markdown", "stability": 2, "stabilityText": "Stable", "miscs": [ { "textRaw": "Debugger", "name": "Debugger", "stability": 2, "stabilityText": "Stable", "type": "misc", "desc": "

Node.js includes a full-featured out-of-process debugging utility accessible\nvia a simple [TCP-based protocol][] and built-in debugging client. To use it,\nstart Node.js with the debug argument followed by the path to the script to\ndebug; a prompt will be displayed indicating successful launch of the debugger:\n\n

\n
% node debug myscript.js\n< debugger listening on port 5858\nconnecting... ok\nbreak in /home/indutny/Code/git/indutny/myscript.js:1\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\ndebug>
\n

Node.js's debugger client does not yet support the full range of commands, but\nsimple step and inspection are possible.\n\n

\n

Inserting the statement debugger; into the source code of a script will\nenable a breakpoint at that position in the code.\n\n

\n

For example, suppose myscript.js is written as:\n\n

\n
// myscript.js\nx = 5;\nsetTimeout(function () {\n  debugger;\n  console.log('world');\n}, 1000);\nconsole.log('hello');
\n

Once the debugger is run, a breakpoint will occur at line 4:\n\n

\n
% node debug myscript.js\n< debugger listening on port 5858\nconnecting... ok\nbreak in /home/indutny/Code/git/indutny/myscript.js:1\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\ndebug> cont\n< hello\nbreak in /home/indutny/Code/git/indutny/myscript.js:3\n  1 x = 5;\n  2 setTimeout(function () {\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\ndebug> next\nbreak in /home/indutny/Code/git/indutny/myscript.js:4\n  2 setTimeout(function () {\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\n  6 console.log('hello');\ndebug> repl\nPress Ctrl + C to leave debug repl\n> x\n5\n> 2+2\n4\ndebug> next\n< world\nbreak in /home/indutny/Code/git/indutny/myscript.js:5\n  3   debugger;\n  4   console.log('world');\n  5 }, 1000);\n  6 console.log('hello');\n  7\ndebug> quit\n%
\n

The repl command allows code to be evaluated remotely. The next command\nsteps over to the next line. Type help to see what other commands are\navailable.\n\n

\n", "miscs": [ { "textRaw": "Watchers", "name": "watchers", "desc": "

It is possible to watch expression and variable values while debugging. On\nevery breakpoint, each expression from the watchers list will be evaluated\nin the current context and displayed immediately before the breakpoint's\nsource code listing.\n\n

\n

To begin watching an expression, type watch('my_expression'). The command\nwatchers will print the active watchers. To remove a watcher, type\nunwatch('my_expression').\n\n

\n", "type": "misc", "displayName": "Watchers" }, { "textRaw": "Commands reference", "name": "commands_reference", "modules": [ { "textRaw": "Stepping", "name": "Stepping", "desc": "

It is also possible to set a breakpoint in a file (module) that\nisn't loaded yet:\n\n

\n
% ./node debug test/fixtures/break-in-module/main.js\n< debugger listening on port 5858\nconnecting to port 5858... ok\nbreak in test/fixtures/break-in-module/main.js:1\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> setBreakpoint('mod.js', 23)\nWarning: script 'mod.js' was not loaded yet.\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> c\nbreak in test/fixtures/break-in-module/mod.js:23\n 21\n 22 exports.hello = function() {\n 23   return 'hello from module';\n 24 };\n 25\ndebug>
\n", "type": "module", "displayName": "Breakpoints" }, { "textRaw": "Breakpoints", "name": "breakpoints", "desc": "

It is also possible to set a breakpoint in a file (module) that\nisn't loaded yet:\n\n

\n
% ./node debug test/fixtures/break-in-module/main.js\n< debugger listening on port 5858\nconnecting to port 5858... ok\nbreak in test/fixtures/break-in-module/main.js:1\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> setBreakpoint('mod.js', 23)\nWarning: script 'mod.js' was not loaded yet.\n  1 var mod = require('./mod.js');\n  2 mod.hello();\n  3 mod.hello();\ndebug> c\nbreak in test/fixtures/break-in-module/mod.js:23\n 21\n 22 exports.hello = function() {\n 23   return 'hello from module';\n 24 };\n 25\ndebug>
\n", "type": "module", "displayName": "Breakpoints" }, { "textRaw": "Execution control", "name": "Execution control", "type": "module", "displayName": "Various" }, { "textRaw": "Various", "name": "various", "type": "module", "displayName": "Various" } ], "type": "misc", "displayName": "Commands reference" }, { "textRaw": "Advanced Usage", "name": "advanced_usage", "desc": "

An alternative way of enabling and accessing the debugger is to start\nNode.js with the --debug command-line flag or by signaling an existing\nNode.js process with SIGUSR1.\n\n

\n

Once a process has been set in debug mode this way, it can be connected to\nusing the Node.js debugger by either connecting to the pid of the running\nprocess or via URI reference to the listening debugger:\n\n

\n
    \n
  • node debug -p <pid> - Connects to the process via the pid
  • \n
  • node debug <URI> - Connects to the process via the URI such as\nlocalhost:5858
  • \n
\n", "type": "misc", "displayName": "Advanced Usage" } ] } ] } node-v4.2.6/doc/api/debugger.markdown000644 000766 000024 00000012160 12650222326 017614 0ustar00iojsstaff000000 000000 # Debugger Stability: 2 - Stable Node.js includes a full-featured out-of-process debugging utility accessible via a simple [TCP-based protocol][] and built-in debugging client. To use it, start Node.js with the `debug` argument followed by the path to the script to debug; a prompt will be displayed indicating successful launch of the debugger: % node debug myscript.js < debugger listening on port 5858 connecting... ok break in /home/indutny/Code/git/indutny/myscript.js:1 1 x = 5; 2 setTimeout(function () { 3 debugger; debug> Node.js's debugger client does not yet support the full range of commands, but simple step and inspection are possible. Inserting the statement `debugger;` into the source code of a script will enable a breakpoint at that position in the code. For example, suppose `myscript.js` is written as: // myscript.js x = 5; setTimeout(function () { debugger; console.log('world'); }, 1000); console.log('hello'); Once the debugger is run, a breakpoint will occur at line 4: % node debug myscript.js < debugger listening on port 5858 connecting... ok break in /home/indutny/Code/git/indutny/myscript.js:1 1 x = 5; 2 setTimeout(function () { 3 debugger; debug> cont < hello break in /home/indutny/Code/git/indutny/myscript.js:3 1 x = 5; 2 setTimeout(function () { 3 debugger; 4 console.log('world'); 5 }, 1000); debug> next break in /home/indutny/Code/git/indutny/myscript.js:4 2 setTimeout(function () { 3 debugger; 4 console.log('world'); 5 }, 1000); 6 console.log('hello'); debug> repl Press Ctrl + C to leave debug repl > x 5 > 2+2 4 debug> next < world break in /home/indutny/Code/git/indutny/myscript.js:5 3 debugger; 4 console.log('world'); 5 }, 1000); 6 console.log('hello'); 7 debug> quit % The `repl` command allows code to be evaluated remotely. The `next` command steps over to the next line. Type `help` to see what other commands are available. ## Watchers It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's source code listing. To begin watching an expression, type `watch('my_expression')`. The command `watchers` will print the active watchers. To remove a watcher, type `unwatch('my_expression')`. ## Commands reference ### Stepping * `cont`, `c` - Continue execution * `next`, `n` - Step next * `step`, `s` - Step in * `out`, `o` - Step out * `pause` - Pause running code (like pause button in Developer Tools) ### Breakpoints * `setBreakpoint()`, `sb()` - Set breakpoint on current line * `setBreakpoint(line)`, `sb(line)` - Set breakpoint on specific line * `setBreakpoint('fn()')`, `sb(...)` - Set breakpoint on a first statement in functions body * `setBreakpoint('script.js', 1)`, `sb(...)` - Set breakpoint on first line of script.js * `clearBreakpoint('script.js', 1)`, `cb(...)` - Clear breakpoint in script.js on line 1 It is also possible to set a breakpoint in a file (module) that isn't loaded yet: % ./node debug test/fixtures/break-in-module/main.js < debugger listening on port 5858 connecting to port 5858... ok break in test/fixtures/break-in-module/main.js:1 1 var mod = require('./mod.js'); 2 mod.hello(); 3 mod.hello(); debug> setBreakpoint('mod.js', 23) Warning: script 'mod.js' was not loaded yet. 1 var mod = require('./mod.js'); 2 mod.hello(); 3 mod.hello(); debug> c break in test/fixtures/break-in-module/mod.js:23 21 22 exports.hello = function() { 23 return 'hello from module'; 24 }; 25 debug> ### Info * `backtrace`, `bt` - Print backtrace of current execution frame * `list(5)` - List scripts source code with 5 line context (5 lines before and after) * `watch(expr)` - Add expression to watch list * `unwatch(expr)` - Remove expression from watch list * `watchers` - List all watchers and their values (automatically listed on each breakpoint) * `repl` - Open debugger's repl for evaluation in debugging script's context ### Execution control * `run` - Run script (automatically runs on debugger's start) * `restart` - Restart script * `kill` - Kill script ### Various * `scripts` - List all loaded scripts * `version` - Display V8's version ## Advanced Usage An alternative way of enabling and accessing the debugger is to start Node.js with the `--debug` command-line flag or by signaling an existing Node.js process with `SIGUSR1`. Once a process has been set in debug mode this way, it can be connected to using the Node.js debugger by either connecting to the `pid` of the running process or via URI reference to the listening debugger: * `node debug -p ` - Connects to the process via the `pid` * `node debug ` - Connects to the process via the URI such as localhost:5858 [TCP-based protocol]: https://github.com/v8/v8/wiki/Debugging-Protocol node-v4.2.6/doc/api/dgram.html000644 000766 000024 00000066654 12650222331 016261 0ustar00iojsstaff000000 000000 UDP / Datagram Sockets Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


UDP / Datagram Sockets#

Stability: 2 - Stable

The dgram module provides an implementation of UDP Datagram sockets.

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(41234);
// server listening 0.0.0.0:41234

Class: dgram.Socket#

The dgram.Socket object is an EventEmitter that encapsulates the datagram functionality.

New instances of dgram.Socket are created using dgram.createSocket(). The new keyword is not to be used to create dgram.Socket instances.

Event: 'close'#

The 'close' event is emitted after a socket is closed with close(). Once triggered, no new 'message' events will be emitted on this socket.

Event: 'error'#

  • exception Error object

The 'error' event is emitted whenever any error occurs. The event handler function is passed a single Error object.

Event: 'listening'#

The 'listening' event is emitted whenever a socket begins listening for datagram messages. This occurs as soon as UDP sockets are created.

Event: 'message'#

  • msg Buffer object. The message
  • rinfo Object. Remote address information

The 'message' event is emitted when a new datagram is available on a socket. The event handler function is passed two arguments: msg and rinfo. The msg argument is a Buffer and rinfo is an object with the sender's address information provided by the address, family and port properties:

socket.on('message', (msg, rinfo) => {
  console.log('Received %d bytes from %s:%d\n',
              msg.length, rinfo.address, rinfo.port);
});

socket.addMembership(multicastAddress[, multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

Tells the kernel to join a multicast group at the given multicastAddress using the IP_ADD_MEMBERSHIP socket option. If the multicastInterface argument is not specified, the operating system will try to add membership to all valid networking interfaces.

socket.address()#

Returns an object containing the address information for a socket. For UDP sockets, this object will contain address, family and port properties.

[socket.bind([port][, address][, callback])]#

  • port Integer, Optional
  • address String, Optional
  • callback Function with no parameters, Optional. Called when binding is complete.

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address. If port is not specified, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

Note that specifying both a 'listening' event listener and passing a callback to the socket.bind() method is not harmful but not very useful.

A bound datagram socket keeps the Node.js process running to receive datagram messages.

If binding fails, an 'error' event is generated. In rare case (e.g. attempting to bind with a closed socket), an Error may be thrown.

Example of a UDP server listening on port 41234:

const dgram = require('dgram');
const server = dgram.createSocket('udp4');

server.on('error', (err) => {
  console.log(`server error:\n${err.stack}`);
  server.close();
});

server.on('message', (msg, rinfo) => {
  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
});

server.on('listening', () => {
  var address = server.address();
  console.log(`server listening ${address.address}:${address.port}`);
});

server.bind(41234);
// server listening 0.0.0.0:41234

socket.bind(options[, callback])#

  • options Object - Required. Supports the following properties:
    • port Number - Required.
    • address String - Optional.
    • exclusive Boolean - Optional.
  • callback Function - Optional.

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address that are passed as properties of an options object passed as the first argument. If port is not specified, the operating system will attempt to bind to a random port. If address is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening' event is emitted and the optional callback function is called.

The options object may contain an additional exclusive property that is use when using dgram.Socket objects with the [cluster] module. When exclusive is set to false (the default), cluster workers will use the same underlying socket handle allowing connection handling duties to be shared. When exclusive is true, however, the handle is not shared and attempted port sharing results in an error.

An example socket listening on an exclusive port is shown below.

socket.bind({
  address: 'localhost',
  port: 8000,
  exclusive: true
});

socket.close([callback])#

Close the underlying socket and stop listening for data on it. If a callback is provided, it is added as a listener for the 'close' event.

socket.dropMembership(multicastAddress[, multicastInterface])#

  • multicastAddress String
  • multicastInterface String, Optional

Instructs the kernel to leave a multicast group at multicastAddress using the IP_DROP_MEMBERSHIP socket option. This method is automatically called by the kernel when the socket is closed or the process terminates, so most apps will never have reason to call this.

If multicastInterface is not specified, the operating system will attempt to drop membership on all valid interfaces.

socket.send(buf, offset, length, port, address[, callback])#

  • buf Buffer object or string. Message to be sent
  • offset Integer. Offset in the buffer where the message starts.
  • length Integer. Number of bytes in the message.
  • port Integer. Destination port.
  • address String. Destination hostname or IP address.
  • callback Function. Called when the message has been sent. Optional.

Broadcasts a datagram on the socket. The destination port and address must be specified.

The buf argument is a Buffer object containing the message. The offset and length specify the offset within the Buffer where the message begins and the number of bytes in the message, respectively. With messages that contain multi-byte characters, offset and length will be calculated with respect to byte length and not the character position.

The address argument is a string. If the value of address is a host name, DNS will be used to resolve the address of the host. If the address is not specified or is an empty string, '0.0.0.0' or '::0' will be used instead. It is possible, depending on the network configuration, that these defaults may not work; accordingly, it is best to be explicit about the destination address.

If the socket has not been previously bound with a call to bind, the socket is assigned a random port number and is bound to the "all interfaces" address ('0.0.0.0' for udp4 sockets, '::0' for udp6 sockets.)

An optional callback function may be specified to as a way of reporting DNS errors or for determining when it is safe to reuse the buf object. Note that DNS lookups delay the time to send for at least one tick of the Node.js event loop.

The only way to know for sure that the datagram has been sent is by using a callback. If an error occurs and a callback is given, the error will be passed as the first argument to the callback. If a callback is not given, the error is emitted as an 'error' event on the socket object.

Example of sending a UDP packet to a random port on localhost;

const dgram = require('dgram');
const message = new Buffer('Some bytes');
const client = dgram.createSocket('udp4');
client.send(message, 0, message.length, 41234, 'localhost', (err) => {
  client.close();
});

A Note about UDP datagram size

The maximum size of an IPv4/v6 datagram depends on the MTU (Maximum Transmission Unit) and on the Payload Length field size.

  • The Payload Length field is 16 bits wide, which means that a normal payload exceed 64K octets including the internet header and data (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); this is generally true for loopback interfaces, but such long datagram messages are impractical for most hosts and networks.

  • The MTU is the largest size a given link layer technology can support for datagram messages. For any link, IPv4 mandates a minimum MTU of 68 octets, while the recommended MTU for IPv4 is 576 (typically recommended as the MTU for dial-up type applications), whether they arrive whole or in fragments.

    For IPv6, the minimum MTU is 1280 octets, however, the mandatory minimum fragment reassembly buffer size is 1500 octets. The value of 68 octets is very small, since most current link layer technologies, like Ethernet, have a minimum MTU of 1500.

It is impossible to know in advance the MTU of each link through which a packet might travel. Sending a datagram greater than the receiver MTU will not work because the packet will get silently dropped without informing the source that the data did not reach its intended recipient.

socket.setBroadcast(flag)#

  • flag Boolean

Sets or clears the SO_BROADCAST socket option. When set to true, UDP packets may be sent to a local interface's broadcast address.

socket.setMulticastLoopback(flag)#

  • flag Boolean

Sets or clears the IP_MULTICAST_LOOP socket option. When set to true, multicast packets will also be received on the local interface.

socket.setMulticastTTL(ttl)#

  • ttl Integer

Sets the IP_MULTICAST_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through, specifically for multicast traffic. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded.

The argument passed to to socket.setMulticastTTL() is a number of hops between 0 and 255. The default on most systems is 1 but can vary.

socket.setTTL(ttl)#

  • ttl Integer

Sets the IP_TTL socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. Changing TTL values is typically done for network probes or when multicasting.

The argument to socket.setTTL() is a number of hops between 1 and 255. The default on most systems is 64 but can vary.

socket.ref()#

By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active. The socket.ref() method adds the socket back to the reference counting and restores the default behavior.

Calling socket.ref() multiples times will have no additional effect.

The socket.ref() method returns a reference to the socket so calls can be chained.

socket.unref()#

By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The socket.unref() method can be used to exclude the socket from the reference counting that keeps the Node.js process active, allowing the process to exit even if the socket is still listening.

Calling socket.unref() multiple times will have no addition effect.

The socket.unref() method returns a reference to the socket so calls can be chained.

Change to asynchronous socket.bind() behavior#

As of Node.js v0.10, dgram.Socket#bind() changed to an asynchronous execution model. Legacy code that assumes synchronous behavior, as in the following example:

const s = dgram.createSocket('udp4');
s.bind(1234);
s.addMembership('224.0.0.114');

Must be changed to pass a callback function to the dgram.Socket#bind() function:

const s = dgram.createSocket('udp4');
s.bind(1234, () => {
  s.addMembership('224.0.0.114');
});

dgram module functions#

dgram.createSocket(options[, callback])#

  • options Object
  • callback Function. Attached as a listener to 'message' events.
  • Returns: Socket object

Creates a dgram.Socket object. The options argument is an object that should contain a type field of either udp4 or udp6 and an optional boolean reuseAddr field.

When reuseAddr is true socket.bind() will reuse the address, even if another process has already bound a socket on it. reuseAddr defaults to false. An optional callback function can be passed specified which is added as a listener for 'message' events.

Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.

dgram.createSocket(type[, callback])#

  • type String. Either 'udp4' or 'udp6'
  • callback Function. Attached as a listener to 'message' events. Optional
  • Returns: Socket object

Creates a dgram.Socket object of the specified type. The type argument can be either udp4 or udp6. An optional callback function can be passed which is added as a listener for 'message' events.

Once the socket is created, calling socket.bind() will instruct the socket to begin listening for datagram messages. When address and port are not passed to socket.bind() the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both udp4 and udp6 sockets). The bound address and port can be retrieved using socket.address().address and socket.address().port.

node-v4.2.6/doc/api/dgram.json000644 000766 000024 00000074430 12650222331 016255 0ustar00iojsstaff000000 000000 { "source": "doc/api/dgram.markdown", "modules": [ { "textRaw": "UDP / Datagram Sockets", "name": "dgram", "stability": 2, "stabilityText": "Stable", "desc": "

The dgram module provides an implementation of UDP Datagram sockets.\n\n

\n
const dgram = require('dgram');\nconst server = dgram.createSocket('udp4');\n\nserver.on('error', (err) => {\n  console.log(`server error:\\n${err.stack}`);\n  server.close();\n});\n\nserver.on('message', (msg, rinfo) => {\n  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);\n});\n\nserver.on('listening', () => {\n  var address = server.address();\n  console.log(`server listening ${address.address}:${address.port}`);\n});\n\nserver.bind(41234);\n// server listening 0.0.0.0:41234
\n", "classes": [ { "textRaw": "Class: dgram.Socket", "type": "class", "name": "dgram.Socket", "desc": "

The dgram.Socket object is an [EventEmitter][] that encapsulates the\ndatagram functionality.\n\n

\n

New instances of dgram.Socket are created using [dgram.createSocket()][].\nThe new keyword is not to be used to create dgram.Socket instances.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

The 'close' event is emitted after a socket is closed with [close()][].\nOnce triggered, no new 'message' events will be emitted on this socket.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

The 'error' event is emitted whenever any error occurs. The event handler\nfunction is passed a single Error object.\n\n

\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "desc": "

The 'listening' event is emitted whenever a socket begins listening for\ndatagram messages. This occurs as soon as UDP sockets are created.\n\n

\n", "params": [] }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

The 'message' event is emitted when a new datagram is available on a socket.\nThe event handler function is passed two arguments: msg and rinfo. The\nmsg argument is a [Buffer][] and rinfo is an object with the sender's\naddress information provided by the address, family and port properties:\n\n

\n
socket.on('message', (msg, rinfo) => {\n  console.log('Received %d bytes from %s:%d\\n',\n              msg.length, rinfo.address, rinfo.port);\n});
\n" } ], "methods": [ { "textRaw": "socket.addMembership(multicastAddress[, multicastInterface])", "type": "method", "name": "addMembership", "signatures": [ { "params": [ { "textRaw": "`multicastAddress` String ", "name": "multicastAddress", "desc": "String" }, { "textRaw": "`multicastInterface` String, Optional ", "name": "multicastInterface", "optional": true, "desc": "String" } ] }, { "params": [ { "name": "multicastAddress" }, { "name": "multicastInterface", "optional": true } ] } ], "desc": "

Tells the kernel to join a multicast group at the given multicastAddress\nusing the IP_ADD_MEMBERSHIP socket option. If the multicastInterface\nargument is not specified, the operating system will try to add membership to\nall valid networking interfaces.\n\n

\n" }, { "textRaw": "socket.address()", "type": "method", "name": "address", "desc": "

Returns an object containing the address information for a socket.\nFor UDP sockets, this object will contain address, family and port\nproperties.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.bind(options[, callback])", "type": "method", "name": "bind", "signatures": [ { "params": [ { "textRaw": "`options` {Object} - Required. Supports the following properties: ", "options": [ { "textRaw": "`port` {Number} - Required. ", "name": "port", "type": "Number", "desc": "Required." }, { "textRaw": "`address` {String} - Optional. ", "name": "address", "type": "String", "desc": "Optional." }, { "textRaw": "`exclusive` {Boolean} - Optional. ", "name": "exclusive", "type": "Boolean", "desc": "Optional." } ], "name": "options", "type": "Object", "desc": "Required. Supports the following properties:" }, { "textRaw": "`callback` {Function} - Optional. ", "name": "callback", "type": "Function", "desc": "Optional.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a\nnamed port and optional address that are passed as properties of an\noptions object passed as the first argument. If port is not specified, the\noperating system will attempt to bind to a random port. If address is not\nspecified, the operating system will attempt to listen on all addresses. Once\nbinding is complete, a 'listening' event is emitted and the optional\ncallback function is called.\n\n

\n

The options object may contain an additional exclusive property that is\nuse when using dgram.Socket objects with the [cluster] module. When\nexclusive is set to false (the default), cluster workers will use the same\nunderlying socket handle allowing connection handling duties to be shared.\nWhen exclusive is true, however, the handle is not shared and attempted\nport sharing results in an error.\n\n

\n

An example socket listening on an exclusive port is shown below.\n\n

\n
socket.bind({\n  address: 'localhost',\n  port: 8000,\n  exclusive: true\n});
\n" }, { "textRaw": "socket.close([callback])", "type": "method", "name": "close", "desc": "

Close the underlying socket and stop listening for data on it. If a callback is\nprovided, it is added as a listener for the ['close'][] event.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "socket.dropMembership(multicastAddress[, multicastInterface])", "type": "method", "name": "dropMembership", "signatures": [ { "params": [ { "textRaw": "`multicastAddress` String ", "name": "multicastAddress", "desc": "String" }, { "textRaw": "`multicastInterface` String, Optional ", "name": "multicastInterface", "optional": true, "desc": "String" } ] }, { "params": [ { "name": "multicastAddress" }, { "name": "multicastInterface", "optional": true } ] } ], "desc": "

Instructs the kernel to leave a multicast group at multicastAddress using the\nIP_DROP_MEMBERSHIP socket option. This method is automatically called by the\nkernel when the socket is closed or the process terminates, so most apps will\nnever have reason to call this.\n\n

\n

If multicastInterface is not specified, the operating system will attempt to\ndrop membership on all valid interfaces.\n\n

\n" }, { "textRaw": "socket.send(buf, offset, length, port, address[, callback])", "type": "method", "name": "send", "signatures": [ { "params": [ { "textRaw": "`buf` Buffer object or string. Message to be sent ", "name": "buf", "desc": "Buffer object or string. Message to be sent" }, { "textRaw": "`offset` Integer. Offset in the buffer where the message starts. ", "name": "offset", "desc": "Integer. Offset in the buffer where the message starts." }, { "textRaw": "`length` Integer. Number of bytes in the message. ", "name": "length", "desc": "Integer. Number of bytes in the message." }, { "textRaw": "`port` Integer. Destination port. ", "name": "port", "desc": "Integer. Destination port." }, { "textRaw": "`address` String. Destination hostname or IP address. ", "name": "address", "desc": "String. Destination hostname or IP address." }, { "textRaw": "`callback` Function. Called when the message has been sent. Optional. ", "name": "callback", "desc": "Function. Called when the message has been sent. Optional.", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "offset" }, { "name": "length" }, { "name": "port" }, { "name": "address" }, { "name": "callback", "optional": true } ] } ], "desc": "

Broadcasts a datagram on the socket. The destination port and address must\nbe specified.\n\n

\n

The buf argument is a [Buffer] object containing the message. The offset\nand length specify the offset within the Buffer where the message begins\nand the number of bytes in the message, respectively. With messages that\ncontain multi-byte characters, offset and length will be calculated with\nrespect to [byte length][] and not the character position.\n\n

\n

The address argument is a string. If the value of address is a host name,\nDNS will be used to resolve the address of the host. If the address is not\nspecified or is an empty string, '0.0.0.0' or '::0' will be used instead.\nIt is possible, depending on the network configuration, that these defaults\nmay not work; accordingly, it is best to be explicit about the destination\naddress.\n\n

\n

If the socket has not been previously bound with a call to bind, the socket\nis assigned a random port number and is bound to the "all interfaces" address\n('0.0.0.0' for udp4 sockets, '::0' for udp6 sockets.)\n\n

\n

An optional callback function may be specified to as a way of reporting\nDNS errors or for determining when it is safe to reuse the buf object.\nNote that DNS lookups delay the time to send for at least one tick of the\nNode.js event loop.\n\n

\n

The only way to know for sure that the datagram has been sent is by using a\ncallback. If an error occurs and a callback is given, the error will be\npassed as the first argument to the callback. If a callback is not given,\nthe error is emitted as an 'error' event on the socket object.\n\n

\n

Example of sending a UDP packet to a random port on localhost;\n\n

\n
const dgram = require('dgram');\nconst message = new Buffer('Some bytes');\nconst client = dgram.createSocket('udp4');\nclient.send(message, 0, message.length, 41234, 'localhost', (err) => {\n  client.close();\n});
\n

A Note about UDP datagram size\n\n

\n

The maximum size of an IPv4/v6 datagram depends on the MTU\n(Maximum Transmission Unit) and on the Payload Length field size.\n\n

\n
    \n
  • The Payload Length field is 16 bits wide, which means that a normal\npayload exceed 64K octets including the internet header and data\n(65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header);\nthis is generally true for loopback interfaces, but such long datagram\nmessages are impractical for most hosts and networks.

    \n
  • \n
  • The MTU is the largest size a given link layer technology can support for\ndatagram messages. For any link, IPv4 mandates a minimum MTU of 68\noctets, while the recommended MTU for IPv4 is 576 (typically recommended\nas the MTU for dial-up type applications), whether they arrive whole or in\nfragments.

    \n

    For IPv6, the minimum MTU is 1280 octets, however, the mandatory minimum\nfragment reassembly buffer size is 1500 octets. The value of 68 octets is\nvery small, since most current link layer technologies, like Ethernet, have a\nminimum MTU of 1500.

    \n
  • \n
\n

It is impossible to know in advance the MTU of each link through which\na packet might travel. Sending a datagram greater than the receiver MTU will\nnot work because the packet will get silently dropped without informing the\nsource that the data did not reach its intended recipient.\n\n

\n" }, { "textRaw": "socket.setBroadcast(flag)", "type": "method", "name": "setBroadcast", "signatures": [ { "params": [ { "textRaw": "`flag` Boolean ", "name": "flag", "desc": "Boolean" } ] }, { "params": [ { "name": "flag" } ] } ], "desc": "

Sets or clears the SO_BROADCAST socket option. When set to true, UDP\npackets may be sent to a local interface's broadcast address.\n\n

\n" }, { "textRaw": "socket.setMulticastLoopback(flag)", "type": "method", "name": "setMulticastLoopback", "signatures": [ { "params": [ { "textRaw": "`flag` Boolean ", "name": "flag", "desc": "Boolean" } ] }, { "params": [ { "name": "flag" } ] } ], "desc": "

Sets or clears the IP_MULTICAST_LOOP socket option. When set to true,\nmulticast packets will also be received on the local interface.\n\n

\n" }, { "textRaw": "socket.setMulticastTTL(ttl)", "type": "method", "name": "setMulticastTTL", "signatures": [ { "params": [ { "textRaw": "`ttl` Integer ", "name": "ttl", "desc": "Integer" } ] }, { "params": [ { "name": "ttl" } ] } ], "desc": "

Sets the IP_MULTICAST_TTL socket option. While TTL generally stands for\n"Time to Live", in this context it specifies the number of IP hops that a\npacket is allowed to travel through, specifically for multicast traffic. Each\nrouter or gateway that forwards a packet decrements the TTL. If the TTL is\ndecremented to 0 by a router, it will not be forwarded.\n\n

\n

The argument passed to to socket.setMulticastTTL() is a number of hops\nbetween 0 and 255. The default on most systems is 1 but can vary.\n\n

\n" }, { "textRaw": "socket.setTTL(ttl)", "type": "method", "name": "setTTL", "signatures": [ { "params": [ { "textRaw": "`ttl` Integer ", "name": "ttl", "desc": "Integer" } ] }, { "params": [ { "name": "ttl" } ] } ], "desc": "

Sets the IP_TTL socket option. While TTL generally stands for "Time to Live",\nin this context it specifies the number of IP hops that a packet is allowed to\ntravel through. Each router or gateway that forwards a packet decrements the\nTTL. If the TTL is decremented to 0 by a router, it will not be forwarded.\nChanging TTL values is typically done for network probes or when multicasting.\n\n

\n

The argument to socket.setTTL() is a number of hops between 1 and 255.\nThe default on most systems is 64 but can vary.\n\n

\n" }, { "textRaw": "socket.ref()", "type": "method", "name": "ref", "desc": "

By default, binding a socket will cause it to block the Node.js process from\nexiting as long as the socket is open. The socket.unref() method can be used\nto exclude the socket from the reference counting that keeps the Node.js\nprocess active. The socket.ref() method adds the socket back to the reference\ncounting and restores the default behavior.\n\n

\n

Calling socket.ref() multiples times will have no additional effect.\n\n

\n

The socket.ref() method returns a reference to the socket so calls can be\nchained.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.unref()", "type": "method", "name": "unref", "desc": "

By default, binding a socket will cause it to block the Node.js process from\nexiting as long as the socket is open. The socket.unref() method can be used\nto exclude the socket from the reference counting that keeps the Node.js\nprocess active, allowing the process to exit even if the socket is still\nlistening.\n\n

\n

Calling socket.unref() multiple times will have no addition effect.\n\n

\n

The socket.unref() method returns a reference to the socket so calls can be\nchained.\n\n

\n", "signatures": [ { "params": [] } ] } ], "modules": [ { "textRaw": "[socket.bind([port][, address][, callback])]", "name": "[socket.bind([port][,_address][,_callback])]", "desc": "

For UDP sockets, causes the dgram.Socket to listen for datagram messages on a\nnamed port and optional address. If port is not specified, the operating\nsystem will attempt to bind to a random port. If address is not specified,\nthe operating system will attempt to listen on all addresses. Once binding is\ncomplete, a 'listening' event is emitted and the optional callback function\nis called.\n\n

\n

Note that specifying both a 'listening' event listener and passing a\ncallback to the socket.bind() method is not harmful but not very\nuseful.\n\n

\n

A bound datagram socket keeps the Node.js process running to receive\ndatagram messages.\n\n

\n

If binding fails, an 'error' event is generated. In rare case (e.g.\nattempting to bind with a closed socket), an [Error][] may be thrown.\n\n

\n

Example of a UDP server listening on port 41234:\n\n

\n
const dgram = require('dgram');\nconst server = dgram.createSocket('udp4');\n\nserver.on('error', (err) => {\n  console.log(`server error:\\n${err.stack}`);\n  server.close();\n});\n\nserver.on('message', (msg, rinfo) => {\n  console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);\n});\n\nserver.on('listening', () => {\n  var address = server.address();\n  console.log(`server listening ${address.address}:${address.port}`);\n});\n\nserver.bind(41234);\n// server listening 0.0.0.0:41234
\n", "type": "module", "displayName": "[socket.bind([port][, address][, callback])]" }, { "textRaw": "Change to asynchronous `socket.bind()` behavior", "name": "change_to_asynchronous_`socket.bind()`_behavior", "desc": "

As of Node.js v0.10, [dgram.Socket#bind()][] changed to an asynchronous\nexecution model. Legacy code that assumes synchronous behavior, as in the\nfollowing example:\n\n

\n
const s = dgram.createSocket('udp4');\ns.bind(1234);\ns.addMembership('224.0.0.114');
\n

Must be changed to pass a callback function to the [dgram.Socket#bind()][]\nfunction:\n\n

\n
const s = dgram.createSocket('udp4');\ns.bind(1234, () => {\n  s.addMembership('224.0.0.114');\n});
\n", "type": "module", "displayName": "Change to asynchronous `socket.bind()` behavior" } ] } ], "modules": [ { "textRaw": "`dgram` module functions", "name": "`dgram`_module_functions", "methods": [ { "textRaw": "dgram.createSocket(options[, callback])", "type": "method", "name": "createSocket", "signatures": [ { "return": { "textRaw": "Returns: Socket object ", "name": "return", "desc": "Socket object" }, "params": [ { "textRaw": "`options` Object ", "name": "options", "desc": "Object" }, { "textRaw": "`callback` Function. Attached as a listener to `'message'` events. ", "name": "callback", "desc": "Function. Attached as a listener to `'message'` events.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

Creates a dgram.Socket object. The options argument is an object that\nshould contain a type field of either udp4 or udp6 and an optional\nboolean reuseAddr field.\n\n

\n

When reuseAddr is true [socket.bind()][] will reuse the address, even if\nanother process has already bound a socket on it. reuseAddr defaults to\nfalse. An optional callback function can be passed specified which is added\nas a listener for 'message' events.\n\n

\n

Once the socket is created, calling [socket.bind()][] will instruct the\nsocket to begin listening for datagram messages. When address and port are\nnot passed to [socket.bind()][] the method will bind the socket to the "all\ninterfaces" address on a random port (it does the right thing for both udp4\nand udp6 sockets). The bound address and port can be retrieved using\n[socket.address().address][] and [socket.address().port][].\n\n

\n" } ], "type": "module", "displayName": "`dgram` module functions" } ], "methods": [ { "textRaw": "dgram.createSocket(type[, callback])", "type": "method", "name": "createSocket", "signatures": [ { "return": { "textRaw": "Returns: Socket object ", "name": "return", "desc": "Socket object" }, "params": [ { "textRaw": "`type` String. Either 'udp4' or 'udp6' ", "name": "type", "desc": "String. Either 'udp4' or 'udp6'" }, { "textRaw": "`callback` Function. Attached as a listener to `'message'` events. Optional ", "name": "callback", "optional": true, "desc": "Function. Attached as a listener to `'message'` events." } ] }, { "params": [ { "name": "type" }, { "name": "callback", "optional": true } ] } ], "desc": "

Creates a dgram.Socket object of the specified type. The type argument\ncan be either udp4 or udp6. An optional callback function can be passed\nwhich is added as a listener for 'message' events.\n\n

\n

Once the socket is created, calling [socket.bind()][] will instruct the\nsocket to begin listening for datagram messages. When address and port are\nnot passed to [socket.bind()][] the method will bind the socket to the "all\ninterfaces" address on a random port (it does the right thing for both udp4\nand udp6 sockets). The bound address and port can be retrieved using\n[socket.address().address][] and [socket.address().port][].\n\n

\n" } ], "type": "module", "displayName": "dgram" } ] } node-v4.2.6/doc/api/dgram.markdown000644 000766 000024 00000036222 12650222326 017127 0ustar00iojsstaff000000 000000 # UDP / Datagram Sockets Stability: 2 - Stable The `dgram` module provides an implementation of UDP Datagram sockets. const dgram = require('dgram'); const server = dgram.createSocket('udp4'); server.on('error', (err) => { console.log(`server error:\n${err.stack}`); server.close(); }); server.on('message', (msg, rinfo) => { console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); }); server.on('listening', () => { var address = server.address(); console.log(`server listening ${address.address}:${address.port}`); }); server.bind(41234); // server listening 0.0.0.0:41234 ## Class: dgram.Socket The `dgram.Socket` object is an [`EventEmitter`][] that encapsulates the datagram functionality. New instances of `dgram.Socket` are created using [`dgram.createSocket()`][]. The `new` keyword is not to be used to create `dgram.Socket` instances. ### Event: 'close' The `'close'` event is emitted after a socket is closed with [`close()`][]. Once triggered, no new `'message'` events will be emitted on this socket. ### Event: 'error' * `exception` Error object The `'error'` event is emitted whenever any error occurs. The event handler function is passed a single Error object. ### Event: 'listening' The `'listening'` event is emitted whenever a socket begins listening for datagram messages. This occurs as soon as UDP sockets are created. ### Event: 'message' * `msg` Buffer object. The message * `rinfo` Object. Remote address information The `'message'` event is emitted when a new datagram is available on a socket. The event handler function is passed two arguments: `msg` and `rinfo`. The `msg` argument is a [`Buffer`][] and `rinfo` is an object with the sender's address information provided by the `address`, `family` and `port` properties: socket.on('message', (msg, rinfo) => { console.log('Received %d bytes from %s:%d\n', msg.length, rinfo.address, rinfo.port); }); ### socket.addMembership(multicastAddress[, multicastInterface]) * `multicastAddress` String * `multicastInterface` String, Optional Tells the kernel to join a multicast group at the given `multicastAddress` using the `IP_ADD_MEMBERSHIP` socket option. If the `multicastInterface` argument is not specified, the operating system will try to add membership to all valid networking interfaces. ### socket.address() Returns an object containing the address information for a socket. For UDP sockets, this object will contain `address`, `family` and `port` properties. ### [socket.bind([port][, address][, callback])] * `port` Integer, Optional * `address` String, Optional * `callback` Function with no parameters, Optional. Called when binding is complete. For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a named `port` and optional `address`. If `port` is not specified, the operating system will attempt to bind to a random port. If `address` is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a `'listening'` event is emitted and the optional `callback` function is called. Note that specifying both a `'listening'` event listener and passing a `callback` to the `socket.bind()` method is not harmful but not very useful. A bound datagram socket keeps the Node.js process running to receive datagram messages. If binding fails, an `'error'` event is generated. In rare case (e.g. attempting to bind with a closed socket), an [`Error`][] may be thrown. Example of a UDP server listening on port 41234: const dgram = require('dgram'); const server = dgram.createSocket('udp4'); server.on('error', (err) => { console.log(`server error:\n${err.stack}`); server.close(); }); server.on('message', (msg, rinfo) => { console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`); }); server.on('listening', () => { var address = server.address(); console.log(`server listening ${address.address}:${address.port}`); }); server.bind(41234); // server listening 0.0.0.0:41234 ### socket.bind(options[, callback]) * `options` {Object} - Required. Supports the following properties: * `port` {Number} - Required. * `address` {String} - Optional. * `exclusive` {Boolean} - Optional. * `callback` {Function} - Optional. For UDP sockets, causes the `dgram.Socket` to listen for datagram messages on a named `port` and optional `address` that are passed as properties of an `options` object passed as the first argument. If `port` is not specified, the operating system will attempt to bind to a random port. If `address` is not specified, the operating system will attempt to listen on all addresses. Once binding is complete, a `'listening'` event is emitted and the optional `callback` function is called. The `options` object may contain an additional `exclusive` property that is use when using `dgram.Socket` objects with the [`cluster`] module. When `exclusive` is set to `false` (the default), cluster workers will use the same underlying socket handle allowing connection handling duties to be shared. When `exclusive` is `true`, however, the handle is not shared and attempted port sharing results in an error. An example socket listening on an exclusive port is shown below. socket.bind({ address: 'localhost', port: 8000, exclusive: true }); ### socket.close([callback]) Close the underlying socket and stop listening for data on it. If a callback is provided, it is added as a listener for the [`'close'`][] event. ### socket.dropMembership(multicastAddress[, multicastInterface]) * `multicastAddress` String * `multicastInterface` String, Optional Instructs the kernel to leave a multicast group at `multicastAddress` using the `IP_DROP_MEMBERSHIP` socket option. This method is automatically called by the kernel when the socket is closed or the process terminates, so most apps will never have reason to call this. If `multicastInterface` is not specified, the operating system will attempt to drop membership on all valid interfaces. ### socket.send(buf, offset, length, port, address[, callback]) * `buf` Buffer object or string. Message to be sent * `offset` Integer. Offset in the buffer where the message starts. * `length` Integer. Number of bytes in the message. * `port` Integer. Destination port. * `address` String. Destination hostname or IP address. * `callback` Function. Called when the message has been sent. Optional. Broadcasts a datagram on the socket. The destination `port` and `address` must be specified. The `buf` argument is a [`Buffer`] object containing the message. The `offset` and `length` specify the offset within the `Buffer` where the message begins and the number of bytes in the message, respectively. With messages that contain multi-byte characters, `offset` and `length` will be calculated with respect to [byte length][] and not the character position. The `address` argument is a string. If the value of `address` is a host name, DNS will be used to resolve the address of the host. If the `address` is not specified or is an empty string, `'0.0.0.0'` or `'::0'` will be used instead. It is possible, depending on the network configuration, that these defaults may not work; accordingly, it is best to be explicit about the destination address. If the socket has not been previously bound with a call to `bind`, the socket is assigned a random port number and is bound to the "all interfaces" address (`'0.0.0.0'` for `udp4` sockets, `'::0'` for `udp6` sockets.) An optional `callback` function may be specified to as a way of reporting DNS errors or for determining when it is safe to reuse the `buf` object. Note that DNS lookups delay the time to send for at least one tick of the Node.js event loop. The only way to know for sure that the datagram has been sent is by using a `callback`. If an error occurs and a `callback` is given, the error will be passed as the first argument to the `callback`. If a `callback` is not given, the error is emitted as an `'error'` event on the `socket` object. Example of sending a UDP packet to a random port on `localhost`; const dgram = require('dgram'); const message = new Buffer('Some bytes'); const client = dgram.createSocket('udp4'); client.send(message, 0, message.length, 41234, 'localhost', (err) => { client.close(); }); **A Note about UDP datagram size** The maximum size of an `IPv4/v6` datagram depends on the `MTU` (_Maximum Transmission Unit_) and on the `Payload Length` field size. - The `Payload Length` field is `16 bits` wide, which means that a normal payload exceed 64K octets _including_ the internet header and data (65,507 bytes = 65,535 − 8 bytes UDP header − 20 bytes IP header); this is generally true for loopback interfaces, but such long datagram messages are impractical for most hosts and networks. - The `MTU` is the largest size a given link layer technology can support for datagram messages. For any link, `IPv4` mandates a minimum `MTU` of `68` octets, while the recommended `MTU` for IPv4 is `576` (typically recommended as the `MTU` for dial-up type applications), whether they arrive whole or in fragments. For `IPv6`, the minimum `MTU` is `1280` octets, however, the mandatory minimum fragment reassembly buffer size is `1500` octets. The value of `68` octets is very small, since most current link layer technologies, like Ethernet, have a minimum `MTU` of `1500`. It is impossible to know in advance the MTU of each link through which a packet might travel. Sending a datagram greater than the receiver `MTU` will not work because the packet will get silently dropped without informing the source that the data did not reach its intended recipient. ### socket.setBroadcast(flag) * `flag` Boolean Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP packets may be sent to a local interface's broadcast address. ### socket.setMulticastLoopback(flag) * `flag` Boolean Sets or clears the `IP_MULTICAST_LOOP` socket option. When set to `true`, multicast packets will also be received on the local interface. ### socket.setMulticastTTL(ttl) * `ttl` Integer Sets the `IP_MULTICAST_TTL` socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through, specifically for multicast traffic. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. The argument passed to to `socket.setMulticastTTL()` is a number of hops between 0 and 255. The default on most systems is `1` but can vary. ### socket.setTTL(ttl) * `ttl` Integer Sets the `IP_TTL` socket option. While TTL generally stands for "Time to Live", in this context it specifies the number of IP hops that a packet is allowed to travel through. Each router or gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a router, it will not be forwarded. Changing TTL values is typically done for network probes or when multicasting. The argument to `socket.setTTL()` is a number of hops between 1 and 255. The default on most systems is 64 but can vary. ### socket.ref() By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The `socket.unref()` method can be used to exclude the socket from the reference counting that keeps the Node.js process active. The `socket.ref()` method adds the socket back to the reference counting and restores the default behavior. Calling `socket.ref()` multiples times will have no additional effect. The `socket.ref()` method returns a reference to the socket so calls can be chained. ### socket.unref() By default, binding a socket will cause it to block the Node.js process from exiting as long as the socket is open. The `socket.unref()` method can be used to exclude the socket from the reference counting that keeps the Node.js process active, allowing the process to exit even if the socket is still listening. Calling `socket.unref()` multiple times will have no addition effect. The `socket.unref()` method returns a reference to the socket so calls can be chained. ### Change to asynchronous `socket.bind()` behavior As of Node.js v0.10, [`dgram.Socket#bind()`][] changed to an asynchronous execution model. Legacy code that assumes synchronous behavior, as in the following example: const s = dgram.createSocket('udp4'); s.bind(1234); s.addMembership('224.0.0.114'); Must be changed to pass a callback function to the [`dgram.Socket#bind()`][] function: const s = dgram.createSocket('udp4'); s.bind(1234, () => { s.addMembership('224.0.0.114'); }); ## `dgram` module functions ### dgram.createSocket(options[, callback]) * `options` Object * `callback` Function. Attached as a listener to `'message'` events. * Returns: Socket object Creates a `dgram.Socket` object. The `options` argument is an object that should contain a `type` field of either `udp4` or `udp6` and an optional boolean `reuseAddr` field. When `reuseAddr` is `true` [`socket.bind()`][] will reuse the address, even if another process has already bound a socket on it. `reuseAddr` defaults to `false`. An optional `callback` function can be passed specified which is added as a listener for `'message'` events. Once the socket is created, calling [`socket.bind()`][] will instruct the socket to begin listening for datagram messages. When `address` and `port` are not passed to [`socket.bind()`][] the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both `udp4` and `udp6` sockets). The bound address and port can be retrieved using [`socket.address().address`][] and [`socket.address().port`][]. ## dgram.createSocket(type[, callback]) * `type` String. Either 'udp4' or 'udp6' * `callback` Function. Attached as a listener to `'message'` events. Optional * Returns: Socket object Creates a `dgram.Socket` object of the specified `type`. The `type` argument can be either `udp4` or `udp6`. An optional `callback` function can be passed which is added as a listener for `'message'` events. Once the socket is created, calling [`socket.bind()`][] will instruct the socket to begin listening for datagram messages. When `address` and `port` are not passed to [`socket.bind()`][] the method will bind the socket to the "all interfaces" address on a random port (it does the right thing for both `udp4` and `udp6` sockets). The bound address and port can be retrieved using [`socket.address().address`][] and [`socket.address().port`][]. [`EventEmitter`]: events.html [`Buffer`]: buffer.html [`'close'`]: #dgram_event_close [`addMembership()`]: #dgram_socket_addmembership_multicastaddress_multicastinterface [`close()`]: #dgram_socket_close_callback [`dgram.createSocket()`]: #dgram_dgram_createsocket_options_callback [`dgram.Socket#bind()`]: #dgram_socket_bind_options_callback [`Error`]: errors.html#errors_class_error [`socket.address().address`]: #dgram_socket_address [`socket.address().port`]: #dgram_socket_address [`socket.bind()`]: #dgram_socket_bind_port_address_callback [byte length]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding node-v4.2.6/doc/api/dns.html000644 000766 000024 00000061370 12650222331 015741 0ustar00iojsstaff000000 000000 DNS Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


DNS#

Stability: 2 - Stable

The dns module contains functions belonging to two different categories:

1) Functions that use the underlying operating system facilities to perform name resolution, and that do not necessarily perform any network communication. This category contains only one function: dns.lookup(). Developers looking to perform name resolution in the same way that other applications on the same operating system behave should use dns.lookup().

For example, looking up nodejs.org.

const dns = require('dns');

dns.lookup('nodejs.org', (err, addresses, family) => {
  console.log('addresses:', addresses);
});

2) Functions that connect to an actual DNS server to perform name resolution, and that always use the network to perform DNS queries. This category contains all functions in the dns module except dns.lookup(). These functions do not use the same set of configuration files used by dns.lookup() (e.g. /etc/hosts). These functions should be used by developers who do not want to use the underlying operating system's facilities for name resolution, and instead want to always perform DNS queries.

Below is an example that resolves 'nodejs.org' then reverse resolves the IP addresses that are returned.

const dns = require('dns');

dns.resolve4('nodejs.org', (err, addresses) => {
  if (err) throw err;

  console.log(`addresses: ${JSON.stringify(addresses)}`);

  addresses.forEach((a) => {
    dns.reverse(a, (err, hostnames) => {
      if (err) {
        throw err;
      }
      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
    });
  });
});

There are subtle consequences in choosing one over the other, please consult the Implementation considerations section for more information.

dns.getServers()#

Returns an array of IP address strings that are being used for name resolution.

dns.lookup(hostname[, options], callback)#

Resolves a hostname (e.g. 'nodejs.org') into the first found A (IPv4) or AAAA (IPv6) record. options can be an object or integer. If options is not provided, then IPv4 and IPv6 addresses are both valid. If options is an integer, then it must be 4 or 6.

Alternatively, options can be an object containing these properties:

  • family {Number} - The record family. If present, must be the integer 4 or 6. If not provided, both IP v4 and v6 addresses are accepted.
  • hints: {Number} - If present, it should be one or more of the supported getaddrinfo flags. If hints is not provided, then no flags are passed to getaddrinfo. Multiple flags can be passed through hints by logically ORing their values. See supported getaddrinfo flags below for more information on supported flags.
  • all: {Boolean} - When true, the callback returns all resolved addresses in an array, otherwise returns a single address. Defaults to false.

All properties are optional. An example usage of options is shown below.

{
  family: 4,
  hints: dns.ADDRCONFIG | dns.V4MAPPED,
  all: false
}

The callback function has arguments (err, address, family). address is a string representation of an IPv4 or IPv6 address. family is either the integer 4 or 6 and denotes the family of address (not necessarily the value initially passed to lookup).

With the all option set to true, the arguments change to (err, addresses), with addresses being an array of objects with the properties address and family.

On error, err is an Error object, where err.code is the error code. Keep in mind that err.code will be set to 'ENOENT' not only when the hostname does not exist but also when the lookup fails in other ways such as no available file descriptors.

dns.lookup() does not necessarily have anything to do with the DNS protocol. The implementation uses an operating system facility that can associate names with addresses, and vice versa. This implementation can have subtle but important consequences on the behavior of any Node.js program. Please take some time to consult the Implementation considerations section before using dns.lookup().

Supported getaddrinfo flags#

The following flags can be passed as hints to dns.lookup().

  • dns.ADDRCONFIG: Returned address types are determined by the types of addresses supported by the current system. For example, IPv4 addresses are only returned if the current system has at least one IPv4 address configured. Loopback addresses are not considered.
  • dns.V4MAPPED: If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. Note that it is not supported on some operating systems (e.g FreeBSD 10.1).

dns.lookupService(address, port, callback)#

Resolves the given address and port into a hostname and service using the operating system's underlying getnameinfo implementation.

The callback has arguments (err, hostname, service). The hostname and service arguments are strings (e.g. 'localhost' and 'http' respectively).

On error, err is an Error object, where err.code is the error code.

const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
  console.log(hostname, service);
    // Prints: localhost ssh
});

dns.resolve(hostname[, rrtype], callback)#

Uses the DNS protocol to resolve a hostname (e.g. 'nodejs.org') into an array of the record types specified by rrtype.

Valid values for rrtype are:

  • 'A' - IPV4 addresses, default
  • 'AAAA' - IPV6 addresses
  • 'MX' - mail exchange records
  • 'TXT' - text records
  • 'SRV' - SRV records
  • 'PTR' - used for reverse IP lookups
  • 'NS' - name server records
  • 'CNAME' - canonical name records
  • 'SOA' - start of authority record

The callback function has arguments (err, addresses). When successful, addresses will be an array. The type of each item in addresses is determined by the record type, and described in the documentation for the corresponding lookup methods below.

On error, err is an Error object, where err.code is one of the error codes listed below.

dns.resolve4(hostname, callback)#

Uses the DNS protocol to resolve a IPv4 addresses (A records) for the hostname. The addresses argument passed to the callback function will contain an array of IPv4 addresses (e.g. ['74.125.79.104', '74.125.79.105', '74.125.79.106']).

dns.resolve6(hostname, callback)#

Uses the DNS protocol to resolve a IPv6 addresses (AAAA records) for the hostname. The addresses argument passed to the callback function will contain an array of IPv6 addresses.

dns.resolveCname(hostname, callback)#

Uses the DNS protocol to resolve CNAME records for the hostname. The addresses argument passed to the callback function will contain an of canonical name records available for the hostname (e.g. ['bar.example.com']).

dns.resolveMx(hostname, callback)#

Uses the DNS protocol to resolve mail exchange records (MX records) for the hostname. The addresses argument passed to the callback function will contain an array of objects containing both a priority and exchange property (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).

dns.resolveNs(hostname, callback)#

Uses the DNS protocol to resolve name server records (NS records) for the hostname. The addresses argument passed to the callback function will contain an array of name server records available for hostname (e.g., ['ns1.example.com', 'ns2.example.com']).

dns.resolveSoa(hostname, callback)#

Uses the DNS protocol to resolve a start of authority record (SOA record) for the hostname. The addresses argument passed to the callback function will be an object with the following properties:

  • nsname
  • hostmaster
  • serial
  • refresh
  • retry
  • expire
  • minttl

    {

    nsname: 'ns.example.com',
    hostmaster: 'root.example.com',
    serial: 2013101809,
    refresh: 10000,
    retry: 2400,
    expire: 604800,
    minttl: 3600

    }

dns.resolveSrv(hostname, callback)#

Uses the DNS protocol to resolve service records (SRV records) for the hostname. The addresses argument passed to the callback function will be an array of objects with the following properties:

  • priority
  • weight
  • port
  • name

    {

    priority: 10,
    weight: 5,
    port: 21223,
    name: 'service.example.com'

    }

dns.resolveTxt(hostname, callback)#

Uses the DNS protocol to resolve text queries (TXT records) for the hostname. The addresses argument passed to the callback function is is a two-dimentional array of the text records available for hostname (e.g., [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately.

dns.reverse(ip, callback)#

Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of hostnames.

The callback function has arguments (err, hostnames), where hostnames is an array of resolved hostnames for the given ip.

On error, err is an Error object, where err.code is one of the error codes listed below.

dns.setServers(servers)#

Sets the IP addresses of the servers to be used when resolving. The servers argument is an array of IPv4 or IPv6 addresses.

If a port specified on the address it will be removed.

An error will be thrown if an invalid address is provided.

The dns.setServers() method must not be called while a DNS query is in progress.

Error codes#

Each DNS query can return one of the following error codes:

  • dns.NODATA: DNS server returned answer with no data.
  • dns.FORMERR: DNS server claims query was misformatted.
  • dns.SERVFAIL: DNS server returned general failure.
  • dns.NOTFOUND: Domain name not found.
  • dns.NOTIMP: DNS server does not implement requested operation.
  • dns.REFUSED: DNS server refused query.
  • dns.BADQUERY: Misformatted DNS query.
  • dns.BADNAME: Misformatted hostname.
  • dns.BADFAMILY: Unsupported address family.
  • dns.BADRESP: Misformatted DNS reply.
  • dns.CONNREFUSED: Could not contact DNS servers.
  • dns.TIMEOUT: Timeout while contacting DNS servers.
  • dns.EOF: End of file.
  • dns.FILE: Error reading file.
  • dns.NOMEM: Out of memory.
  • dns.DESTRUCTION: Channel is being destroyed.
  • dns.BADSTR: Misformatted string.
  • dns.BADFLAGS: Illegal flags specified.
  • dns.NONAME: Given hostname is not numeric.
  • dns.BADHINTS: Illegal hints flags specified.
  • dns.NOTINITIALIZED: c-ares library initialization not yet performed.
  • dns.LOADIPHLPAPI: Error loading iphlpapi.dll.
  • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
  • dns.CANCELLED: DNS query cancelled.

Implementation considerations#

Although dns.lookup() and the various dns.resolve*()/dns.reverse() functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs.

dns.lookup()#

Under the hood, dns.lookup() uses the same operating system facilities as most other programs. For instance, dns.lookup() will almost always resolve a given name the same way as the ping command. On most POSIX-like operating systems, the behavior of the dns.lookup() function can be modified by changing settings in nsswitch.conf(5) and/or resolv.conf(5), but note that changing these files will change the behavior of all other programs running on the same operating system.

Though the call to dns.lookup() will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to getaddrinfo(3) that runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it means that if for whatever reason the call to getaddrinfo(3) takes a long time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by setting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than 4 (its current default value). For more information on libuv's threadpool, see the official libuv documentation.

dns.resolve(), dns.resolve*() and dns.reverse()#

These functions are implemented quite differently than dns.lookup(). They do not use getaddrinfo(3) and they always perform a DNS query on the network. This network communication is always done asynchronously, and does not use libuv's threadpool.

As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that dns.lookup() can have.

They do not use the same set of configuration files than what dns.lookup() uses. For instance, they do not use the configuration from /etc/hosts.

node-v4.2.6/doc/api/dns.json000644 000766 000024 00000055617 12650222331 015755 0ustar00iojsstaff000000 000000 { "source": "doc/api/dns.markdown", "modules": [ { "textRaw": "DNS", "name": "dns", "stability": 2, "stabilityText": "Stable", "desc": "

The dns module contains functions belonging to two different categories:\n\n

\n

1) Functions that use the underlying operating system facilities to perform\nname resolution, and that do not necessarily perform any network communication.\nThis category contains only one function: [dns.lookup()][]. Developers\nlooking to perform name resolution in the same way that other applications on\nthe same operating system behave should use [dns.lookup()][].\n\n

\n

For example, looking up nodejs.org.\n\n

\n
const dns = require('dns');\n\ndns.lookup('nodejs.org', (err, addresses, family) => {\n  console.log('addresses:', addresses);\n});
\n

2) Functions that connect to an actual DNS server to perform name resolution,\nand that always use the network to perform DNS queries. This category\ncontains all functions in the dns module except [dns.lookup()][]. These\nfunctions do not use the same set of configuration files used by\n[dns.lookup()][] (e.g. /etc/hosts). These functions should be used by\ndevelopers who do not want to use the underlying operating system's facilities\nfor name resolution, and instead want to always perform DNS queries.\n\n

\n

Below is an example that resolves 'nodejs.org' then reverse resolves the IP\naddresses that are returned.\n\n

\n
const dns = require('dns');\n\ndns.resolve4('nodejs.org', (err, addresses) => {\n  if (err) throw err;\n\n  console.log(`addresses: ${JSON.stringify(addresses)}`);\n\n  addresses.forEach((a) => {\n    dns.reverse(a, (err, hostnames) => {\n      if (err) {\n        throw err;\n      }\n      console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);\n    });\n  });\n});
\n

There are subtle consequences in choosing one over the other, please consult\nthe [Implementation considerations section][] for more information.\n\n

\n", "methods": [ { "textRaw": "dns.getServers()", "type": "method", "name": "getServers", "desc": "

Returns an array of IP address strings that are being used for name\nresolution.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "dns.lookup(hostname[, options], callback)", "type": "method", "name": "lookup", "desc": "

Resolves a hostname (e.g. 'nodejs.org') into the first found A (IPv4) or\nAAAA (IPv6) record. options can be an object or integer. If options is\nnot provided, then IPv4 and IPv6 addresses are both valid. If options is\nan integer, then it must be 4 or 6.\n\n

\n

Alternatively, options can be an object containing these properties:\n\n

\n
    \n
  • family {Number} - The record family. If present, must be the integer\n4 or 6. If not provided, both IP v4 and v6 addresses are accepted.
  • \n
  • hints: {Number} - If present, it should be one or more of the supported\ngetaddrinfo flags. If hints is not provided, then no flags are passed to\ngetaddrinfo. Multiple flags can be passed through hints by logically\nORing their values.\nSee [supported getaddrinfo flags][] below for more information on supported\nflags.
  • \n
  • all: {Boolean} - When true, the callback returns all resolved addresses\nin an array, otherwise returns a single address. Defaults to false.
  • \n
\n

All properties are optional. An example usage of options is shown below.\n\n

\n
{\n  family: 4,\n  hints: dns.ADDRCONFIG | dns.V4MAPPED,\n  all: false\n}
\n

The callback function has arguments (err, address, family). address is a\nstring representation of an IPv4 or IPv6 address. family is either the\ninteger 4 or 6 and denotes the family of address (not necessarily the\nvalue initially passed to lookup).\n\n

\n

With the all option set to true, the arguments change to\n(err, addresses), with addresses being an array of objects with the\nproperties address and family.\n\n

\n

On error, err is an [Error][] object, where err.code is the error code.\nKeep in mind that err.code will be set to 'ENOENT' not only when\nthe hostname does not exist but also when the lookup fails in other ways\nsuch as no available file descriptors.\n\n

\n

dns.lookup() does not necessarily have anything to do with the DNS protocol.\nThe implementation uses an operating system facility that can associate names\nwith addresses, and vice versa. This implementation can have subtle but\nimportant consequences on the behavior of any Node.js program. Please take some\ntime to consult the [Implementation considerations section][] before using\ndns.lookup().\n\n

\n", "modules": [ { "textRaw": "Supported getaddrinfo flags", "name": "supported_getaddrinfo_flags", "desc": "

The following flags can be passed as hints to [dns.lookup()][].\n\n

\n
    \n
  • dns.ADDRCONFIG: Returned address types are determined by the types\nof addresses supported by the current system. For example, IPv4 addresses\nare only returned if the current system has at least one IPv4 address\nconfigured. Loopback addresses are not considered.
  • \n
  • dns.V4MAPPED: If the IPv6 family was specified, but no IPv6 addresses were\nfound, then return IPv4 mapped IPv6 addresses. Note that it is not supported\non some operating systems (e.g FreeBSD 10.1).
  • \n
\n", "type": "module", "displayName": "Supported getaddrinfo flags" } ], "signatures": [ { "params": [ { "name": "hostname" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "dns.lookupService(address, port, callback)", "type": "method", "name": "lookupService", "desc": "

Resolves the given address and port into a hostname and service using\nthe operating system's underlying getnameinfo implementation.\n\n

\n

The callback has arguments (err, hostname, service). The hostname and\nservice arguments are strings (e.g. 'localhost' and 'http' respectively).\n\n

\n

On error, err is an [Error][] object, where err.code is the error code.\n\n

\n
const dns = require('dns');\ndns.lookupService('127.0.0.1', 22, (err, hostname, service) => {\n  console.log(hostname, service);\n    // Prints: localhost ssh\n});
\n", "signatures": [ { "params": [ { "name": "address" }, { "name": "port" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve(hostname[, rrtype], callback)", "type": "method", "name": "resolve", "desc": "

Uses the DNS protocol to resolve a hostname (e.g. 'nodejs.org') into an\narray of the record types specified by rrtype.\n\n

\n

Valid values for rrtype are:\n\n

\n
    \n
  • 'A' - IPV4 addresses, default
  • \n
  • 'AAAA' - IPV6 addresses
  • \n
  • 'MX' - mail exchange records
  • \n
  • 'TXT' - text records
  • \n
  • 'SRV' - SRV records
  • \n
  • 'PTR' - used for reverse IP lookups
  • \n
  • 'NS' - name server records
  • \n
  • 'CNAME' - canonical name records
  • \n
  • 'SOA' - start of authority record
  • \n
\n

The callback function has arguments (err, addresses). When successful,\naddresses will be an array. The type of each item in addresses is\ndetermined by the record type, and described in the documentation for the\ncorresponding lookup methods below.\n\n

\n

On error, err is an [Error][] object, where err.code is\none of the error codes listed below.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "rrtype", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve4(hostname, callback)", "type": "method", "name": "resolve4", "desc": "

Uses the DNS protocol to resolve a IPv4 addresses (A records) for the\nhostname. The addresses argument passed to the callback function\nwill contain an array of IPv4 addresses (e.g.\n['74.125.79.104', '74.125.79.105', '74.125.79.106']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolve6(hostname, callback)", "type": "method", "name": "resolve6", "desc": "

Uses the DNS protocol to resolve a IPv6 addresses (AAAA records) for the\nhostname. The addresses argument passed to the callback function\nwill contain an array of IPv6 addresses.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveCname(hostname, callback)", "type": "method", "name": "resolveCname", "desc": "

Uses the DNS protocol to resolve CNAME records for the hostname. The\naddresses argument passed to the callback function\nwill contain an of canonical name records available for the hostname\n(e.g. ['bar.example.com']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveMx(hostname, callback)", "type": "method", "name": "resolveMx", "desc": "

Uses the DNS protocol to resolve mail exchange records (MX records) for the\nhostname. The addresses argument passed to the callback function will\ncontain an array of objects containing both a priority and exchange\nproperty (e.g. [{priority: 10, exchange: 'mx.example.com'}, ...]).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveNs(hostname, callback)", "type": "method", "name": "resolveNs", "desc": "

Uses the DNS protocol to resolve name server records (NS records) for the\nhostname. The addresses argument passed to the callback function will\ncontain an array of name server records available for hostname\n(e.g., ['ns1.example.com', 'ns2.example.com']).\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveSoa(hostname, callback)", "type": "method", "name": "resolveSoa", "desc": "

Uses the DNS protocol to resolve a start of authority record (SOA record) for\nthe hostname. The addresses argument passed to the callback function will\nbe an object with the following properties:\n\n

\n
    \n
  • nsname
  • \n
  • hostmaster
  • \n
  • serial
  • \n
  • refresh
  • \n
  • retry
  • \n
  • expire
  • \n
  • minttl

    \n

    {

    \n
    nsname: 'ns.example.com',\nhostmaster: 'root.example.com',\nserial: 2013101809,\nrefresh: 10000,\nretry: 2400,\nexpire: 604800,\nminttl: 3600
    \n

    }

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveSrv(hostname, callback)", "type": "method", "name": "resolveSrv", "desc": "

Uses the DNS protocol to resolve service records (SRV records) for the\nhostname. The addresses argument passed to the callback function will\nbe an array of objects with the following properties:\n\n

\n
    \n
  • priority
  • \n
  • weight
  • \n
  • port
  • \n
  • name

    \n

    {

    \n
    priority: 10,\nweight: 5,\nport: 21223,\nname: 'service.example.com'
    \n

    }

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.resolveTxt(hostname, callback)", "type": "method", "name": "resolveTxt", "desc": "

Uses the DNS protocol to resolve text queries (TXT records) for the\nhostname. The addresses argument passed to the callback function is\nis a two-dimentional array of the text records available for hostname (e.g.,\n[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Each sub-array contains TXT chunks of\none record. Depending on the use case, these could be either joined together or\ntreated separately.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.reverse(ip, callback)", "type": "method", "name": "reverse", "desc": "

Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an\narray of hostnames.\n\n

\n

The callback function has arguments (err, hostnames), where hostnames\nis an array of resolved hostnames for the given ip.\n\n

\n

On error, err is an [Error][] object, where err.code is\none of the error codes listed below.\n\n

\n", "signatures": [ { "params": [ { "name": "ip" }, { "name": "callback" } ] } ] }, { "textRaw": "dns.setServers(servers)", "type": "method", "name": "setServers", "desc": "

Sets the IP addresses of the servers to be used when resolving. The servers\nargument is an array of IPv4 or IPv6 addresses.\n\n

\n

If a port specified on the address it will be removed.\n\n

\n

An error will be thrown if an invalid address is provided.\n\n

\n

The dns.setServers() method must not be called while a DNS query is in\nprogress.\n\n

\n", "signatures": [ { "params": [ { "name": "servers" } ] } ] } ], "modules": [ { "textRaw": "Error codes", "name": "error_codes", "desc": "

Each DNS query can return one of the following error codes:\n\n

\n
    \n
  • dns.NODATA: DNS server returned answer with no data.
  • \n
  • dns.FORMERR: DNS server claims query was misformatted.
  • \n
  • dns.SERVFAIL: DNS server returned general failure.
  • \n
  • dns.NOTFOUND: Domain name not found.
  • \n
  • dns.NOTIMP: DNS server does not implement requested operation.
  • \n
  • dns.REFUSED: DNS server refused query.
  • \n
  • dns.BADQUERY: Misformatted DNS query.
  • \n
  • dns.BADNAME: Misformatted hostname.
  • \n
  • dns.BADFAMILY: Unsupported address family.
  • \n
  • dns.BADRESP: Misformatted DNS reply.
  • \n
  • dns.CONNREFUSED: Could not contact DNS servers.
  • \n
  • dns.TIMEOUT: Timeout while contacting DNS servers.
  • \n
  • dns.EOF: End of file.
  • \n
  • dns.FILE: Error reading file.
  • \n
  • dns.NOMEM: Out of memory.
  • \n
  • dns.DESTRUCTION: Channel is being destroyed.
  • \n
  • dns.BADSTR: Misformatted string.
  • \n
  • dns.BADFLAGS: Illegal flags specified.
  • \n
  • dns.NONAME: Given hostname is not numeric.
  • \n
  • dns.BADHINTS: Illegal hints flags specified.
  • \n
  • dns.NOTINITIALIZED: c-ares library initialization not yet performed.
  • \n
  • dns.LOADIPHLPAPI: Error loading iphlpapi.dll.
  • \n
  • dns.ADDRGETNETWORKPARAMS: Could not find GetNetworkParams function.
  • \n
  • dns.CANCELLED: DNS query cancelled.
  • \n
\n", "type": "module", "displayName": "Error codes" }, { "textRaw": "Implementation considerations", "name": "implementation_considerations", "desc": "

Although [dns.lookup()][] and the various dns.resolve*()/dns.reverse()\nfunctions have the same goal of associating a network name with a network\naddress (or vice versa), their behavior is quite different. These differences\ncan have subtle but significant consequences on the behavior of Node.js\nprograms.\n\n

\n", "modules": [ { "textRaw": "`dns.lookup()`", "name": "`dns.lookup()`", "desc": "

Under the hood, [dns.lookup()][] uses the same operating system facilities\nas most other programs. For instance, [dns.lookup()][] will almost always\nresolve a given name the same way as the ping command. On most POSIX-like\noperating systems, the behavior of the [dns.lookup()][] function can be\nmodified by changing settings in nsswitch.conf(5) and/or resolv.conf(5),\nbut note that changing these files will change the behavior of all other\nprograms running on the same operating system.\n\n

\n

Though the call to dns.lookup() will be asynchronous from JavaScript's\nperspective, it is implemented as a synchronous call to getaddrinfo(3) that\nruns on libuv's threadpool. Because libuv's threadpool has a fixed size, it\nmeans that if for whatever reason the call to getaddrinfo(3) takes a long\ntime, other operations that could run on libuv's threadpool (such as filesystem\noperations) will experience degraded performance. In order to mitigate this\nissue, one potential solution is to increase the size of libuv's threadpool by\nsetting the 'UV_THREADPOOL_SIZE' environment variable to a value greater than\n4 (its current default value). For more information on libuv's threadpool, see\n[the official libuv documentation][].\n\n

\n", "type": "module", "displayName": "`dns.lookup()`" }, { "textRaw": "`dns.resolve()`, `dns.resolve*()` and `dns.reverse()`", "name": "`dns.resolve()`,_`dns.resolve*()`_and_`dns.reverse()`", "desc": "

These functions are implemented quite differently than [dns.lookup()][]. They\ndo not use getaddrinfo(3) and they always perform a DNS query on the\nnetwork. This network communication is always done asynchronously, and does not\nuse libuv's threadpool.\n\n

\n

As a result, these functions cannot have the same negative impact on other\nprocessing that happens on libuv's threadpool that [dns.lookup()][] can have.\n\n

\n

They do not use the same set of configuration files than what [dns.lookup()][]\nuses. For instance, they do not use the configuration from /etc/hosts.\n\n

\n", "type": "module", "displayName": "`dns.resolve()`, `dns.resolve*()` and `dns.reverse()`" } ], "type": "module", "displayName": "Implementation considerations" } ], "type": "module", "displayName": "DNS" } ] } node-v4.2.6/doc/api/dns.markdown000644 000766 000024 00000032530 12650222326 016617 0ustar00iojsstaff000000 000000 # DNS Stability: 2 - Stable The `dns` module contains functions belonging to two different categories: 1) Functions that use the underlying operating system facilities to perform name resolution, and that do not necessarily perform any network communication. This category contains only one function: [`dns.lookup()`][]. __Developers looking to perform name resolution in the same way that other applications on the same operating system behave should use [`dns.lookup()`][].__ For example, looking up `nodejs.org`. const dns = require('dns'); dns.lookup('nodejs.org', (err, addresses, family) => { console.log('addresses:', addresses); }); 2) Functions that connect to an actual DNS server to perform name resolution, and that _always_ use the network to perform DNS queries. This category contains all functions in the `dns` module _except_ [`dns.lookup()`][]. These functions do not use the same set of configuration files used by [`dns.lookup()`][] (e.g. `/etc/hosts`). These functions should be used by developers who do not want to use the underlying operating system's facilities for name resolution, and instead want to _always_ perform DNS queries. Below is an example that resolves `'nodejs.org'` then reverse resolves the IP addresses that are returned. const dns = require('dns'); dns.resolve4('nodejs.org', (err, addresses) => { if (err) throw err; console.log(`addresses: ${JSON.stringify(addresses)}`); addresses.forEach((a) => { dns.reverse(a, (err, hostnames) => { if (err) { throw err; } console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`); }); }); }); There are subtle consequences in choosing one over the other, please consult the [Implementation considerations section][] for more information. ## dns.getServers() Returns an array of IP address strings that are being used for name resolution. ## dns.lookup(hostname[, options], callback) Resolves a hostname (e.g. `'nodejs.org'`) into the first found A (IPv4) or AAAA (IPv6) record. `options` can be an object or integer. If `options` is not provided, then IPv4 and IPv6 addresses are both valid. If `options` is an integer, then it must be `4` or `6`. Alternatively, `options` can be an object containing these properties: * `family` {Number} - The record family. If present, must be the integer `4` or `6`. If not provided, both IP v4 and v6 addresses are accepted. * `hints`: {Number} - If present, it should be one or more of the supported `getaddrinfo` flags. If `hints` is not provided, then no flags are passed to `getaddrinfo`. Multiple flags can be passed through `hints` by logically `OR`ing their values. See [supported `getaddrinfo` flags][] below for more information on supported flags. * `all`: {Boolean} - When `true`, the callback returns all resolved addresses in an array, otherwise returns a single address. Defaults to `false`. All properties are optional. An example usage of options is shown below. { family: 4, hints: dns.ADDRCONFIG | dns.V4MAPPED, all: false } The `callback` function has arguments `(err, address, family)`. `address` is a string representation of an IPv4 or IPv6 address. `family` is either the integer `4` or `6` and denotes the family of `address` (not necessarily the value initially passed to `lookup`). With the `all` option set to `true`, the arguments change to `(err, addresses)`, with `addresses` being an array of objects with the properties `address` and `family`. On error, `err` is an [`Error`][] object, where `err.code` is the error code. Keep in mind that `err.code` will be set to `'ENOENT'` not only when the hostname does not exist but also when the lookup fails in other ways such as no available file descriptors. `dns.lookup()` does not necessarily have anything to do with the DNS protocol. The implementation uses an operating system facility that can associate names with addresses, and vice versa. This implementation can have subtle but important consequences on the behavior of any Node.js program. Please take some time to consult the [Implementation considerations section][] before using `dns.lookup()`. ### Supported getaddrinfo flags The following flags can be passed as hints to [`dns.lookup()`][]. - `dns.ADDRCONFIG`: Returned address types are determined by the types of addresses supported by the current system. For example, IPv4 addresses are only returned if the current system has at least one IPv4 address configured. Loopback addresses are not considered. - `dns.V4MAPPED`: If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. Note that it is not supported on some operating systems (e.g FreeBSD 10.1). ## dns.lookupService(address, port, callback) Resolves the given `address` and `port` into a hostname and service using the operating system's underlying `getnameinfo` implementation. The callback has arguments `(err, hostname, service)`. The `hostname` and `service` arguments are strings (e.g. `'localhost'` and `'http'` respectively). On error, `err` is an [`Error`][] object, where `err.code` is the error code. const dns = require('dns'); dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { console.log(hostname, service); // Prints: localhost ssh }); ## dns.resolve(hostname[, rrtype], callback) Uses the DNS protocol to resolve a hostname (e.g. `'nodejs.org'`) into an array of the record types specified by `rrtype`. Valid values for `rrtype` are: * `'A'` - IPV4 addresses, default * `'AAAA'` - IPV6 addresses * `'MX'` - mail exchange records * `'TXT'` - text records * `'SRV'` - SRV records * `'PTR'` - used for reverse IP lookups * `'NS'` - name server records * `'CNAME'` - canonical name records * `'SOA'` - start of authority record The `callback` function has arguments `(err, addresses)`. When successful, `addresses` will be an array. The type of each item in `addresses` is determined by the record type, and described in the documentation for the corresponding lookup methods below. On error, `err` is an [`Error`][] object, where `err.code` is one of the error codes listed below. ## dns.resolve4(hostname, callback) Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of IPv4 addresses (e.g. `['74.125.79.104', '74.125.79.105', '74.125.79.106']`). ## dns.resolve6(hostname, callback) Uses the DNS protocol to resolve a IPv6 addresses (`AAAA` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of IPv6 addresses. ## dns.resolveCname(hostname, callback) Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The `addresses` argument passed to the `callback` function will contain an of canonical name records available for the `hostname` (e.g. `['bar.example.com']`). ## dns.resolveMx(hostname, callback) Uses the DNS protocol to resolve mail exchange records (`MX` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of objects containing both a `priority` and `exchange` property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`). ## dns.resolveNs(hostname, callback) Uses the DNS protocol to resolve name server records (`NS` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of name server records available for `hostname` (e.g., `['ns1.example.com', 'ns2.example.com']`). ## dns.resolveSoa(hostname, callback) Uses the DNS protocol to resolve a start of authority record (`SOA` record) for the `hostname`. The `addresses` argument passed to the `callback` function will be an object with the following properties: * `nsname` * `hostmaster` * `serial` * `refresh` * `retry` * `expire` * `minttl` { nsname: 'ns.example.com', hostmaster: 'root.example.com', serial: 2013101809, refresh: 10000, retry: 2400, expire: 604800, minttl: 3600 } ## dns.resolveSrv(hostname, callback) Uses the DNS protocol to resolve service records (`SRV` records) for the `hostname`. The `addresses` argument passed to the `callback` function will be an array of objects with the following properties: * `priority` * `weight` * `port` * `name` { priority: 10, weight: 5, port: 21223, name: 'service.example.com' } ## dns.resolveTxt(hostname, callback) Uses the DNS protocol to resolve text queries (`TXT` records) for the `hostname`. The `addresses` argument passed to the `callback` function is is a two-dimentional array of the text records available for `hostname` (e.g., `[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of one record. Depending on the use case, these could be either joined together or treated separately. ## dns.reverse(ip, callback) Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of hostnames. The `callback` function has arguments `(err, hostnames)`, where `hostnames` is an array of resolved hostnames for the given `ip`. On error, `err` is an [`Error`][] object, where `err.code` is one of the error codes listed below. ## dns.setServers(servers) Sets the IP addresses of the servers to be used when resolving. The `servers` argument is an array of IPv4 or IPv6 addresses. If a port specified on the address it will be removed. An error will be thrown if an invalid address is provided. The `dns.setServers()` method must not be called while a DNS query is in progress. ## Error codes Each DNS query can return one of the following error codes: - `dns.NODATA`: DNS server returned answer with no data. - `dns.FORMERR`: DNS server claims query was misformatted. - `dns.SERVFAIL`: DNS server returned general failure. - `dns.NOTFOUND`: Domain name not found. - `dns.NOTIMP`: DNS server does not implement requested operation. - `dns.REFUSED`: DNS server refused query. - `dns.BADQUERY`: Misformatted DNS query. - `dns.BADNAME`: Misformatted hostname. - `dns.BADFAMILY`: Unsupported address family. - `dns.BADRESP`: Misformatted DNS reply. - `dns.CONNREFUSED`: Could not contact DNS servers. - `dns.TIMEOUT`: Timeout while contacting DNS servers. - `dns.EOF`: End of file. - `dns.FILE`: Error reading file. - `dns.NOMEM`: Out of memory. - `dns.DESTRUCTION`: Channel is being destroyed. - `dns.BADSTR`: Misformatted string. - `dns.BADFLAGS`: Illegal flags specified. - `dns.NONAME`: Given hostname is not numeric. - `dns.BADHINTS`: Illegal hints flags specified. - `dns.NOTINITIALIZED`: c-ares library initialization not yet performed. - `dns.LOADIPHLPAPI`: Error loading iphlpapi.dll. - `dns.ADDRGETNETWORKPARAMS`: Could not find GetNetworkParams function. - `dns.CANCELLED`: DNS query cancelled. ## Implementation considerations Although [`dns.lookup()`][] and the various `dns.resolve*()/dns.reverse()` functions have the same goal of associating a network name with a network address (or vice versa), their behavior is quite different. These differences can have subtle but significant consequences on the behavior of Node.js programs. ### `dns.lookup()` Under the hood, [`dns.lookup()`][] uses the same operating system facilities as most other programs. For instance, [`dns.lookup()`][] will almost always resolve a given name the same way as the `ping` command. On most POSIX-like operating systems, the behavior of the [`dns.lookup()`][] function can be modified by changing settings in `nsswitch.conf(5)` and/or `resolv.conf(5)`, but note that changing these files will change the behavior of _all other programs running on the same operating system_. Though the call to `dns.lookup()` will be asynchronous from JavaScript's perspective, it is implemented as a synchronous call to `getaddrinfo(3)` that runs on libuv's threadpool. Because libuv's threadpool has a fixed size, it means that if for whatever reason the call to `getaddrinfo(3)` takes a long time, other operations that could run on libuv's threadpool (such as filesystem operations) will experience degraded performance. In order to mitigate this issue, one potential solution is to increase the size of libuv's threadpool by setting the `'UV_THREADPOOL_SIZE'` environment variable to a value greater than `4` (its current default value). For more information on libuv's threadpool, see [the official libuv documentation][]. ### `dns.resolve()`, `dns.resolve*()` and `dns.reverse()` These functions are implemented quite differently than [`dns.lookup()`][]. They do not use `getaddrinfo(3)` and they _always_ perform a DNS query on the network. This network communication is always done asynchronously, and does not use libuv's threadpool. As a result, these functions cannot have the same negative impact on other processing that happens on libuv's threadpool that [`dns.lookup()`][] can have. They do not use the same set of configuration files than what [`dns.lookup()`][] uses. For instance, _they do not use the configuration from `/etc/hosts`_. [`dns.lookup()`]: #dns_dns_lookup_hostname_options_callback [`dns.resolve()`]: #dns_dns_resolve_hostname_rrtype_callback [`dns.resolve4()`]: #dns_dns_resolve4_hostname_callback [`Error`]: errors.html#errors_class_error [Implementation considerations section]: #dns_implementation_considerations [supported `getaddrinfo` flags]: #dns_supported_getaddrinfo_flags [the official libuv documentation]: http://docs.libuv.org/en/latest/threadpool.html node-v4.2.6/doc/api/documentation.html000644 000766 000024 00000015527 12650222331 020031 0ustar00iojsstaff000000 000000 About this Documentation Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


About this Documentation#

The goal of this documentation is to comprehensively explain the Node.js API, both from a reference as well as a conceptual point of view. Each section describes a built-in module or high-level concept.

Where appropriate, property types, method arguments, and the arguments provided to event handlers are detailed in a list underneath the topic heading.

Every .html document has a corresponding .json document presenting the same information in a structured manner. This feature is experimental, and added for the benefit of IDEs and other utilities that wish to do programmatic things with the documentation.

Every .html and .json file is generated based on the corresponding .markdown file in the doc/api/ folder in Node.js's source tree. The documentation is generated using the tools/doc/generate.js program. The HTML template is located at doc/template.html.

Stability Index#

Throughout the documentation, you will see indications of a section's stability. The Node.js API is still somewhat changing, and as it matures, certain parts are more reliable than others. Some are so proven, and so relied upon, that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous and in the process of being redesigned.

The stability indices are as follows:

Stability: 0 - Deprecated
This feature is known to be problematic, and changes are
planned.  Do not rely on it.  Use of the feature may cause warnings.  Backwards
compatibility should not be expected.
Stability: 1 - Experimental
This feature is subject to change, and is gated by a command line flag.
It may change or be removed in future versions.
Stability: 2 - Stable
The API has proven satisfactory. Compatibility with the npm ecosystem
is a high priority, and will not be broken unless absolutely necessary.
Stability: 3 - Locked
Only fixes related to security, performance, or bug fixes will be accepted.
Please do not suggest API changes in this area; they will be refused.

JSON Output#

Stability: 1 - Experimental

Every HTML file in the markdown has a corresponding JSON file with the same data.

This feature was added in Node.js v0.6.12. It is experimental.

node-v4.2.6/doc/api/documentation.json000644 000766 000024 00000005772 12650222331 020037 0ustar00iojsstaff000000 000000 { "source": "doc/api/documentation.markdown", "miscs": [ { "textRaw": "About this Documentation", "name": "About this Documentation", "type": "misc", "desc": "

The goal of this documentation is to comprehensively explain the Node.js\nAPI, both from a reference as well as a conceptual point of view. Each\nsection describes a built-in module or high-level concept.\n\n

\n

Where appropriate, property types, method arguments, and the arguments\nprovided to event handlers are detailed in a list underneath the topic\nheading.\n\n

\n

Every .html document has a corresponding .json document presenting\nthe same information in a structured manner. This feature is\nexperimental, and added for the benefit of IDEs and other utilities that\nwish to do programmatic things with the documentation.\n\n

\n

Every .html and .json file is generated based on the corresponding\n.markdown file in the doc/api/ folder in Node.js's source tree. The\ndocumentation is generated using the tools/doc/generate.js program.\nThe HTML template is located at doc/template.html.\n\n

\n", "miscs": [ { "textRaw": "Stability Index", "name": "Stability Index", "type": "misc", "desc": "

Throughout the documentation, you will see indications of a section's\nstability. The Node.js API is still somewhat changing, and as it\nmatures, certain parts are more reliable than others. Some are so\nproven, and so relied upon, that they are unlikely to ever change at\nall. Others are brand new and experimental, or known to be hazardous\nand in the process of being redesigned.\n\n

\n

The stability indices are as follows:\n\n

\n
Stability: 0 - Deprecated\nThis feature is known to be problematic, and changes are\nplanned.  Do not rely on it.  Use of the feature may cause warnings.  Backwards\ncompatibility should not be expected.
\n
Stability: 1 - Experimental\nThis feature is subject to change, and is gated by a command line flag.\nIt may change or be removed in future versions.
\n
Stability: 2 - Stable\nThe API has proven satisfactory. Compatibility with the npm ecosystem\nis a high priority, and will not be broken unless absolutely necessary.
\n
Stability: 3 - Locked\nOnly fixes related to security, performance, or bug fixes will be accepted.\nPlease do not suggest API changes in this area; they will be refused.
\n" }, { "textRaw": "JSON Output", "name": "json_output", "stability": 1, "stabilityText": "Experimental", "desc": "

Every HTML file in the markdown has a corresponding JSON file with the\nsame data.\n\n

\n

This feature was added in Node.js v0.6.12. It is experimental.\n

\n", "type": "misc", "displayName": "JSON Output" } ] } ] } node-v4.2.6/doc/api/documentation.markdown000644 000766 000024 00000004404 12650222326 020703 0ustar00iojsstaff000000 000000 # About this Documentation The goal of this documentation is to comprehensively explain the Node.js API, both from a reference as well as a conceptual point of view. Each section describes a built-in module or high-level concept. Where appropriate, property types, method arguments, and the arguments provided to event handlers are detailed in a list underneath the topic heading. Every `.html` document has a corresponding `.json` document presenting the same information in a structured manner. This feature is experimental, and added for the benefit of IDEs and other utilities that wish to do programmatic things with the documentation. Every `.html` and `.json` file is generated based on the corresponding `.markdown` file in the `doc/api/` folder in Node.js's source tree. The documentation is generated using the `tools/doc/generate.js` program. The HTML template is located at `doc/template.html`. ## Stability Index Throughout the documentation, you will see indications of a section's stability. The Node.js API is still somewhat changing, and as it matures, certain parts are more reliable than others. Some are so proven, and so relied upon, that they are unlikely to ever change at all. Others are brand new and experimental, or known to be hazardous and in the process of being redesigned. The stability indices are as follows: ``` Stability: 0 - Deprecated This feature is known to be problematic, and changes are planned. Do not rely on it. Use of the feature may cause warnings. Backwards compatibility should not be expected. ``` ``` Stability: 1 - Experimental This feature is subject to change, and is gated by a command line flag. It may change or be removed in future versions. ``` ``` Stability: 2 - Stable The API has proven satisfactory. Compatibility with the npm ecosystem is a high priority, and will not be broken unless absolutely necessary. ``` ``` Stability: 3 - Locked Only fixes related to security, performance, or bug fixes will be accepted. Please do not suggest API changes in this area; they will be refused. ``` ## JSON Output Stability: 1 - Experimental Every HTML file in the markdown has a corresponding JSON file with the same data. This feature was added in Node.js v0.6.12. It is experimental. node-v4.2.6/doc/api/domain.html000644 000766 000024 00000056505 12650222331 016430 0ustar00iojsstaff000000 000000 Domain Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Domain#

Stability: 0 - Deprecated

This module is pending deprecation. Once a replacement API has been finalized, this module will be fully deprecated. Most end users should not have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future.

Domains provide a way to handle multiple different IO operations as a single group. If any of the event emitters or callbacks registered to a domain emit an 'error' event, or throw an error, then the domain object will be notified, rather than losing the context of the error in the process.on('uncaughtException') handler, or causing the program to exit immediately with an error code.

Warning: Don't Ignore Errors!#

Domain error handlers are not a substitute for closing down your process when an error occurs.

By the very nature of how throw works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state.

The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else.

The better approach is to send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.

In this way, domain usage goes hand-in-hand with the cluster module, since the master process can fork a new worker when a worker encounters an error. For Node.js programs that scale to multiple machines, the terminating proxy or service registry can take note of the failure, and react accordingly.

For example, this is not a good idea:

// XXX WARNING!  BAD IDEA!

var d = require('domain').create();
d.on('error', (er) => {
  // The error won't crash the process, but what it does is worse!
  // Though we've prevented abrupt process restarting, we are leaking
  // resources like crazy if this ever happens.
  // This is no better than process.on('uncaughtException')!
  console.log('error, but oh well', er.message);
});
d.run(() => {
  require('http').createServer((req, res) => {
    handleRequest(req, res);
  }).listen(PORT);
});

By using the context of a domain, and the resilience of separating our program into multiple worker processes, we can react more appropriately, and handle errors with much greater safety.

// Much better!

const cluster = require('cluster');
const PORT = +process.env.PORT || 1337;

if (cluster.isMaster) {
  // In real life, you'd probably use more than just 2 workers,
  // and perhaps not put the master and worker in the same file.
  //
  // You can also of course get a bit fancier about logging, and
  // implement whatever custom logic you need to prevent DoS
  // attacks and other bad behavior.
  //
  // See the options in the cluster documentation.
  //
  // The important thing is that the master does very little,
  // increasing our resilience to unexpected errors.

  cluster.fork();
  cluster.fork();

  cluster.on('disconnect', (worker) => {
    console.error('disconnect!');
    cluster.fork();
  });

} else {
  // the worker
  //
  // This is where we put our bugs!

  const domain = require('domain');

  // See the cluster documentation for more details about using
  // worker processes to serve requests.  How it works, caveats, etc.

  const server = require('http').createServer((req, res) => {
    var d = domain.create();
    d.on('error', (er) => {
      console.error('error', er.stack);

      // Note: we're in dangerous territory!
      // By definition, something unexpected occurred,
      // which we probably didn't want.
      // Anything can happen now!  Be very careful!

      try {
        // make sure we close down within 30 seconds
        var killtimer = setTimeout(() => {
          process.exit(1);
        }, 30000);
        // But don't keep the process open just for that!
        killtimer.unref();

        // stop taking new requests.
        server.close();

        // Let the master know we're dead.  This will trigger a
        // 'disconnect' in the cluster master, and then it will fork
        // a new worker.
        cluster.worker.disconnect();

        // try to send an error to the request that triggered the problem
        res.statusCode = 500;
        res.setHeader('content-type', 'text/plain');
        res.end('Oops, there was a problem!\n');
      } catch (er2) {
        // oh well, not much we can do at this point.
        console.error('Error sending 500!', er2.stack);
      }
    });

    // Because req and res were created before this domain existed,
    // we need to explicitly add them.
    // See the explanation of implicit vs explicit binding below.
    d.add(req);
    d.add(res);

    // Now run the handler function in the domain.
    d.run(() => {
      handleRequest(req, res);
    });
  });
  server.listen(PORT);
}

// This part isn't important.  Just an example routing thing.
// You'd put your fancy application logic here.
function handleRequest(req, res) {
  switch(req.url) {
    case '/error':
      // We do some async stuff, and then...
      setTimeout(() => {
        // Whoops!
        flerb.bark();
      });
      break;
    default:
      res.end('ok');
  }
}

Additions to Error objects#

Any time an Error object is routed through a domain, a few extra fields are added to it.

  • error.domain The domain that first handled the error.
  • error.domainEmitter The event emitter that emitted an 'error' event with the error object.
  • error.domainBound The callback function which was bound to the domain, and passed an error as its first argument.
  • error.domainThrown A boolean indicating whether the error was thrown, emitted, or passed to a bound callback function.

Implicit Binding#

If domains are in use, then all new EventEmitter objects (including Stream objects, requests, responses, etc.) will be implicitly bound to the active domain at the time of their creation.

Additionally, callbacks passed to lowlevel event loop requests (such as to fs.open, or other callback-taking methods) will automatically be bound to the active domain. If they throw, then the domain will catch the error.

In order to prevent excessive memory usage, Domain objects themselves are not implicitly added as children of the active domain. If they were, then it would be too easy to prevent request and response objects from being properly garbage collected.

If you want to nest Domain objects as children of a parent Domain, then you must explicitly add them.

Implicit binding routes thrown errors and 'error' events to the Domain's 'error' event, but does not register the EventEmitter on the Domain, so domain.dispose() will not shut down the EventEmitter. Implicit binding only takes care of thrown errors and 'error' events.

Explicit Binding#

Sometimes, the domain in use is not the one that ought to be used for a specific event emitter. Or, the event emitter could have been created in the context of one domain, but ought to instead be bound to some other domain.

For example, there could be one domain in use for an HTTP server, but perhaps we would like to have a separate domain to use for each request.

That is possible via explicit binding.

For example:

// create a top-level domain for the server
const domain = require('domain');
const http = require('http');
const serverDomain = domain.create();

serverDomain.run(() => {
  // server is created in the scope of serverDomain
  http.createServer((req, res) => {
    // req and res are also created in the scope of serverDomain
    // however, we'd prefer to have a separate domain for each request.
    // create it first thing, and add req and res to it.
    var reqd = domain.create();
    reqd.add(req);
    reqd.add(res);
    reqd.on('error', (er) => {
      console.error('Error', er, req.url);
      try {
        res.writeHead(500);
        res.end('Error occurred, sorry.');
      } catch (er) {
        console.error('Error sending 500', er, req.url);
      }
    });
  }).listen(1337);
});

domain.create()#

  • return: Domain

Returns a new Domain object.

Class: Domain#

The Domain class encapsulates the functionality of routing errors and uncaught exceptions to the active Domain object.

Domain is a child class of EventEmitter. To handle the errors that it catches, listen to its 'error' event.

domain.run(fn[, arg][, ...])#

  • fn Function

Run the supplied function in the context of the domain, implicitly binding all event emitters, timers, and lowlevel requests that are created in that context. Optionally, arguments can be passed to the function.

This is the most basic way to use a domain.

Example:

const domain = require('domain');
const fs = require('fs');
const d = domain.create();
d.on('error', (er) => {
  console.error('Caught error!', er);
});
d.run(() => {
  process.nextTick(() => {
    setTimeout(() => { // simulating some various async stuff
      fs.open('non-existent file', 'r', (er, fd) => {
        if (er) throw er;
        // proceed...
      });
    }, 100);
  });
});

In this example, the d.on('error') handler will be triggered, rather than crashing the program.

domain.members#

  • Array

An array of timers and event emitters that have been explicitly added to the domain.

domain.add(emitter)#

  • emitter EventEmitter | Timer emitter or timer to be added to the domain

Explicitly adds an emitter to the domain. If any event handlers called by the emitter throw an error, or if the emitter emits an 'error' event, it will be routed to the domain's 'error' event, just like with implicit binding.

This also works with timers that are returned from setInterval() and setTimeout(). If their callback function throws, it will be caught by the domain 'error' handler.

If the Timer or EventEmitter was already bound to a domain, it is removed from that one, and bound to this one instead.

domain.remove(emitter)#

  • emitter EventEmitter | Timer emitter or timer to be removed from the domain

The opposite of domain.add(emitter). Removes domain handling from the specified emitter.

domain.bind(callback)#

  • callback Function The callback function
  • return: Function The bound function

The returned function will be a wrapper around the supplied callback function. When the returned function is called, any errors that are thrown will be routed to the domain's 'error' event.

Example#

const d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.bind(function(er, data) {
    // if this throws, it will also be passed to the domain
    return cb(er, data ? JSON.parse(data) : null);
  }));
}

d.on('error', (er) => {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.intercept(callback)#

  • callback Function The callback function
  • return: Function The intercepted function

This method is almost identical to domain.bind(callback). However, in addition to catching thrown errors, it will also intercept Error objects sent as the first argument to the function.

In this way, the common if (err) return callback(err); pattern can be replaced with a single error handler in a single place.

Example#

const d = domain.create();

function readSomeFile(filename, cb) {
  fs.readFile(filename, 'utf8', d.intercept(function(data) {
    // note, the first argument is never passed to the
    // callback since it is assumed to be the 'Error' argument
    // and thus intercepted by the domain.

    // if this throws, it will also be passed to the domain
    // so the error-handling logic can be moved to the 'error'
    // event on the domain instead of being repeated throughout
    // the program.
    return cb(null, JSON.parse(data));
  }));
}

d.on('error', (er) => {
  // an error occurred somewhere.
  // if we throw it now, it will crash the program
  // with the normal line number and stack message.
});

domain.enter()#

The enter method is plumbing used by the run, bind, and intercept methods to set the active domain. It sets domain.active and process.domain to the domain, and implicitly pushes the domain onto the domain stack managed by the domain module (see domain.exit() for details on the domain stack). The call to enter delimits the beginning of a chain of asynchronous calls and I/O operations bound to a domain.

Calling enter changes only the active domain, and does not alter the domain itself. enter and exit can be called an arbitrary number of times on a single domain.

If the domain on which enter is called has been disposed, enter will return without setting the domain.

domain.exit()#

The exit method exits the current domain, popping it off the domain stack. Any time execution is going to switch to the context of a different chain of asynchronous calls, it's important to ensure that the current domain is exited. The call to exit delimits either the end of or an interruption to the chain of asynchronous calls and I/O operations bound to a domain.

If there are multiple, nested domains bound to the current execution context, exit will exit any domains nested within this domain.

Calling exit changes only the active domain, and does not alter the domain itself. enter and exit can be called an arbitrary number of times on a single domain.

If the domain on which exit is called has been disposed, exit will return without exiting the domain.

domain.dispose()#

Stability: 0 - Deprecated.  Please recover from failed IO actions
explicitly via error event handlers set on the domain.

Once dispose has been called, the domain will no longer be used by callbacks bound into the domain via run, bind, or intercept, and a 'dispose' event is emitted.

node-v4.2.6/doc/api/domain.json000644 000766 000024 00000054457 12650222331 016441 0ustar00iojsstaff000000 000000 { "source": "doc/api/domain.markdown", "modules": [ { "textRaw": "Domain", "name": "domain", "stability": 0, "stabilityText": "Deprecated", "desc": "

This module is pending deprecation. Once a replacement API has been\nfinalized, this module will be fully deprecated. Most end users should\nnot have cause to use this module. Users who absolutely must have\nthe functionality that domains provide may rely on it for the time being\nbut should expect to have to migrate to a different solution\nin the future.\n\n

\n

Domains provide a way to handle multiple different IO operations as a\nsingle group. If any of the event emitters or callbacks registered to a\ndomain emit an 'error' event, or throw an error, then the domain object\nwill be notified, rather than losing the context of the error in the\nprocess.on('uncaughtException') handler, or causing the program to\nexit immediately with an error code.\n\n

\n", "miscs": [ { "textRaw": "Warning: Don't Ignore Errors!", "name": "Warning: Don't Ignore Errors!", "type": "misc", "desc": "

Domain error handlers are not a substitute for closing down your\nprocess when an error occurs.\n\n

\n

By the very nature of how [throw][] works in JavaScript, there is almost\nnever any way to safely "pick up where you left off", without leaking\nreferences, or creating some other sort of undefined brittle state.\n\n

\n

The safest way to respond to a thrown error is to shut down the\nprocess. Of course, in a normal web server, you might have many\nconnections open, and it is not reasonable to abruptly shut those down\nbecause an error was triggered by someone else.\n\n

\n

The better approach is to send an error response to the request that\ntriggered the error, while letting the others finish in their normal\ntime, and stop listening for new requests in that worker.\n\n

\n

In this way, domain usage goes hand-in-hand with the cluster module,\nsince the master process can fork a new worker when a worker\nencounters an error. For Node.js programs that scale to multiple\nmachines, the terminating proxy or service registry can take note of\nthe failure, and react accordingly.\n\n

\n

For example, this is not a good idea:\n\n

\n
// XXX WARNING!  BAD IDEA!\n\nvar d = require('domain').create();\nd.on('error', (er) => {\n  // The error won't crash the process, but what it does is worse!\n  // Though we've prevented abrupt process restarting, we are leaking\n  // resources like crazy if this ever happens.\n  // This is no better than process.on('uncaughtException')!\n  console.log('error, but oh well', er.message);\n});\nd.run(() => {\n  require('http').createServer((req, res) => {\n    handleRequest(req, res);\n  }).listen(PORT);\n});
\n

By using the context of a domain, and the resilience of separating our\nprogram into multiple worker processes, we can react more\nappropriately, and handle errors with much greater safety.\n\n

\n
// Much better!\n\nconst cluster = require('cluster');\nconst PORT = +process.env.PORT || 1337;\n\nif (cluster.isMaster) {\n  // In real life, you'd probably use more than just 2 workers,\n  // and perhaps not put the master and worker in the same file.\n  //\n  // You can also of course get a bit fancier about logging, and\n  // implement whatever custom logic you need to prevent DoS\n  // attacks and other bad behavior.\n  //\n  // See the options in the cluster documentation.\n  //\n  // The important thing is that the master does very little,\n  // increasing our resilience to unexpected errors.\n\n  cluster.fork();\n  cluster.fork();\n\n  cluster.on('disconnect', (worker) => {\n    console.error('disconnect!');\n    cluster.fork();\n  });\n\n} else {\n  // the worker\n  //\n  // This is where we put our bugs!\n\n  const domain = require('domain');\n\n  // See the cluster documentation for more details about using\n  // worker processes to serve requests.  How it works, caveats, etc.\n\n  const server = require('http').createServer((req, res) => {\n    var d = domain.create();\n    d.on('error', (er) => {\n      console.error('error', er.stack);\n\n      // Note: we're in dangerous territory!\n      // By definition, something unexpected occurred,\n      // which we probably didn't want.\n      // Anything can happen now!  Be very careful!\n\n      try {\n        // make sure we close down within 30 seconds\n        var killtimer = setTimeout(() => {\n          process.exit(1);\n        }, 30000);\n        // But don't keep the process open just for that!\n        killtimer.unref();\n\n        // stop taking new requests.\n        server.close();\n\n        // Let the master know we're dead.  This will trigger a\n        // 'disconnect' in the cluster master, and then it will fork\n        // a new worker.\n        cluster.worker.disconnect();\n\n        // try to send an error to the request that triggered the problem\n        res.statusCode = 500;\n        res.setHeader('content-type', 'text/plain');\n        res.end('Oops, there was a problem!\\n');\n      } catch (er2) {\n        // oh well, not much we can do at this point.\n        console.error('Error sending 500!', er2.stack);\n      }\n    });\n\n    // Because req and res were created before this domain existed,\n    // we need to explicitly add them.\n    // See the explanation of implicit vs explicit binding below.\n    d.add(req);\n    d.add(res);\n\n    // Now run the handler function in the domain.\n    d.run(() => {\n      handleRequest(req, res);\n    });\n  });\n  server.listen(PORT);\n}\n\n// This part isn't important.  Just an example routing thing.\n// You'd put your fancy application logic here.\nfunction handleRequest(req, res) {\n  switch(req.url) {\n    case '/error':\n      // We do some async stuff, and then...\n      setTimeout(() => {\n        // Whoops!\n        flerb.bark();\n      });\n      break;\n    default:\n      res.end('ok');\n  }\n}
\n" }, { "textRaw": "Additions to Error objects", "name": "Additions to Error objects", "type": "misc", "desc": "

Any time an Error object is routed through a domain, a few extra fields\nare added to it.\n\n

\n
    \n
  • error.domain The domain that first handled the error.
  • \n
  • error.domainEmitter The event emitter that emitted an 'error' event\nwith the error object.
  • \n
  • error.domainBound The callback function which was bound to the\ndomain, and passed an error as its first argument.
  • \n
  • error.domainThrown A boolean indicating whether the error was\nthrown, emitted, or passed to a bound callback function.
  • \n
\n" }, { "textRaw": "Implicit Binding", "name": "Implicit Binding", "type": "misc", "desc": "

If domains are in use, then all new EventEmitter objects (including\nStream objects, requests, responses, etc.) will be implicitly bound to\nthe active domain at the time of their creation.\n\n

\n

Additionally, callbacks passed to lowlevel event loop requests (such as\nto fs.open, or other callback-taking methods) will automatically be\nbound to the active domain. If they throw, then the domain will catch\nthe error.\n\n

\n

In order to prevent excessive memory usage, Domain objects themselves\nare not implicitly added as children of the active domain. If they\nwere, then it would be too easy to prevent request and response objects\nfrom being properly garbage collected.\n\n

\n

If you want to nest Domain objects as children of a parent Domain,\nthen you must explicitly add them.\n\n

\n

Implicit binding routes thrown errors and 'error' events to the\nDomain's 'error' event, but does not register the EventEmitter on the\nDomain, so [domain.dispose()][] will not shut down the EventEmitter.\nImplicit binding only takes care of thrown errors and 'error' events.\n\n

\n" }, { "textRaw": "Explicit Binding", "name": "Explicit Binding", "type": "misc", "desc": "

Sometimes, the domain in use is not the one that ought to be used for a\nspecific event emitter. Or, the event emitter could have been created\nin the context of one domain, but ought to instead be bound to some\nother domain.\n\n

\n

For example, there could be one domain in use for an HTTP server, but\nperhaps we would like to have a separate domain to use for each request.\n\n

\n

That is possible via explicit binding.\n\n

\n

For example:\n\n

\n
// create a top-level domain for the server\nconst domain = require('domain');\nconst http = require('http');\nconst serverDomain = domain.create();\n\nserverDomain.run(() => {\n  // server is created in the scope of serverDomain\n  http.createServer((req, res) => {\n    // req and res are also created in the scope of serverDomain\n    // however, we'd prefer to have a separate domain for each request.\n    // create it first thing, and add req and res to it.\n    var reqd = domain.create();\n    reqd.add(req);\n    reqd.add(res);\n    reqd.on('error', (er) => {\n      console.error('Error', er, req.url);\n      try {\n        res.writeHead(500);\n        res.end('Error occurred, sorry.');\n      } catch (er) {\n        console.error('Error sending 500', er, req.url);\n      }\n    });\n  }).listen(1337);\n});
\n" } ], "methods": [ { "textRaw": "domain.create()", "type": "method", "name": "create", "signatures": [ { "return": { "textRaw": "return: {Domain} ", "name": "return", "type": "Domain" }, "params": [] }, { "params": [] } ], "desc": "

Returns a new Domain object.\n\n

\n" } ], "classes": [ { "textRaw": "Class: Domain", "type": "class", "name": "Domain", "desc": "

The Domain class encapsulates the functionality of routing errors and\nuncaught exceptions to the active Domain object.\n\n

\n

Domain is a child class of [EventEmitter][]. To handle the errors that it\ncatches, listen to its 'error' event.\n\n

\n", "methods": [ { "textRaw": "domain.run(fn[, arg][, ...])", "type": "method", "name": "run", "signatures": [ { "params": [ { "textRaw": "`fn` {Function} ", "name": "fn", "type": "Function" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] }, { "params": [ { "name": "fn" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ], "desc": "

Run the supplied function in the context of the domain, implicitly\nbinding all event emitters, timers, and lowlevel requests that are\ncreated in that context. Optionally, arguments can be passed to\nthe function.\n\n

\n

This is the most basic way to use a domain.\n\n

\n

Example:\n\n

\n
const domain = require('domain');\nconst fs = require('fs');\nconst d = domain.create();\nd.on('error', (er) => {\n  console.error('Caught error!', er);\n});\nd.run(() => {\n  process.nextTick(() => {\n    setTimeout(() => { // simulating some various async stuff\n      fs.open('non-existent file', 'r', (er, fd) => {\n        if (er) throw er;\n        // proceed...\n      });\n    }, 100);\n  });\n});
\n

In this example, the d.on('error') handler will be triggered, rather\nthan crashing the program.\n\n

\n" }, { "textRaw": "domain.add(emitter)", "type": "method", "name": "add", "signatures": [ { "params": [ { "textRaw": "`emitter` {EventEmitter | Timer} emitter or timer to be added to the domain ", "name": "emitter", "type": "EventEmitter | Timer", "desc": "emitter or timer to be added to the domain" } ] }, { "params": [ { "name": "emitter" } ] } ], "desc": "

Explicitly adds an emitter to the domain. If any event handlers called by\nthe emitter throw an error, or if the emitter emits an 'error' event, it\nwill be routed to the domain's 'error' event, just like with implicit\nbinding.\n\n

\n

This also works with timers that are returned from [setInterval()][] and\n[setTimeout()][]. If their callback function throws, it will be caught by\nthe domain 'error' handler.\n\n

\n

If the Timer or EventEmitter was already bound to a domain, it is removed\nfrom that one, and bound to this one instead.\n\n

\n" }, { "textRaw": "domain.remove(emitter)", "type": "method", "name": "remove", "signatures": [ { "params": [ { "textRaw": "`emitter` {EventEmitter | Timer} emitter or timer to be removed from the domain ", "name": "emitter", "type": "EventEmitter | Timer", "desc": "emitter or timer to be removed from the domain" } ] }, { "params": [ { "name": "emitter" } ] } ], "desc": "

The opposite of [domain.add(emitter)][]. Removes domain handling from the\nspecified emitter.\n\n

\n" }, { "textRaw": "domain.bind(callback)", "type": "method", "name": "bind", "signatures": [ { "return": { "textRaw": "return: {Function} The bound function ", "name": "return", "type": "Function", "desc": "The bound function" }, "params": [ { "textRaw": "`callback` {Function} The callback function ", "name": "callback", "type": "Function", "desc": "The callback function" } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

The returned function will be a wrapper around the supplied callback\nfunction. When the returned function is called, any errors that are\nthrown will be routed to the domain's 'error' event.\n\n

\n

Example

\n
const d = domain.create();\n\nfunction readSomeFile(filename, cb) {\n  fs.readFile(filename, 'utf8', d.bind(function(er, data) {\n    // if this throws, it will also be passed to the domain\n    return cb(er, data ? JSON.parse(data) : null);\n  }));\n}\n\nd.on('error', (er) => {\n  // an error occurred somewhere.\n  // if we throw it now, it will crash the program\n  // with the normal line number and stack message.\n});
\n" }, { "textRaw": "domain.intercept(callback)", "type": "method", "name": "intercept", "signatures": [ { "return": { "textRaw": "return: {Function} The intercepted function ", "name": "return", "type": "Function", "desc": "The intercepted function" }, "params": [ { "textRaw": "`callback` {Function} The callback function ", "name": "callback", "type": "Function", "desc": "The callback function" } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

This method is almost identical to [domain.bind(callback)][]. However, in\naddition to catching thrown errors, it will also intercept [Error][]\nobjects sent as the first argument to the function.\n\n

\n

In this way, the common if (err) return callback(err); pattern can be replaced\nwith a single error handler in a single place.\n\n

\n

Example

\n
const d = domain.create();\n\nfunction readSomeFile(filename, cb) {\n  fs.readFile(filename, 'utf8', d.intercept(function(data) {\n    // note, the first argument is never passed to the\n    // callback since it is assumed to be the 'Error' argument\n    // and thus intercepted by the domain.\n\n    // if this throws, it will also be passed to the domain\n    // so the error-handling logic can be moved to the 'error'\n    // event on the domain instead of being repeated throughout\n    // the program.\n    return cb(null, JSON.parse(data));\n  }));\n}\n\nd.on('error', (er) => {\n  // an error occurred somewhere.\n  // if we throw it now, it will crash the program\n  // with the normal line number and stack message.\n});
\n" }, { "textRaw": "domain.enter()", "type": "method", "name": "enter", "desc": "

The enter method is plumbing used by the run, bind, and intercept\nmethods to set the active domain. It sets domain.active and process.domain\nto the domain, and implicitly pushes the domain onto the domain stack managed\nby the domain module (see [domain.exit()][] for details on the domain stack). The\ncall to enter delimits the beginning of a chain of asynchronous calls and I/O\noperations bound to a domain.\n\n

\n

Calling enter changes only the active domain, and does not alter the domain\nitself. enter and exit can be called an arbitrary number of times on a\nsingle domain.\n\n

\n

If the domain on which enter is called has been disposed, enter will return\nwithout setting the domain.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "domain.exit()", "type": "method", "name": "exit", "desc": "

The exit method exits the current domain, popping it off the domain stack.\nAny time execution is going to switch to the context of a different chain of\nasynchronous calls, it's important to ensure that the current domain is exited.\nThe call to exit delimits either the end of or an interruption to the chain\nof asynchronous calls and I/O operations bound to a domain.\n\n

\n

If there are multiple, nested domains bound to the current execution context,\nexit will exit any domains nested within this domain.\n\n

\n

Calling exit changes only the active domain, and does not alter the domain\nitself. enter and exit can be called an arbitrary number of times on a\nsingle domain.\n\n

\n

If the domain on which exit is called has been disposed, exit will return\nwithout exiting the domain.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "domain.dispose()", "type": "method", "name": "dispose", "desc": "
Stability: 0 - Deprecated.  Please recover from failed IO actions\nexplicitly via error event handlers set on the domain.
\n

Once dispose has been called, the domain will no longer be used by callbacks\nbound into the domain via run, bind, or intercept, and a 'dispose' event\nis emitted.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "`members` {Array} ", "name": "members", "desc": "

An array of timers and event emitters that have been explicitly added\nto the domain.\n\n

\n" } ] } ], "type": "module", "displayName": "Domain" } ] } node-v4.2.6/doc/api/domain.markdown000644 000766 000024 00000035213 12650222326 017303 0ustar00iojsstaff000000 000000 # Domain Stability: 0 - Deprecated **This module is pending deprecation**. Once a replacement API has been finalized, this module will be fully deprecated. Most end users should **not** have cause to use this module. Users who absolutely must have the functionality that domains provide may rely on it for the time being but should expect to have to migrate to a different solution in the future. Domains provide a way to handle multiple different IO operations as a single group. If any of the event emitters or callbacks registered to a domain emit an `'error'` event, or throw an error, then the domain object will be notified, rather than losing the context of the error in the `process.on('uncaughtException')` handler, or causing the program to exit immediately with an error code. ## Warning: Don't Ignore Errors! Domain error handlers are not a substitute for closing down your process when an error occurs. By the very nature of how [`throw`][] works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state. The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else. The better approach is to send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker. In this way, `domain` usage goes hand-in-hand with the cluster module, since the master process can fork a new worker when a worker encounters an error. For Node.js programs that scale to multiple machines, the terminating proxy or service registry can take note of the failure, and react accordingly. For example, this is not a good idea: ```javascript // XXX WARNING! BAD IDEA! var d = require('domain').create(); d.on('error', (er) => { // The error won't crash the process, but what it does is worse! // Though we've prevented abrupt process restarting, we are leaking // resources like crazy if this ever happens. // This is no better than process.on('uncaughtException')! console.log('error, but oh well', er.message); }); d.run(() => { require('http').createServer((req, res) => { handleRequest(req, res); }).listen(PORT); }); ``` By using the context of a domain, and the resilience of separating our program into multiple worker processes, we can react more appropriately, and handle errors with much greater safety. ```javascript // Much better! const cluster = require('cluster'); const PORT = +process.env.PORT || 1337; if (cluster.isMaster) { // In real life, you'd probably use more than just 2 workers, // and perhaps not put the master and worker in the same file. // // You can also of course get a bit fancier about logging, and // implement whatever custom logic you need to prevent DoS // attacks and other bad behavior. // // See the options in the cluster documentation. // // The important thing is that the master does very little, // increasing our resilience to unexpected errors. cluster.fork(); cluster.fork(); cluster.on('disconnect', (worker) => { console.error('disconnect!'); cluster.fork(); }); } else { // the worker // // This is where we put our bugs! const domain = require('domain'); // See the cluster documentation for more details about using // worker processes to serve requests. How it works, caveats, etc. const server = require('http').createServer((req, res) => { var d = domain.create(); d.on('error', (er) => { console.error('error', er.stack); // Note: we're in dangerous territory! // By definition, something unexpected occurred, // which we probably didn't want. // Anything can happen now! Be very careful! try { // make sure we close down within 30 seconds var killtimer = setTimeout(() => { process.exit(1); }, 30000); // But don't keep the process open just for that! killtimer.unref(); // stop taking new requests. server.close(); // Let the master know we're dead. This will trigger a // 'disconnect' in the cluster master, and then it will fork // a new worker. cluster.worker.disconnect(); // try to send an error to the request that triggered the problem res.statusCode = 500; res.setHeader('content-type', 'text/plain'); res.end('Oops, there was a problem!\n'); } catch (er2) { // oh well, not much we can do at this point. console.error('Error sending 500!', er2.stack); } }); // Because req and res were created before this domain existed, // we need to explicitly add them. // See the explanation of implicit vs explicit binding below. d.add(req); d.add(res); // Now run the handler function in the domain. d.run(() => { handleRequest(req, res); }); }); server.listen(PORT); } // This part isn't important. Just an example routing thing. // You'd put your fancy application logic here. function handleRequest(req, res) { switch(req.url) { case '/error': // We do some async stuff, and then... setTimeout(() => { // Whoops! flerb.bark(); }); break; default: res.end('ok'); } } ``` ## Additions to Error objects Any time an `Error` object is routed through a domain, a few extra fields are added to it. * `error.domain` The domain that first handled the error. * `error.domainEmitter` The event emitter that emitted an `'error'` event with the error object. * `error.domainBound` The callback function which was bound to the domain, and passed an error as its first argument. * `error.domainThrown` A boolean indicating whether the error was thrown, emitted, or passed to a bound callback function. ## Implicit Binding If domains are in use, then all **new** EventEmitter objects (including Stream objects, requests, responses, etc.) will be implicitly bound to the active domain at the time of their creation. Additionally, callbacks passed to lowlevel event loop requests (such as to fs.open, or other callback-taking methods) will automatically be bound to the active domain. If they throw, then the domain will catch the error. In order to prevent excessive memory usage, Domain objects themselves are not implicitly added as children of the active domain. If they were, then it would be too easy to prevent request and response objects from being properly garbage collected. If you *want* to nest Domain objects as children of a parent Domain, then you must explicitly add them. Implicit binding routes thrown errors and `'error'` events to the Domain's `'error'` event, but does not register the EventEmitter on the Domain, so [`domain.dispose()`][] will not shut down the EventEmitter. Implicit binding only takes care of thrown errors and `'error'` events. ## Explicit Binding Sometimes, the domain in use is not the one that ought to be used for a specific event emitter. Or, the event emitter could have been created in the context of one domain, but ought to instead be bound to some other domain. For example, there could be one domain in use for an HTTP server, but perhaps we would like to have a separate domain to use for each request. That is possible via explicit binding. For example: ``` // create a top-level domain for the server const domain = require('domain'); const http = require('http'); const serverDomain = domain.create(); serverDomain.run(() => { // server is created in the scope of serverDomain http.createServer((req, res) => { // req and res are also created in the scope of serverDomain // however, we'd prefer to have a separate domain for each request. // create it first thing, and add req and res to it. var reqd = domain.create(); reqd.add(req); reqd.add(res); reqd.on('error', (er) => { console.error('Error', er, req.url); try { res.writeHead(500); res.end('Error occurred, sorry.'); } catch (er) { console.error('Error sending 500', er, req.url); } }); }).listen(1337); }); ``` ## domain.create() * return: {Domain} Returns a new Domain object. ## Class: Domain The Domain class encapsulates the functionality of routing errors and uncaught exceptions to the active Domain object. Domain is a child class of [`EventEmitter`][]. To handle the errors that it catches, listen to its `'error'` event. ### domain.run(fn[, arg][, ...]) * `fn` {Function} Run the supplied function in the context of the domain, implicitly binding all event emitters, timers, and lowlevel requests that are created in that context. Optionally, arguments can be passed to the function. This is the most basic way to use a domain. Example: ``` const domain = require('domain'); const fs = require('fs'); const d = domain.create(); d.on('error', (er) => { console.error('Caught error!', er); }); d.run(() => { process.nextTick(() => { setTimeout(() => { // simulating some various async stuff fs.open('non-existent file', 'r', (er, fd) => { if (er) throw er; // proceed... }); }, 100); }); }); ``` In this example, the `d.on('error')` handler will be triggered, rather than crashing the program. ### domain.members * {Array} An array of timers and event emitters that have been explicitly added to the domain. ### domain.add(emitter) * `emitter` {EventEmitter | Timer} emitter or timer to be added to the domain Explicitly adds an emitter to the domain. If any event handlers called by the emitter throw an error, or if the emitter emits an `'error'` event, it will be routed to the domain's `'error'` event, just like with implicit binding. This also works with timers that are returned from [`setInterval()`][] and [`setTimeout()`][]. If their callback function throws, it will be caught by the domain 'error' handler. If the Timer or EventEmitter was already bound to a domain, it is removed from that one, and bound to this one instead. ### domain.remove(emitter) * `emitter` {EventEmitter | Timer} emitter or timer to be removed from the domain The opposite of [`domain.add(emitter)`][]. Removes domain handling from the specified emitter. ### domain.bind(callback) * `callback` {Function} The callback function * return: {Function} The bound function The returned function will be a wrapper around the supplied callback function. When the returned function is called, any errors that are thrown will be routed to the domain's `'error'` event. #### Example const d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.bind(function(er, data) { // if this throws, it will also be passed to the domain return cb(er, data ? JSON.parse(data) : null); })); } d.on('error', (er) => { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. }); ### domain.intercept(callback) * `callback` {Function} The callback function * return: {Function} The intercepted function This method is almost identical to [`domain.bind(callback)`][]. However, in addition to catching thrown errors, it will also intercept [`Error`][] objects sent as the first argument to the function. In this way, the common `if (err) return callback(err);` pattern can be replaced with a single error handler in a single place. #### Example const d = domain.create(); function readSomeFile(filename, cb) { fs.readFile(filename, 'utf8', d.intercept(function(data) { // note, the first argument is never passed to the // callback since it is assumed to be the 'Error' argument // and thus intercepted by the domain. // if this throws, it will also be passed to the domain // so the error-handling logic can be moved to the 'error' // event on the domain instead of being repeated throughout // the program. return cb(null, JSON.parse(data)); })); } d.on('error', (er) => { // an error occurred somewhere. // if we throw it now, it will crash the program // with the normal line number and stack message. }); ### domain.enter() The `enter` method is plumbing used by the `run`, `bind`, and `intercept` methods to set the active domain. It sets `domain.active` and `process.domain` to the domain, and implicitly pushes the domain onto the domain stack managed by the domain module (see [`domain.exit()`][] for details on the domain stack). The call to `enter` delimits the beginning of a chain of asynchronous calls and I/O operations bound to a domain. Calling `enter` changes only the active domain, and does not alter the domain itself. `enter` and `exit` can be called an arbitrary number of times on a single domain. If the domain on which `enter` is called has been disposed, `enter` will return without setting the domain. ### domain.exit() The `exit` method exits the current domain, popping it off the domain stack. Any time execution is going to switch to the context of a different chain of asynchronous calls, it's important to ensure that the current domain is exited. The call to `exit` delimits either the end of or an interruption to the chain of asynchronous calls and I/O operations bound to a domain. If there are multiple, nested domains bound to the current execution context, `exit` will exit any domains nested within this domain. Calling `exit` changes only the active domain, and does not alter the domain itself. `enter` and `exit` can be called an arbitrary number of times on a single domain. If the domain on which `exit` is called has been disposed, `exit` will return without exiting the domain. ### domain.dispose() Stability: 0 - Deprecated. Please recover from failed IO actions explicitly via error event handlers set on the domain. Once `dispose` has been called, the domain will no longer be used by callbacks bound into the domain via `run`, `bind`, or `intercept`, and a `'dispose'` event is emitted. [`domain.add(emitter)`]: #domain_domain_add_emitter [`domain.bind(callback)`]: #domain_domain_bind_callback [`domain.dispose()`]: #domain_domain_dispose [`domain.exit()`]: #domain_domain_exit [`Error`]: errors.html#errors_class_error [`EventEmitter`]: events.html#events_class_events_eventemitter [`setInterval()`]: timers.html#timers_setinterval_callback_delay_arg [`setTimeout()`]: timers.html#timers_settimeout_callback_delay_arg [`throw`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw node-v4.2.6/doc/api/errors.html000644 000766 000024 00000073623 12650222331 016475 0ustar00iojsstaff000000 000000 Errors Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Errors#

Applications running in Node.js will generally experience four categories of errors:

  • Standard JavaScript errors such as:
    • [EvalError][]: thrown when a call to eval() fails.
    • SyntaxError: thrown in response to improper JavaScript language syntax.
    • [RangeError][]: thrown when a value is not within an expected range
    • ReferenceError: thrown when using undefined variables
    • TypeError: thrown when passing arguments of the wrong type
    • [URIError][]: thrown when a global URI handling function is misused.
  • System errors triggered by underlying operating system constraints such as attempting to open a file that does not exist, attempting to send data over a closed socket, etc;
  • And User-specified errors triggered by application code.
  • Assertion Errors are a special class of error that can be triggered whenever Node.js detects an exceptional logic violation that should never occur. These are raised typically by the assert module.

All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript Error class and are guaranteed to provide at least the properties available on that class.

Error Propagation and Interception#

Node.js supports several mechanisms for propagating and handling errors that occur while an application is running. How these errors are reported and handled depends entirely on the type of Error and the style of the API that is called.

All JavaScript errors are handled as exceptions that immediately generate and throw an error using the standard JavaScript throw mechanism. These are handled using the try / catch construct provided by the JavaScript language.

// Throws with a ReferenceError because z is undefined
try {
  const m = 1;
  const n = m + z;
} catch (err) {
  // Handle the error here.
}

Any use of the JavaScript throw mechanism will raise an exception that must be handled using try / catch or the Node.js process will exit immediately.

With few exceptions, Synchronous APIs (any blocking method that does not accept a callback function, such as fs.readFileSync), will use throw to report errors.

Errors that occur within Asynchronous APIs may be reported in multiple ways:

  • Most asynchronous methods that accept a callback function will accept an Error object passed as the first argument to that function. If that first argument is not null and is an instance of Error, then an error occurred that should be handled.

    const fs = require('fs');
    fs.readFile('a file that does not exist', (err, data) => {
      if (err) {
        console.error('There was an error reading the file!', err);
        return;
      }
      // Otherwise handle the data
    });
  • When an asynchronous method is called on an object that is an EventEmitter, errors can be routed to that object's 'error' event.

    const net = require('net');
    const connection = net.connect('localhost');
    
    // Adding an 'error' event handler to a stream:
    connection.on('error', (err) => {
      // If the connection is reset by the server, or if it can't
      // connect at all, or on any sort of error encountered by
      // the connection, the error will be sent here.
      console.error(err);
    });
    
    connection.pipe(process.stdout);
  • A handful of typically asynchronous methods in the Node.js API may still use the throw mechanism to raise exceptions that must be handled using try / catch. There is no comprehensive list of such methods; please refer to the documentation of each method to determine the appropriate error handling mechanism required.

The use of the 'error' event mechanism is most common for stream-based and event emitter-based APIs, which themselves represent a series of asynchronous operations over time (as opposed to a single operation that may pass or fail).

For all EventEmitter objects, if an 'error' event handler is not provided, the error will be thrown, causing the Node.js process to report an unhandled exception and crash unless either: The domain module is used appropriately or a handler has been registered for the process.on('uncaughtException') event.

const EventEmitter = require('events');
const ee = new EventEmitter();

setImmediate(() => {
  // This will crash the process because no 'error' event
  // handler has been added.
  ee.emit('error', new Error('This will crash'));
});

Errors generated in this way cannot be intercepted using try / catch as they are thrown after the calling code has already exited.

Developers must refer to the documentation for each method to determine exactly how errors raised by those methods are propagated.

Node.js style callbacks#

Most asynchronous methods exposed by the Node.js core API follow an idiomatic pattern referred to as a "Node.js style callback". With this pattern, a callback function is passed to the method as an argument. When the operation either completes or an error is raised, the callback function is called with the Error object (if any) passed as the first argument. If no error was raised, the first argument will be passed as null.

const fs = require('fs');

function nodeStyleCallback(err, data) {
 if (err) {
   console.error('There was an error', err);
   return;
 }
 console.log(data);
}

fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);
fs.readFile('/some/file/that/does-exist', nodeStyleCallback)

The JavaScript try / catch mechanism cannot be used to intercept errors generated by asynchronous APIs. A common mistake for beginners is to try to use throw inside a Node.js style callback:

// THIS WILL NOT WORK:
const fs = require('fs');

try {
  fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    // mistaken assumption: throwing here...
    if (err) {
      throw err;
    }
  });
} catch(err) {
  // This will not catch the throw!
  console.log(err);
}

This will not work because the callback function passed to fs.readFile() is called asynchronously. By the time the callback has been called, the surrounding code (including the try { } catch(err) { } block will have already exited. Throwing an error inside the callback can crash the Node.js process in most cases. If domains are enabled, or a handler has been registered with process.on('uncaughtException'), such errors can be intercepted.

Class: Error#

A generic JavaScript Error object that does not denote any specific circumstance of why the error occurred. Error objects capture a "stack trace" detailing the point in the code at which the Error was instantiated, and may provide a text description of the error.

All errors generated by Node.js, including all System and JavaScript errors, will either be instances of, or inherit from, the Error class.

new Error(message)#

Creates a new Error object and sets the error.message property to the provided text message. If an object is passed as message, the text message is generated by calling message.toString(). The error.stack property will represent the point in the code at which new Error() was called. Stack traces are dependent on V8's stack trace API. Stack traces extend only to either (a) the beginning of synchronous code execution, or (b) the number of frames given by the property Error.stackTraceLimit, whichever is smaller.

Error.captureStackTrace(targetObject[, constructorOpt])#

Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.

const myObject = {};
Error.captureStackTrace(myObject);
myObject.stack  // similar to `new Error().stack`

The first line of the trace, instead of being prefixed with ErrorType: message, will be the result of calling targetObject.toString().

The optional constructorOpt argument accepts a function. If given, all frames above constructorOpt, including constructorOpt, will be omitted from the generated stack trace.

The constructorOpt argument is useful for hiding implementation details of error generation from an end user. For instance:

function MyError() {
  Error.captureStackTrace(this, MyError);
}

// Without passing MyError to captureStackTrace, the MyError
// frame would should up in the .stack property. by passing
// the constructor, we omit that frame and all frames above it.
new MyError().stack

Error.stackTraceLimit#

The Error.stackTraceLimit property specifies the number of stack frames collected by a stack trace (whether generated by new Error().stack or Error.captureStackTrace(obj)).

The default value is 10 but may be set to any valid JavaScript number. Changes will affect any stack trace captured after the value has been changed.

If set to a non-number value, or set to a negative number, stack traces will not capture any frames.

error.message#

Returns the string description of error as set by calling new Error(message). The message passed to the constructor will also appear in the first line of the stack trace of the Error, however changing this property after the Error object is created may not change the first line of the stack trace.

const err = new Error('The message');
console.log(err.message);
  // Prints: The message

error.stack#

Returns a string describing the point in the code at which the Error was instantiated.

For example:

Error: Things keep happening!
   at /home/gbusey/file.js:525:2
   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)
   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)
   at increaseSynergy (/home/gbusey/actors.js:701:6)

The first line is formatted as <error class name>: <error message>, and is followed by a series of stack frames (each line beginning with "at "). Each frame describes a call site within the code that lead to the error being generated. V8 attempts to display a name for each function (by variable name, function name, or object method name), but occasionally it will not be able to find a suitable name. If V8 cannot determine a name for the function, only location information will be displayed for that frame. Otherwise, the determined function name will be displayed with location information appended in parentheses.

It is important to note that frames are only generated for JavaScript functions. If, for example, execution synchronously passes through a C++ addon function called cheetahify, which itself calls a JavaScript function, the frame representing the cheetahify call will not be present in the stack traces:

const cheetahify = require('./native-binding.node');

function makeFaster() {
  // cheetahify *synchronously* calls speedy.
  cheetahify(function speedy() {
    throw new Error('oh no!');
  });
}

makeFaster(); // will throw:
  // /home/gbusey/file.js:6
  //     throw new Error('oh no!');
  //           ^
  // Error: oh no!
  //     at speedy (/home/gbusey/file.js:6:11)
  //     at makeFaster (/home/gbusey/file.js:5:3)
  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)
  //     at Module._compile (module.js:456:26)
  //     at Object.Module._extensions..js (module.js:474:10)
  //     at Module.load (module.js:356:32)
  //     at Function.Module._load (module.js:312:12)
  //     at Function.Module.runMain (module.js:497:10)
  //     at startup (node.js:119:16)
  //     at node.js:906:3

The location information will be one of:

  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • plain-filename.js:line:column, if the frame represents a call internal to Node.js.
  • /absolute/path/to/file.js:line:column, if the frame represents a call in a user program, or its dependencies.

The string representing the stack trace is lazily generated when the error.stack property is accessed.

The number of frames captured by the stack trace is bounded by the smaller of Error.stackTraceLimit or the number of available frames on the current event loop tick.

System-level errors are generated as augmented Error instances, which are detailed below.

Class: RangeError#

A subclass of Error that indicates that a provided argument was not within the set or range of acceptable values for a function; whether that is a numeric range, or outside the set of options for a given function parameter.

For example:

require('net').connect(-1);
  // throws RangeError, port should be > 0 && < 65536

Node.js will generate and throw RangeError instances immediately as a form of argument validation.

Class: ReferenceError#

A subclass of Error that indicates that an attempt is being made to access a variable that is not defined. Such errors commonly indicate typos in code, or an otherwise broken program.

While client code may generate and propagate these errors, in practice, only V8 will do so.

doesNotExist;
  // throws ReferenceError, doesNotExist is not a variable in this program.

ReferenceError instances will have an error.arguments property whose value is an array containing a single element: a string representing the variable that was not defined.

const assert = require('assert');
try {
  doesNotExist;
} catch(err) {
  assert(err.arguments[0], 'doesNotExist');
}

Unless an application is dynamically generating and running code, ReferenceError instances should always be considered a bug in the code or its dependencies.

Class: SyntaxError#

A subclass of Error that indicates that a program is not valid JavaScript. These errors may only be generated and propagated as a result of code evaluation. Code evaluation may happen as a result of eval, Function, require, or vm. These errors are almost always indicative of a broken program.

try {
  require('vm').runInThisContext('binary ! isNotOk');
} catch(err) {
  // err will be a SyntaxError
}

SyntaxError instances are unrecoverable in the context that created them – they may only be caught by other contexts.

Class: TypeError#

A subclass of Error that indicates that a provided argument is not an allowable type. For example, passing a function to a parameter which expects a string would be considered a TypeError.

require('url').parse(function() { });
  // throws TypeError, since it expected a string

Node.js will generate and throw TypeError instances immediately as a form of argument validation.

Exceptions vs. Errors#

A JavaScript exception is a value that is thrown as a result of an invalid operation or as the target of a throw statement. While it is not required that these values are instances of Error or classes which inherit from Error, all exceptions thrown by Node.js or the JavaScript runtime will be instances of Error.

Some exceptions are unrecoverable at the JavaScript layer. Such exceptions will always cause the Node.js process to crash. Examples include assert() checks or abort() calls in the C++ layer.

System Errors#

System errors are generated when exceptions occur within the program's runtime environment. Typically, these are operational errors that occur when an application violates an operating system constraint such as attempting to read a file that does not exist or when the user does not have sufficient permissions.

System errors are typically generated at the syscall level: an exhaustive list of error codes and their meanings is available by running man 2 intro or man 3 errno on most Unices; or online.

In Node.js, system errors are represented as augmented Error objects with added properties.

Class: System Error#

error.code#

error.errno#

Returns a string representing the error code, which is always E followed by a sequence of capital letters, and may be referenced in man 2 intro.

The properties error.code and error.errno are aliases of one another and return the same value.

error.syscall#

Returns a string describing the syscall that failed.

Common System Errors#

This list is not exhaustive, but enumerates many of the common system errors encountered when writing a Node.js program. An exhaustive list may be found here.

  • EACCES (Permission denied): An attempt was made to access a file in a way forbidden by its file access permissions.

  • EADDRINUSE (Address already in use): An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.

  • ECONNREFUSED (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.

  • ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the http and net modules.

  • EEXIST (File exists): An existing file was the target of an operation that required that the target not exist.

  • EISDIR (Is a directory): An operation expected a file, but the given pathname was a directory.

  • EMFILE (Too many open files in system): Maximum number of file descriptors allowable on the system has been reached, and requests for another descriptor cannot be fulfilled until at least one has been closed. This is encountered when opening many files at once in parallel, especially on systems (in particular, OS X) where there is a low file descriptor limit for processes. To remedy a low limit, run ulimit -n 2048 in the same shell that will run the Node.js process.

  • ENOENT (No such file or directory): Commonly raised by fs operations to indicate that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path.

  • ENOTDIR (Not a directory): A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.

  • ENOTEMPTY (Directory not empty): A directory with entries was the target of an operation that requires an empty directory -- usually fs.unlink.

  • EPERM (Operation not permitted): An attempt was made to perform an operation that requires elevated privileges.

  • EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the data. Commonly encountered at the net and http layers, indicative that the remote side of the stream being written to has been closed.

  • ETIMEDOUT (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by http or net -- often a sign that a socket.end() was not properly called.

node-v4.2.6/doc/api/errors.json000644 000766 000024 00000110475 12650222331 016477 0ustar00iojsstaff000000 000000 { "source": "doc/api/errors.markdown", "classes": [ { "textRaw": "Class: Error", "type": "class", "name": "Error", "desc": "

A generic JavaScript Error object that does not denote any specific\ncircumstance of why the error occurred. Error objects capture a "stack trace"\ndetailing the point in the code at which the Error was instantiated, and may\nprovide a text description of the error.\n\n

\n

All errors generated by Node.js, including all System and JavaScript errors,\nwill either be instances of, or inherit from, the Error class.\n\n

\n", "methods": [ { "textRaw": "Error.captureStackTrace(targetObject[, constructorOpt])", "type": "method", "name": "captureStackTrace", "desc": "

Creates a .stack property on targetObject, which when accessed returns\na string representing the location in the code at which\nError.captureStackTrace() was called.\n\n

\n
const myObject = {};\nError.captureStackTrace(myObject);\nmyObject.stack  // similar to `new Error().stack`
\n

The first line of the trace, instead of being prefixed with ErrorType:\nmessage, will be the result of calling targetObject.toString().\n\n

\n

The optional constructorOpt argument accepts a function. If given, all frames\nabove constructorOpt, including constructorOpt, will be omitted from the\ngenerated stack trace.\n\n

\n

The constructorOpt argument is useful for hiding implementation\ndetails of error generation from an end user. For instance:\n\n

\n
function MyError() {\n  Error.captureStackTrace(this, MyError);\n}\n\n// Without passing MyError to captureStackTrace, the MyError\n// frame would should up in the .stack property. by passing\n// the constructor, we omit that frame and all frames above it.\nnew MyError().stack
\n", "signatures": [ { "params": [ { "name": "targetObject" }, { "name": "constructorOpt", "optional": true } ] } ] } ], "properties": [ { "textRaw": "Error.stackTraceLimit", "name": "stackTraceLimit", "desc": "

The Error.stackTraceLimit property specifies the number of stack frames\ncollected by a stack trace (whether generated by new Error().stack or\nError.captureStackTrace(obj)).\n\n

\n

The default value is 10 but may be set to any valid JavaScript number. Changes\nwill affect any stack trace captured after the value has been changed.\n\n

\n

If set to a non-number value, or set to a negative number, stack traces will\nnot capture any frames.\n\n

\n", "properties": [ { "textRaw": "error.message", "name": "message", "desc": "

Returns the string description of error as set by calling new Error(message).\nThe message passed to the constructor will also appear in the first line of\nthe stack trace of the Error, however changing this property after the\nError object is created may not change the first line of the stack trace.\n\n

\n
const err = new Error('The message');\nconsole.log(err.message);\n  // Prints: The message
\n" }, { "textRaw": "error.stack", "name": "stack", "desc": "

Returns a string describing the point in the code at which the Error was\ninstantiated.\n\n

\n

For example:\n\n

\n
Error: Things keep happening!\n   at /home/gbusey/file.js:525:2\n   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)\n   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)\n   at increaseSynergy (/home/gbusey/actors.js:701:6)
\n

The first line is formatted as <error class name>: <error message>, and\nis followed by a series of stack frames (each line beginning with "at ").\nEach frame describes a call site within the code that lead to the error being\ngenerated. V8 attempts to display a name for each function (by variable name,\nfunction name, or object method name), but occasionally it will not be able to\nfind a suitable name. If V8 cannot determine a name for the function, only\nlocation information will be displayed for that frame. Otherwise, the\ndetermined function name will be displayed with location information appended\nin parentheses.\n\n

\n

It is important to note that frames are only generated for JavaScript\nfunctions. If, for example, execution synchronously passes through a C++ addon\nfunction called cheetahify, which itself calls a JavaScript function, the\nframe representing the cheetahify call will not be present in the stack\ntraces:\n\n

\n
const cheetahify = require('./native-binding.node');\n\nfunction makeFaster() {\n  // cheetahify *synchronously* calls speedy.\n  cheetahify(function speedy() {\n    throw new Error('oh no!');\n  });\n}\n\nmakeFaster(); // will throw:\n  // /home/gbusey/file.js:6\n  //     throw new Error('oh no!');\n  //           ^\n  // Error: oh no!\n  //     at speedy (/home/gbusey/file.js:6:11)\n  //     at makeFaster (/home/gbusey/file.js:5:3)\n  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)\n  //     at Module._compile (module.js:456:26)\n  //     at Object.Module._extensions..js (module.js:474:10)\n  //     at Module.load (module.js:356:32)\n  //     at Function.Module._load (module.js:312:12)\n  //     at Function.Module.runMain (module.js:497:10)\n  //     at startup (node.js:119:16)\n  //     at node.js:906:3
\n

The location information will be one of:\n\n

\n
    \n
  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • \n
  • plain-filename.js:line:column, if the frame represents a call internal\n to Node.js.
  • \n
  • /absolute/path/to/file.js:line:column, if the frame represents a call in\na user program, or its dependencies.
  • \n
\n

The string representing the stack trace is lazily generated when the\nerror.stack property is accessed.\n\n

\n

The number of frames captured by the stack trace is bounded by the smaller of\nError.stackTraceLimit or the number of available frames on the current event\nloop tick.\n\n

\n

System-level errors are generated as augmented Error instances, which are\ndetailed below.\n\n

\n" } ] } ], "signatures": [ { "params": [ { "name": "message" } ], "desc": "

Creates a new Error object and sets the error.message property to the\nprovided text message. If an object is passed as message, the text message\nis generated by calling message.toString(). The error.stack property will\nrepresent the point in the code at which new Error() was called. Stack traces\nare dependent on [V8's stack trace API][]. Stack traces extend only to either\n(a) the beginning of synchronous code execution, or (b) the number of frames\ngiven by the property Error.stackTraceLimit, whichever is smaller.\n\n

\n" } ] }, { "textRaw": "Class: RangeError", "type": "class", "name": "RangeError", "desc": "

A subclass of Error that indicates that a provided argument was not within the\nset or range of acceptable values for a function; whether that is a numeric\nrange, or outside the set of options for a given function parameter.\n\n

\n

For example:\n\n

\n
require('net').connect(-1);\n  // throws RangeError, port should be > 0 && < 65536
\n

Node.js will generate and throw RangeError instances immediately as a form\nof argument validation.\n\n

\n" }, { "textRaw": "Class: ReferenceError", "type": "class", "name": "ReferenceError", "desc": "

A subclass of Error that indicates that an attempt is being made to access a\nvariable that is not defined. Such errors commonly indicate typos in code, or\nan otherwise broken program.\n\n

\n

While client code may generate and propagate these errors, in practice, only V8\nwill do so.\n\n

\n
doesNotExist;\n  // throws ReferenceError, doesNotExist is not a variable in this program.
\n

ReferenceError instances will have an error.arguments property whose value\nis an array containing a single element: a string representing the variable\nthat was not defined.\n\n

\n
const assert = require('assert');\ntry {\n  doesNotExist;\n} catch(err) {\n  assert(err.arguments[0], 'doesNotExist');\n}
\n

Unless an application is dynamically generating and running code,\nReferenceError instances should always be considered a bug in the code\nor its dependencies.\n\n

\n" }, { "textRaw": "Class: SyntaxError", "type": "class", "name": "SyntaxError", "desc": "

A subclass of Error that indicates that a program is not valid JavaScript.\nThese errors may only be generated and propagated as a result of code\nevaluation. Code evaluation may happen as a result of eval, Function,\nrequire, or [vm][]. These errors are almost always indicative of a broken\nprogram.\n\n

\n
try {\n  require('vm').runInThisContext('binary ! isNotOk');\n} catch(err) {\n  // err will be a SyntaxError\n}
\n

SyntaxError instances are unrecoverable in the context that created them –\nthey may only be caught by other contexts.\n\n

\n" }, { "textRaw": "Class: TypeError", "type": "class", "name": "TypeError", "desc": "

A subclass of Error that indicates that a provided argument is not an\nallowable type. For example, passing a function to a parameter which expects a\nstring would be considered a TypeError.\n\n

\n
require('url').parse(function() { });\n  // throws TypeError, since it expected a string
\n

Node.js will generate and throw TypeError instances immediately as a form\nof argument validation.\n\n

\n" } ], "miscs": [ { "textRaw": "Errors", "name": "Errors", "type": "misc", "desc": "

Applications running in Node.js will generally experience four categories of\nerrors:\n\n

\n
    \n
  • Standard JavaScript errors such as:
      \n
    • [EvalError][]: thrown when a call to eval() fails.
    • \n
    • [SyntaxError][]: thrown in response to improper JavaScript language\nsyntax.
    • \n
    • [RangeError][]: thrown when a value is not within an expected range
    • \n
    • [ReferenceError][]: thrown when using undefined variables
    • \n
    • [TypeError][]: thrown when passing arguments of the wrong type
    • \n
    • [URIError][]: thrown when a global URI handling function is misused.
    • \n
    \n
  • \n
  • System errors triggered by underlying operating system constraints such\nas attempting to open a file that does not exist, attempting to send data\nover a closed socket, etc;
  • \n
  • And User-specified errors triggered by application code.
  • \n
  • Assertion Errors are a special class of error that can be triggered whenever\nNode.js detects an exceptional logic violation that should never occur. These\nare raised typically by the assert module.
  • \n
\n

All JavaScript and System errors raised by Node.js inherit from, or are\ninstances of, the standard JavaScript [Error][] class and are guaranteed\nto provide at least the properties available on that class.\n\n

\n", "miscs": [ { "textRaw": "Error Propagation and Interception", "name": "Error Propagation and Interception", "type": "misc", "desc": "

Node.js supports several mechanisms for propagating and handling errors that\noccur while an application is running. How these errors are reported and\nhandled depends entirely on the type of Error and the style of the API that is\ncalled.\n\n

\n

All JavaScript errors are handled as exceptions that immediately generate\nand throw an error using the standard JavaScript throw mechanism. These\nare handled using the [try / catch construct][] provided by the JavaScript\nlanguage.\n\n

\n
// Throws with a ReferenceError because z is undefined\ntry {\n  const m = 1;\n  const n = m + z;\n} catch (err) {\n  // Handle the error here.\n}
\n

Any use of the JavaScript throw mechanism will raise an exception that\nmust be handled using try / catch or the Node.js process will exit\nimmediately.\n\n

\n

With few exceptions, Synchronous APIs (any blocking method that does not\naccept a callback function, such as [fs.readFileSync][]), will use throw\nto report errors.\n\n

\n

Errors that occur within Asynchronous APIs may be reported in multiple ways:\n\n

\n
    \n
  • Most asynchronous methods that accept a callback function will accept an\nError object passed as the first argument to that function. If that first\nargument is not null and is an instance of Error, then an error occurred\nthat should be handled.

    \n
    const fs = require('fs');\nfs.readFile('a file that does not exist', (err, data) => {\n  if (err) {\n    console.error('There was an error reading the file!', err);\n    return;\n  }\n  // Otherwise handle the data\n});
    \n
  • \n
  • When an asynchronous method is called on an object that is an EventEmitter,\nerrors can be routed to that object's 'error' event.

    \n
    const net = require('net');\nconst connection = net.connect('localhost');\n\n// Adding an 'error' event handler to a stream:\nconnection.on('error', (err) => {\n  // If the connection is reset by the server, or if it can't\n  // connect at all, or on any sort of error encountered by\n  // the connection, the error will be sent here.\n  console.error(err);\n});\n\nconnection.pipe(process.stdout);
    \n
  • \n
  • A handful of typically asynchronous methods in the Node.js API may still\nuse the throw mechanism to raise exceptions that must be handled using\ntry / catch. There is no comprehensive list of such methods; please\nrefer to the documentation of each method to determine the appropriate\nerror handling mechanism required.

    \n
  • \n
\n

The use of the 'error' event mechanism is most common for [stream-based][]\nand [event emitter-based][] APIs, which themselves represent a series of\nasynchronous operations over time (as opposed to a single operation that may\npass or fail).\n\n

\n

For all EventEmitter objects, if an 'error' event handler is not\nprovided, the error will be thrown, causing the Node.js process to report an\nunhandled exception and crash unless either: The [domain][] module is used\nappropriately or a handler has been registered for the\n[process.on('uncaughtException')][] event.\n\n

\n
const EventEmitter = require('events');\nconst ee = new EventEmitter();\n\nsetImmediate(() => {\n  // This will crash the process because no 'error' event\n  // handler has been added.\n  ee.emit('error', new Error('This will crash'));\n});
\n

Errors generated in this way cannot be intercepted using try / catch as\nthey are thrown after the calling code has already exited.\n\n

\n

Developers must refer to the documentation for each method to determine\nexactly how errors raised by those methods are propagated.\n\n

\n", "miscs": [ { "textRaw": "Node.js style callbacks", "name": "Node.js style callbacks", "type": "misc", "desc": "

Most asynchronous methods exposed by the Node.js core API follow an idiomatic\npattern referred to as a "Node.js style callback". With this pattern, a\ncallback function is passed to the method as an argument. When the operation\neither completes or an error is raised, the callback function is called with\nthe Error object (if any) passed as the first argument. If no error was raised,\nthe first argument will be passed as null.\n\n

\n
const fs = require('fs');\n\nfunction nodeStyleCallback(err, data) {\n if (err) {\n   console.error('There was an error', err);\n   return;\n }\n console.log(data);\n}\n\nfs.readFile('/some/file/that/does-not-exist', nodeStyleCallback);\nfs.readFile('/some/file/that/does-exist', nodeStyleCallback)
\n

The JavaScript try / catch mechanism cannot be used to intercept errors\ngenerated by asynchronous APIs. A common mistake for beginners is to try to\nuse throw inside a Node.js style callback:\n\n

\n
// THIS WILL NOT WORK:\nconst fs = require('fs');\n\ntry {\n  fs.readFile('/some/file/that/does-not-exist', (err, data) => {\n    // mistaken assumption: throwing here...\n    if (err) {\n      throw err;\n    }\n  });\n} catch(err) {\n  // This will not catch the throw!\n  console.log(err);\n}
\n

This will not work because the callback function passed to fs.readFile() is\ncalled asynchronously. By the time the callback has been called, the\nsurrounding code (including the try { } catch(err) { } block will have\nalready exited. Throwing an error inside the callback can crash the Node.js\nprocess in most cases. If [domains][] are enabled, or a handler has been\nregistered with process.on('uncaughtException'), such errors can be\nintercepted.\n\n

\n" } ] }, { "textRaw": "Exceptions vs. Errors", "name": "Exceptions vs. Errors", "type": "misc", "desc": "

A JavaScript exception is a value that is thrown as a result of an invalid\noperation or as the target of a throw statement. While it is not required\nthat these values are instances of Error or classes which inherit from\nError, all exceptions thrown by Node.js or the JavaScript runtime will be\ninstances of Error.\n\n

\n

Some exceptions are unrecoverable at the JavaScript layer. Such exceptions\nwill always cause the Node.js process to crash. Examples include assert()\nchecks or abort() calls in the C++ layer.\n\n

\n" }, { "textRaw": "System Errors", "name": "system_errors", "desc": "

System errors are generated when exceptions occur within the program's\nruntime environment. Typically, these are operational errors that occur\nwhen an application violates an operating system constraint such as attempting\nto read a file that does not exist or when the user does not have sufficient\npermissions.\n\n

\n

System errors are typically generated at the syscall level: an exhaustive list\nof error codes and their meanings is available by running man 2 intro or\nman 3 errno on most Unices; or [online][].\n\n

\n

In Node.js, system errors are represented as augmented Error objects with\nadded properties.\n\n

\n", "classes": [ { "textRaw": "Class: System Error", "type": "class", "name": "System", "properties": [ { "textRaw": "error.code", "name": "code", "desc": "

Returns a string representing the error code, which is always E followed by\na sequence of capital letters, and may be referenced in man 2 intro.\n\n

\n

The properties error.code and error.errno are aliases of one another and\nreturn the same value.\n\n

\n" }, { "textRaw": "error.errno", "name": "errno", "desc": "

Returns a string representing the error code, which is always E followed by\na sequence of capital letters, and may be referenced in man 2 intro.\n\n

\n

The properties error.code and error.errno are aliases of one another and\nreturn the same value.\n\n

\n" }, { "textRaw": "error.syscall", "name": "syscall", "desc": "

Returns a string describing the [syscall][] that failed.\n\n

\n" } ] } ], "modules": [ { "textRaw": "Common System Errors", "name": "common_system_errors", "desc": "

This list is not exhaustive, but enumerates many of the common system\nerrors encountered when writing a Node.js program. An exhaustive list may be\nfound [here][online].\n\n

\n
    \n
  • EACCES (Permission denied): An attempt was made to access a file in a way\nforbidden by its file access permissions.

    \n
  • \n
  • EADDRINUSE (Address already in use): An attempt to bind a server\n([net][], [http][], or [https][]) to a local address failed due to\nanother server on the local system already occupying that address.

    \n
  • \n
  • ECONNREFUSED (Connection refused): No connection could be made because the\ntarget machine actively refused it. This usually results from trying to\nconnect to a service that is inactive on the foreign host.

    \n
  • \n
  • ECONNRESET (Connection reset by peer): A connection was forcibly closed by\na peer. This normally results from a loss of the connection on the remote\nsocket due to a timeout or reboot. Commonly encountered via the [http][]\nand [net][] modules.

    \n
  • \n
  • EEXIST (File exists): An existing file was the target of an operation that\nrequired that the target not exist.

    \n
  • \n
  • EISDIR (Is a directory): An operation expected a file, but the given\npathname was a directory.

    \n
  • \n
  • EMFILE (Too many open files in system): Maximum number of\n[file descriptors][] allowable on the system has been reached, and\nrequests for another descriptor cannot be fulfilled until at least one\nhas been closed. This is encountered when opening many files at once in\nparallel, especially on systems (in particular, OS X) where there is a low\nfile descriptor limit for processes. To remedy a low limit, run\nulimit -n 2048 in the same shell that will run the Node.js process.

    \n
  • \n
  • ENOENT (No such file or directory): Commonly raised by [fs][] operations\nto indicate that a component of the specified pathname does not exist -- no\nentity (file or directory) could be found by the given path.

    \n
  • \n
  • ENOTDIR (Not a directory): A component of the given pathname existed, but\nwas not a directory as expected. Commonly raised by [fs.readdir][].

    \n
  • \n
  • ENOTEMPTY (Directory not empty): A directory with entries was the target\nof an operation that requires an empty directory -- usually [fs.unlink][].

    \n
  • \n
  • EPERM (Operation not permitted): An attempt was made to perform an\noperation that requires elevated privileges.

    \n
  • \n
  • EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is\nno process to read the data. Commonly encountered at the [net][] and\n[http][] layers, indicative that the remote side of the stream being\nwritten to has been closed.

    \n
  • \n
  • ETIMEDOUT (Operation timed out): A connect or send request failed because\nthe connected party did not properly respond after a period of time. Usually\nencountered by [http][] or [net][] -- often a sign that a socket.end()\nwas not properly called.

    \n
  • \n
\n", "type": "module", "displayName": "Common System Errors" } ], "type": "misc", "displayName": "System Errors" } ], "classes": [ { "textRaw": "Class: Error", "type": "class", "name": "Error", "desc": "

A generic JavaScript Error object that does not denote any specific\ncircumstance of why the error occurred. Error objects capture a "stack trace"\ndetailing the point in the code at which the Error was instantiated, and may\nprovide a text description of the error.\n\n

\n

All errors generated by Node.js, including all System and JavaScript errors,\nwill either be instances of, or inherit from, the Error class.\n\n

\n", "methods": [ { "textRaw": "Error.captureStackTrace(targetObject[, constructorOpt])", "type": "method", "name": "captureStackTrace", "desc": "

Creates a .stack property on targetObject, which when accessed returns\na string representing the location in the code at which\nError.captureStackTrace() was called.\n\n

\n
const myObject = {};\nError.captureStackTrace(myObject);\nmyObject.stack  // similar to `new Error().stack`
\n

The first line of the trace, instead of being prefixed with ErrorType:\nmessage, will be the result of calling targetObject.toString().\n\n

\n

The optional constructorOpt argument accepts a function. If given, all frames\nabove constructorOpt, including constructorOpt, will be omitted from the\ngenerated stack trace.\n\n

\n

The constructorOpt argument is useful for hiding implementation\ndetails of error generation from an end user. For instance:\n\n

\n
function MyError() {\n  Error.captureStackTrace(this, MyError);\n}\n\n// Without passing MyError to captureStackTrace, the MyError\n// frame would should up in the .stack property. by passing\n// the constructor, we omit that frame and all frames above it.\nnew MyError().stack
\n", "signatures": [ { "params": [ { "name": "targetObject" }, { "name": "constructorOpt", "optional": true } ] } ] } ], "properties": [ { "textRaw": "Error.stackTraceLimit", "name": "stackTraceLimit", "desc": "

The Error.stackTraceLimit property specifies the number of stack frames\ncollected by a stack trace (whether generated by new Error().stack or\nError.captureStackTrace(obj)).\n\n

\n

The default value is 10 but may be set to any valid JavaScript number. Changes\nwill affect any stack trace captured after the value has been changed.\n\n

\n

If set to a non-number value, or set to a negative number, stack traces will\nnot capture any frames.\n\n

\n", "properties": [ { "textRaw": "error.message", "name": "message", "desc": "

Returns the string description of error as set by calling new Error(message).\nThe message passed to the constructor will also appear in the first line of\nthe stack trace of the Error, however changing this property after the\nError object is created may not change the first line of the stack trace.\n\n

\n
const err = new Error('The message');\nconsole.log(err.message);\n  // Prints: The message
\n" }, { "textRaw": "error.stack", "name": "stack", "desc": "

Returns a string describing the point in the code at which the Error was\ninstantiated.\n\n

\n

For example:\n\n

\n
Error: Things keep happening!\n   at /home/gbusey/file.js:525:2\n   at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21)\n   at Actor.<anonymous> (/home/gbusey/actors.js:400:8)\n   at increaseSynergy (/home/gbusey/actors.js:701:6)
\n

The first line is formatted as <error class name>: <error message>, and\nis followed by a series of stack frames (each line beginning with "at ").\nEach frame describes a call site within the code that lead to the error being\ngenerated. V8 attempts to display a name for each function (by variable name,\nfunction name, or object method name), but occasionally it will not be able to\nfind a suitable name. If V8 cannot determine a name for the function, only\nlocation information will be displayed for that frame. Otherwise, the\ndetermined function name will be displayed with location information appended\nin parentheses.\n\n

\n

It is important to note that frames are only generated for JavaScript\nfunctions. If, for example, execution synchronously passes through a C++ addon\nfunction called cheetahify, which itself calls a JavaScript function, the\nframe representing the cheetahify call will not be present in the stack\ntraces:\n\n

\n
const cheetahify = require('./native-binding.node');\n\nfunction makeFaster() {\n  // cheetahify *synchronously* calls speedy.\n  cheetahify(function speedy() {\n    throw new Error('oh no!');\n  });\n}\n\nmakeFaster(); // will throw:\n  // /home/gbusey/file.js:6\n  //     throw new Error('oh no!');\n  //           ^\n  // Error: oh no!\n  //     at speedy (/home/gbusey/file.js:6:11)\n  //     at makeFaster (/home/gbusey/file.js:5:3)\n  //     at Object.<anonymous> (/home/gbusey/file.js:10:1)\n  //     at Module._compile (module.js:456:26)\n  //     at Object.Module._extensions..js (module.js:474:10)\n  //     at Module.load (module.js:356:32)\n  //     at Function.Module._load (module.js:312:12)\n  //     at Function.Module.runMain (module.js:497:10)\n  //     at startup (node.js:119:16)\n  //     at node.js:906:3
\n

The location information will be one of:\n\n

\n
    \n
  • native, if the frame represents a call internal to V8 (as in [].forEach).
  • \n
  • plain-filename.js:line:column, if the frame represents a call internal\n to Node.js.
  • \n
  • /absolute/path/to/file.js:line:column, if the frame represents a call in\na user program, or its dependencies.
  • \n
\n

The string representing the stack trace is lazily generated when the\nerror.stack property is accessed.\n\n

\n

The number of frames captured by the stack trace is bounded by the smaller of\nError.stackTraceLimit or the number of available frames on the current event\nloop tick.\n\n

\n

System-level errors are generated as augmented Error instances, which are\ndetailed below.\n\n

\n" } ] } ], "signatures": [ { "params": [ { "name": "message" } ], "desc": "

Creates a new Error object and sets the error.message property to the\nprovided text message. If an object is passed as message, the text message\nis generated by calling message.toString(). The error.stack property will\nrepresent the point in the code at which new Error() was called. Stack traces\nare dependent on [V8's stack trace API][]. Stack traces extend only to either\n(a) the beginning of synchronous code execution, or (b) the number of frames\ngiven by the property Error.stackTraceLimit, whichever is smaller.\n\n

\n" } ] }, { "textRaw": "Class: RangeError", "type": "class", "name": "RangeError", "desc": "

A subclass of Error that indicates that a provided argument was not within the\nset or range of acceptable values for a function; whether that is a numeric\nrange, or outside the set of options for a given function parameter.\n\n

\n

For example:\n\n

\n
require('net').connect(-1);\n  // throws RangeError, port should be > 0 && < 65536
\n

Node.js will generate and throw RangeError instances immediately as a form\nof argument validation.\n\n

\n" }, { "textRaw": "Class: ReferenceError", "type": "class", "name": "ReferenceError", "desc": "

A subclass of Error that indicates that an attempt is being made to access a\nvariable that is not defined. Such errors commonly indicate typos in code, or\nan otherwise broken program.\n\n

\n

While client code may generate and propagate these errors, in practice, only V8\nwill do so.\n\n

\n
doesNotExist;\n  // throws ReferenceError, doesNotExist is not a variable in this program.
\n

ReferenceError instances will have an error.arguments property whose value\nis an array containing a single element: a string representing the variable\nthat was not defined.\n\n

\n
const assert = require('assert');\ntry {\n  doesNotExist;\n} catch(err) {\n  assert(err.arguments[0], 'doesNotExist');\n}
\n

Unless an application is dynamically generating and running code,\nReferenceError instances should always be considered a bug in the code\nor its dependencies.\n\n

\n" }, { "textRaw": "Class: SyntaxError", "type": "class", "name": "SyntaxError", "desc": "

A subclass of Error that indicates that a program is not valid JavaScript.\nThese errors may only be generated and propagated as a result of code\nevaluation. Code evaluation may happen as a result of eval, Function,\nrequire, or [vm][]. These errors are almost always indicative of a broken\nprogram.\n\n

\n
try {\n  require('vm').runInThisContext('binary ! isNotOk');\n} catch(err) {\n  // err will be a SyntaxError\n}
\n

SyntaxError instances are unrecoverable in the context that created them –\nthey may only be caught by other contexts.\n\n

\n" }, { "textRaw": "Class: TypeError", "type": "class", "name": "TypeError", "desc": "

A subclass of Error that indicates that a provided argument is not an\nallowable type. For example, passing a function to a parameter which expects a\nstring would be considered a TypeError.\n\n

\n
require('url').parse(function() { });\n  // throws TypeError, since it expected a string
\n

Node.js will generate and throw TypeError instances immediately as a form\nof argument validation.\n\n

\n" } ] } ] } node-v4.2.6/doc/api/errors.markdown000644 000766 000024 00000050574 12650222326 017357 0ustar00iojsstaff000000 000000 # Errors Applications running in Node.js will generally experience four categories of errors: - Standard JavaScript errors such as: - [`EvalError`][]: thrown when a call to `eval()` fails. - [`SyntaxError`][]: thrown in response to improper JavaScript language syntax. - [`RangeError`][]: thrown when a value is not within an expected range - [`ReferenceError`][]: thrown when using undefined variables - [`TypeError`][]: thrown when passing arguments of the wrong type - [`URIError`][]: thrown when a global URI handling function is misused. - System errors triggered by underlying operating system constraints such as attempting to open a file that does not exist, attempting to send data over a closed socket, etc; - And User-specified errors triggered by application code. - Assertion Errors are a special class of error that can be triggered whenever Node.js detects an exceptional logic violation that should never occur. These are raised typically by the `assert` module. All JavaScript and System errors raised by Node.js inherit from, or are instances of, the standard JavaScript [`Error`][] class and are guaranteed to provide *at least* the properties available on that class. ## Error Propagation and Interception Node.js supports several mechanisms for propagating and handling errors that occur while an application is running. How these errors are reported and handled depends entirely on the type of Error and the style of the API that is called. All JavaScript errors are handled as exceptions that *immediately* generate and throw an error using the standard JavaScript `throw` mechanism. These are handled using the [`try / catch` construct][] provided by the JavaScript language. // Throws with a ReferenceError because z is undefined try { const m = 1; const n = m + z; } catch (err) { // Handle the error here. } Any use of the JavaScript `throw` mechanism will raise an exception that *must* be handled using `try / catch` or the Node.js process will exit immediately. With few exceptions, _Synchronous_ APIs (any blocking method that does not accept a `callback` function, such as [`fs.readFileSync`][]), will use `throw` to report errors. Errors that occur within _Asynchronous APIs_ may be reported in multiple ways: - Most asynchronous methods that accept a `callback` function will accept an `Error` object passed as the first argument to that function. If that first argument is not `null` and is an instance of `Error`, then an error occurred that should be handled. ``` const fs = require('fs'); fs.readFile('a file that does not exist', (err, data) => { if (err) { console.error('There was an error reading the file!', err); return; } // Otherwise handle the data }); ``` - When an asynchronous method is called on an object that is an `EventEmitter`, errors can be routed to that object's `'error'` event. ``` const net = require('net'); const connection = net.connect('localhost'); // Adding an 'error' event handler to a stream: connection.on('error', (err) => { // If the connection is reset by the server, or if it can't // connect at all, or on any sort of error encountered by // the connection, the error will be sent here. console.error(err); }); connection.pipe(process.stdout); ``` - A handful of typically asynchronous methods in the Node.js API may still use the `throw` mechanism to raise exceptions that must be handled using `try / catch`. There is no comprehensive list of such methods; please refer to the documentation of each method to determine the appropriate error handling mechanism required. The use of the `'error'` event mechanism is most common for [stream-based][] and [event emitter-based][] APIs, which themselves represent a series of asynchronous operations over time (as opposed to a single operation that may pass or fail). For *all* `EventEmitter` objects, if an `'error'` event handler is not provided, the error will be thrown, causing the Node.js process to report an unhandled exception and crash unless either: The [`domain`][] module is used appropriately or a handler has been registered for the [`process.on('uncaughtException')`][] event. const EventEmitter = require('events'); const ee = new EventEmitter(); setImmediate(() => { // This will crash the process because no 'error' event // handler has been added. ee.emit('error', new Error('This will crash')); }); Errors generated in this way *cannot* be intercepted using `try / catch` as they are thrown *after* the calling code has already exited. Developers must refer to the documentation for each method to determine exactly how errors raised by those methods are propagated. ### Node.js style callbacks Most asynchronous methods exposed by the Node.js core API follow an idiomatic pattern referred to as a "Node.js style callback". With this pattern, a callback function is passed to the method as an argument. When the operation either completes or an error is raised, the callback function is called with the Error object (if any) passed as the first argument. If no error was raised, the first argument will be passed as `null`. const fs = require('fs'); function nodeStyleCallback(err, data) { if (err) { console.error('There was an error', err); return; } console.log(data); } fs.readFile('/some/file/that/does-not-exist', nodeStyleCallback); fs.readFile('/some/file/that/does-exist', nodeStyleCallback) The JavaScript `try / catch` mechanism **cannot** be used to intercept errors generated by asynchronous APIs. A common mistake for beginners is to try to use `throw` inside a Node.js style callback: // THIS WILL NOT WORK: const fs = require('fs'); try { fs.readFile('/some/file/that/does-not-exist', (err, data) => { // mistaken assumption: throwing here... if (err) { throw err; } }); } catch(err) { // This will not catch the throw! console.log(err); } This will not work because the callback function passed to `fs.readFile()` is called asynchronously. By the time the callback has been called, the surrounding code (including the `try { } catch(err) { }` block will have already exited. Throwing an error inside the callback **can crash the Node.js process** in most cases. If [domains][] are enabled, or a handler has been registered with `process.on('uncaughtException')`, such errors can be intercepted. ## Class: Error A generic JavaScript `Error` object that does not denote any specific circumstance of why the error occurred. `Error` objects capture a "stack trace" detailing the point in the code at which the `Error` was instantiated, and may provide a text description of the error. All errors generated by Node.js, including all System and JavaScript errors, will either be instances of, or inherit from, the `Error` class. ### new Error(message) Creates a new `Error` object and sets the `error.message` property to the provided text message. If an object is passed as `message`, the text message is generated by calling `message.toString()`. The `error.stack` property will represent the point in the code at which `new Error()` was called. Stack traces are dependent on [V8's stack trace API][]. Stack traces extend only to either (a) the beginning of *synchronous code execution*, or (b) the number of frames given by the property `Error.stackTraceLimit`, whichever is smaller. ### Error.captureStackTrace(targetObject[, constructorOpt]) Creates a `.stack` property on `targetObject`, which when accessed returns a string representing the location in the code at which `Error.captureStackTrace()` was called. const myObject = {}; Error.captureStackTrace(myObject); myObject.stack // similar to `new Error().stack` The first line of the trace, instead of being prefixed with `ErrorType: message`, will be the result of calling `targetObject.toString()`. The optional `constructorOpt` argument accepts a function. If given, all frames above `constructorOpt`, including `constructorOpt`, will be omitted from the generated stack trace. The `constructorOpt` argument is useful for hiding implementation details of error generation from an end user. For instance: function MyError() { Error.captureStackTrace(this, MyError); } // Without passing MyError to captureStackTrace, the MyError // frame would should up in the .stack property. by passing // the constructor, we omit that frame and all frames above it. new MyError().stack ### Error.stackTraceLimit The `Error.stackTraceLimit` property specifies the number of stack frames collected by a stack trace (whether generated by `new Error().stack` or `Error.captureStackTrace(obj)`). The default value is `10` but may be set to any valid JavaScript number. Changes will affect any stack trace captured *after* the value has been changed. If set to a non-number value, or set to a negative number, stack traces will not capture any frames. #### error.message Returns the string description of error as set by calling `new Error(message)`. The `message` passed to the constructor will also appear in the first line of the stack trace of the `Error`, however changing this property after the `Error` object is created *may not* change the first line of the stack trace. const err = new Error('The message'); console.log(err.message); // Prints: The message #### error.stack Returns a string describing the point in the code at which the `Error` was instantiated. For example: Error: Things keep happening! at /home/gbusey/file.js:525:2 at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21) at Actor. (/home/gbusey/actors.js:400:8) at increaseSynergy (/home/gbusey/actors.js:701:6) The first line is formatted as `: `, and is followed by a series of stack frames (each line beginning with "at "). Each frame describes a call site within the code that lead to the error being generated. V8 attempts to display a name for each function (by variable name, function name, or object method name), but occasionally it will not be able to find a suitable name. If V8 cannot determine a name for the function, only location information will be displayed for that frame. Otherwise, the determined function name will be displayed with location information appended in parentheses. It is important to note that frames are **only** generated for JavaScript functions. If, for example, execution synchronously passes through a C++ addon function called `cheetahify`, which itself calls a JavaScript function, the frame representing the `cheetahify` call will **not** be present in the stack traces: const cheetahify = require('./native-binding.node'); function makeFaster() { // cheetahify *synchronously* calls speedy. cheetahify(function speedy() { throw new Error('oh no!'); }); } makeFaster(); // will throw: // /home/gbusey/file.js:6 // throw new Error('oh no!'); // ^ // Error: oh no! // at speedy (/home/gbusey/file.js:6:11) // at makeFaster (/home/gbusey/file.js:5:3) // at Object. (/home/gbusey/file.js:10:1) // at Module._compile (module.js:456:26) // at Object.Module._extensions..js (module.js:474:10) // at Module.load (module.js:356:32) // at Function.Module._load (module.js:312:12) // at Function.Module.runMain (module.js:497:10) // at startup (node.js:119:16) // at node.js:906:3 The location information will be one of: * `native`, if the frame represents a call internal to V8 (as in `[].forEach`). * `plain-filename.js:line:column`, if the frame represents a call internal to Node.js. * `/absolute/path/to/file.js:line:column`, if the frame represents a call in a user program, or its dependencies. The string representing the stack trace is lazily generated when the `error.stack` property is **accessed**. The number of frames captured by the stack trace is bounded by the smaller of `Error.stackTraceLimit` or the number of available frames on the current event loop tick. System-level errors are generated as augmented `Error` instances, which are detailed [below](#errors_system_errors). ## Class: RangeError A subclass of `Error` that indicates that a provided argument was not within the set or range of acceptable values for a function; whether that is a numeric range, or outside the set of options for a given function parameter. For example: require('net').connect(-1); // throws RangeError, port should be > 0 && < 65536 Node.js will generate and throw `RangeError` instances *immediately* as a form of argument validation. ## Class: ReferenceError A subclass of `Error` that indicates that an attempt is being made to access a variable that is not defined. Such errors commonly indicate typos in code, or an otherwise broken program. While client code may generate and propagate these errors, in practice, only V8 will do so. doesNotExist; // throws ReferenceError, doesNotExist is not a variable in this program. `ReferenceError` instances will have an `error.arguments` property whose value is an array containing a single element: a string representing the variable that was not defined. const assert = require('assert'); try { doesNotExist; } catch(err) { assert(err.arguments[0], 'doesNotExist'); } Unless an application is dynamically generating and running code, `ReferenceError` instances should always be considered a bug in the code or its dependencies. ## Class: SyntaxError A subclass of `Error` that indicates that a program is not valid JavaScript. These errors may only be generated and propagated as a result of code evaluation. Code evaluation may happen as a result of `eval`, `Function`, `require`, or [vm][]. These errors are almost always indicative of a broken program. try { require('vm').runInThisContext('binary ! isNotOk'); } catch(err) { // err will be a SyntaxError } `SyntaxError` instances are unrecoverable in the context that created them – they may only be caught by other contexts. ## Class: TypeError A subclass of `Error` that indicates that a provided argument is not an allowable type. For example, passing a function to a parameter which expects a string would be considered a TypeError. require('url').parse(function() { }); // throws TypeError, since it expected a string Node.js will generate and throw `TypeError` instances *immediately* as a form of argument validation. ## Exceptions vs. Errors A JavaScript exception is a value that is thrown as a result of an invalid operation or as the target of a `throw` statement. While it is not required that these values are instances of `Error` or classes which inherit from `Error`, all exceptions thrown by Node.js or the JavaScript runtime *will* be instances of Error. Some exceptions are *unrecoverable* at the JavaScript layer. Such exceptions will *always* cause the Node.js process to crash. Examples include `assert()` checks or `abort()` calls in the C++ layer. ## System Errors System errors are generated when exceptions occur within the program's runtime environment. Typically, these are operational errors that occur when an application violates an operating system constraint such as attempting to read a file that does not exist or when the user does not have sufficient permissions. System errors are typically generated at the syscall level: an exhaustive list of error codes and their meanings is available by running `man 2 intro` or `man 3 errno` on most Unices; or [online][]. In Node.js, system errors are represented as augmented `Error` objects with added properties. ### Class: System Error #### error.code #### error.errno Returns a string representing the error code, which is always `E` followed by a sequence of capital letters, and may be referenced in `man 2 intro`. The properties `error.code` and `error.errno` are aliases of one another and return the same value. #### error.syscall Returns a string describing the [syscall][] that failed. ### Common System Errors This list is **not exhaustive**, but enumerates many of the common system errors encountered when writing a Node.js program. An exhaustive list may be found [here][online]. - `EACCES` (Permission denied): An attempt was made to access a file in a way forbidden by its file access permissions. - `EADDRINUSE` (Address already in use): An attempt to bind a server ([`net`][], [`http`][], or [`https`][]) to a local address failed due to another server on the local system already occupying that address. - `ECONNREFUSED` (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host. - `ECONNRESET` (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the [`http`][] and [`net`][] modules. - `EEXIST` (File exists): An existing file was the target of an operation that required that the target not exist. - `EISDIR` (Is a directory): An operation expected a file, but the given pathname was a directory. - `EMFILE` (Too many open files in system): Maximum number of [file descriptors][] allowable on the system has been reached, and requests for another descriptor cannot be fulfilled until at least one has been closed. This is encountered when opening many files at once in parallel, especially on systems (in particular, OS X) where there is a low file descriptor limit for processes. To remedy a low limit, run `ulimit -n 2048` in the same shell that will run the Node.js process. - `ENOENT` (No such file or directory): Commonly raised by [`fs`][] operations to indicate that a component of the specified pathname does not exist -- no entity (file or directory) could be found by the given path. - `ENOTDIR` (Not a directory): A component of the given pathname existed, but was not a directory as expected. Commonly raised by [`fs.readdir`][]. - `ENOTEMPTY` (Directory not empty): A directory with entries was the target of an operation that requires an empty directory -- usually [`fs.unlink`][]. - `EPERM` (Operation not permitted): An attempt was made to perform an operation that requires elevated privileges. - `EPIPE` (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the data. Commonly encountered at the [`net`][] and [`http`][] layers, indicative that the remote side of the stream being written to has been closed. - `ETIMEDOUT` (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by [`http`][] or [`net`][] -- often a sign that a `socket.end()` was not properly called. [`Error`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error [`fs.readdir`]: fs.html#fs_fs_readdir_path_callback [`fs.readFileSync`]: fs.html#fs_fs_readfilesync_file_options [`fs.unlink`]: fs.html#fs_fs_unlink_path_callback [`fs`]: fs.html [`http`]: http.html [`https`]: https.html [`net`]: net.html [`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception [`try / catch` construct]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch [`try { } catch(err) { }`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch [below]: #errors_error_propagation_and_interception [domains]: domain.html [event emitter-based]: events.html#events_class_events_eventemitter [file descriptors]: https://en.wikipedia.org/wiki/File_descriptor [online]: http://man7.org/linux/man-pages/man3/errno.3.html [stream-based]: stream.html [syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html [V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API [vm]: vm.html [`SyntaxError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError [`ReferenceError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError [`TypeError`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError [`domain`]: domain.html node-v4.2.6/doc/api/events.html000644 000766 000024 00000055737 12650222331 016473 0ustar00iojsstaff000000 000000 Events Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Events#

Stability: 2 - Stable

Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") periodically emit named events that cause Function objects ("listeners") to be called.

For instance: a net.Server object emits an event each time a peer connects to it; a fs.ReadStream emits an event when the file is opened; a stream emits an event whenever data is available to be read.

All objects that emit events are instances of the EventEmitter class. These objects expose an eventEmitter.on() function that allows one or more Functions to be attached to named events emitted by the object. Typically, event names are camel-cased strings but any valid JavaScript property key can be used.

When the EventEmitter object emits an event, all of the Functions attached to that specific event are called synchronously. Any values returned by the called listeners are ignored and will be discarded.

The following example shows a simple EventEmitter instance with a single listener. The eventEmitter.on() method is used to register listeners, while the eventEmitter.emit() method is used to trigger the event.

const EventEmitter = require('events');
const util = require('util');

function MyEmitter() {
  EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter);

const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
  console.log('an event occurred!');
});
myEmitter.emit('event');

Any object can become an EventEmitter through inheritance. The example above uses the traditional Node.js style prototypical inheritance using the util.inherits() method. It is, however, possible to use ES6 classes as well:

const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', function() {
  console.log('an event occurred!');
});
myEmitter.emit('event');

Passing arguments and this to listeners#

The eventEmitter.emit() method allows an arbitrary set of arguments to be passed to the listener functions. It is important to keep in mind that when an ordinary listener function is called by the EventEmitter, the standard this keyword is intentionally set to reference the EventEmitter to which the listener is attached.

const myEmitter = new MyEmitter();
myEmitter.on('event', function(a, b) {
  console.log(a, b, this);
    // Prints:
    //   a b MyEmitter {
    //     domain: null,
    //     _events: { event: [Function] },
    //     _eventsCount: 1,
    //     _maxListeners: undefined }
});
myEmitter.emit('event', 'a', 'b');

It is possible to use ES6 Arrow Functions as listeners, however, when doing so, the this keyword will no longer reference the EventEmitter instance:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  console.log(a, b, this);
    // Prints: a b {}
});
myEmitter.emit('event', 'a', 'b');

Asynchronous vs. Synchronous#

The EventListener calls all listeners synchronously in the order in which they were registered. This is important to ensure the proper sequencing of events and to avoid race conditions or logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the setImmediate() or process.nextTick() methods:

const myEmitter = new MyEmitter();
myEmitter.on('event', (a, b) => {
  setImmediate(() => {
    console.log('this happens asynchronously');
  });
});
myEmitter.emit('event', 'a', 'b');

Handling events only once#

When a listener is registered using the eventEmitter.on() method, that listener will be invoked every time the named event is emitted.

const myEmitter = new MyEmitter();
var m = 0;
myEmitter.on('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
  // Prints: 1
myEmitter.emit('event');
  // Prints: 2

Using the eventEmitter.once() method, it is possible to register a listener that is immediately unregistered after it is called.

const myEmitter = new MyEmitter();
var m = 0;
myEmitter.once('event', () => {
  console.log(++m);
});
myEmitter.emit('event');
  // Prints: 1
myEmitter.emit('event');
  // Ignored

Error events#

When an error occurs within an EventEmitter instance, the typical action is for an 'error' event to be emitted. These are treated as a special case within Node.js.

If an EventEmitter does not have at least one listener registered for the 'error' event, and an 'error' event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits.

const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
  // Throws and crashes Node.js

To guard against crashing the Node.js process, developers can either register a listener for the process.on('uncaughtException') event or use the domain module (Note, however, that the domain module has been deprecated).

const myEmitter = new MyEmitter();

process.on('uncaughtException', (err) => {
  console.log('whoops! there was an error');
});

myEmitter.emit('error', new Error('whoops!'));
  // Prints: whoops! there was an error

As a best practice, developers should always register listeners for the 'error' event:

const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
  console.log('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
  // Prints: whoops! there was an error

Class: EventEmitter#

The EventEmitter class is defined and exposed by the events module:

const EventEmitter = require('events');

All EventEmitters emit the event 'newListener' when new listeners are added and 'removeListener' when a listener is removed.

Event: 'newListener'#

  • event String|Symbol The event name
  • listener Function The event handler function

The EventEmitter instance will emit it's own 'newListener' event before a listener is added to it's internal array of listeners.

Listeners registered for the 'newListener' event will be passed the event name and a reference to the listener being added.

The fact that the event is triggered before adding the listener has a subtle but important side effect: any additional listeners registered to the same name within the 'newListener' callback will be inserted before the listener that is in the process of being added.

const myEmitter = new MyEmitter();
// Only do this once so we don't loop forever
myEmitter.once('newListener', (event, listener) => {
  if (event === 'event') {
    // Insert a new listener in front
    myEmitter.on('event', () => {
      console.log('B');
    });
  }
});
myEmitter.on('event', () => {
  console.log('A');
});
myEmitter.emit('event');
  // Prints:
  //   B
  //   A

Event: 'removeListener'#

  • event String|Symbol The event name
  • listener Function The event handler function

The 'removeListener' event is emitted after a listener is removed.

EventEmitter.listenerCount(emitter, event)#

Stability: 0 - Deprecated: Use emitter.listenerCount() instead.

A class method that returns the number of listeners for the given event registered on the given emitter.

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {});
myEmitter.on('event', () => {});
console.log(EventEmitter.listenerCount(myEmitter, 'event'));
  // Prints: 2

EventEmitter.defaultMaxListeners#

By default, a maximum of 10 listeners can be registered for any single event. This limit can be changed for individual EventEmitter instances using the emitter.setMaxListeners(n) method. To change the default for all EventEmitter instances, the EventEmitter.defaultMaxListeners property can be used.

Take caution when setting the EventEmitter.defaultMaxListeners because the change effects all EventEmitter instances, including those created before the change is made. However, calling emitter.setMaxListeners(n) still has precedence over EventEmitter.defaultMaxListeners.

Note that this is not a hard limit. The EventEmitter instance will allow more listeners to be added but will output a trace warning to stderr indicating that a possible EventEmitter memory leak has been detected. For any single EventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners() methods can be used to temporarily avoid this warning:

emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once('event', () => {
  // do stuff
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});

emitter.addListener(event, listener)#

Alias for emitter.on(event, listener).

emitter.emit(event[, arg1][, arg2][, ...])#

Synchronously calls each of the listeners registered for event, in the order they were registered, passing the supplied arguments to each.

Returns true if event had listeners, false otherwise.

emitter.getMaxListeners()#

Returns the current max listener value for the EventEmitter which is either set by emitter.setMaxListeners(n) or defaults to EventEmitter.defaultMaxListeners.

emitter.listenerCount(event)#

  • event Value The type of event

Returns the number of listeners listening to the event type.

emitter.listeners(event)#

Returns a copy of the array of listeners for the specified event.

server.on('connection', (stream) => {
  console.log('someone connected!');
});
console.log(util.inspect(server.listeners('connection')));
  // Prints: [ [Function] ]

emitter.on(event, listener)#

Adds the listener function to the end of the listeners array for the specified event. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of event and listener will result in the listener being added, and called, multiple times.

server.on('connection', (stream) => {
  console.log('someone connected!');
});

Returns a reference to the EventEmitter so calls can be chained.

emitter.once(event, listener)#

Adds a one time listener function for the event. This listener is invoked only the next time event is triggered, after which it is removed.

server.once('connection', (stream) => {
  console.log('Ah, we have our first user!');
});

Returns a reference to the EventEmitter so calls can be chained.

emitter.removeAllListeners([event])#

Removes all listeners, or those of the specified event.

Note that it is bad practice to remove listeners added elsewhere in the code, particularly when the EventEmitter instance was created by some other component or module (e.g. sockets or file streams).

Returns a reference to the EventEmitter so calls can be chained.

emitter.removeListener(event, listener)#

Removes the specified listener from the listener array for the specified event.

var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);

removeListener will remove, at most, one instance of a listener from the listener array. If any single listener has been added multiple times to the listener array for the specified event, then removeListener must be called multiple times to remove each instance.

Because listeners are managed using an internal array, calling this will change the position indices of any listener registered after the listener being removed. This will not impact the order in which listeners are called, but it will means that any copies of the listener array as returned by the emitter.listeners() method will need to be recreated.

Returns a reference to the EventEmitter so calls can be chained.

emitter.setMaxListeners(n)#

By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The emitter.setMaxListeners() method allows the limit to be modified for this specific EventEmitter instance. The value can be set to Infinity (or 0) for to indicate an unlimited number of listeners.

Returns a reference to the EventEmitter so calls can be chained.

node-v4.2.6/doc/api/events.json000644 000766 000024 00000052253 12650222331 016466 0ustar00iojsstaff000000 000000 { "source": "doc/api/events.markdown", "modules": [ { "textRaw": "Events", "name": "Events", "stability": 2, "stabilityText": "Stable", "type": "module", "desc": "

Much of the Node.js core API is built around an idiomatic asynchronous\nevent-driven architecture in which certain kinds of objects (called "emitters")\nperiodically emit named events that cause Function objects ("listeners") to be\ncalled.\n\n

\n

For instance: a [net.Server][] object emits an event each time a peer\nconnects to it; a [fs.ReadStream][] emits an event when the file is opened;\na [stream][] emits an event whenever data is available to be read.\n\n

\n

All objects that emit events are instances of the EventEmitter class. These\nobjects expose an eventEmitter.on() function that allows one or more\nFunctions to be attached to named events emitted by the object. Typically,\nevent names are camel-cased strings but any valid JavaScript property key\ncan be used.\n\n

\n

When the EventEmitter object emits an event, all of the Functions attached\nto that specific event are called synchronously. Any values returned by the\ncalled listeners are ignored and will be discarded.\n\n

\n

The following example shows a simple EventEmitter instance with a single\nlistener. The eventEmitter.on() method is used to register listeners, while\nthe eventEmitter.emit() method is used to trigger the event.\n\n

\n
const EventEmitter = require('events');\nconst util = require('util');\n\nfunction MyEmitter() {\n  EventEmitter.call(this);\n}\nutil.inherits(MyEmitter, EventEmitter);\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', function() {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');
\n

Any object can become an EventEmitter through inheritance. The example above\nuses the traditional Node.js style prototypical inheritance using\nthe util.inherits() method. It is, however, possible to use ES6 classes as\nwell:\n\n

\n
const EventEmitter = require('events');\n\nclass MyEmitter extends EventEmitter {}\n\nconst myEmitter = new MyEmitter();\nmyEmitter.on('event', function() {\n  console.log('an event occurred!');\n});\nmyEmitter.emit('event');
\n", "modules": [ { "textRaw": "Passing arguments and `this` to listeners", "name": "passing_arguments_and_`this`_to_listeners", "desc": "

The eventEmitter.emit() method allows an arbitrary set of arguments to be\npassed to the listener functions. It is important to keep in mind that when an\nordinary listener function is called by the EventEmitter, the standard this\nkeyword is intentionally set to reference the EventEmitter to which the\nlistener is attached.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', function(a, b) {\n  console.log(a, b, this);\n    // Prints:\n    //   a b MyEmitter {\n    //     domain: null,\n    //     _events: { event: [Function] },\n    //     _eventsCount: 1,\n    //     _maxListeners: undefined }\n});\nmyEmitter.emit('event', 'a', 'b');
\n

It is possible to use ES6 Arrow Functions as listeners, however, when doing so,\nthe this keyword will no longer reference the EventEmitter instance:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', (a, b) => {\n  console.log(a, b, this);\n    // Prints: a b {}\n});\nmyEmitter.emit('event', 'a', 'b');
\n", "type": "module", "displayName": "Passing arguments and `this` to listeners" }, { "textRaw": "Asynchronous vs. Synchronous", "name": "asynchronous_vs._synchronous", "desc": "

The EventListener calls all listeners synchronously in the order in which\nthey were registered. This is important to ensure the proper sequencing of\nevents and to avoid race conditions or logic errors. When appropriate,\nlistener functions can switch to an asynchronous mode of operation using\nthe setImmediate() or process.nextTick() methods:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', (a, b) => {\n  setImmediate(() => {\n    console.log('this happens asynchronously');\n  });\n});\nmyEmitter.emit('event', 'a', 'b');
\n", "type": "module", "displayName": "Asynchronous vs. Synchronous" }, { "textRaw": "Handling events only once", "name": "handling_events_only_once", "desc": "

When a listener is registered using the eventEmitter.on() method, that\nlistener will be invoked every time the named event is emitted.\n\n

\n
const myEmitter = new MyEmitter();\nvar m = 0;\nmyEmitter.on('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n  // Prints: 1\nmyEmitter.emit('event');\n  // Prints: 2
\n

Using the eventEmitter.once() method, it is possible to register a listener\nthat is immediately unregistered after it is called.\n\n

\n
const myEmitter = new MyEmitter();\nvar m = 0;\nmyEmitter.once('event', () => {\n  console.log(++m);\n});\nmyEmitter.emit('event');\n  // Prints: 1\nmyEmitter.emit('event');\n  // Ignored
\n", "type": "module", "displayName": "Handling events only once" }, { "textRaw": "Error events", "name": "error_events", "desc": "

When an error occurs within an EventEmitter instance, the typical action is\nfor an 'error' event to be emitted. These are treated as a special case\nwithin Node.js.\n\n

\n

If an EventEmitter does not have at least one listener registered for the\n'error' event, and an 'error' event is emitted, the error is thrown, a\nstack trace is printed, and the Node.js process exits.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.emit('error', new Error('whoops!'));\n  // Throws and crashes Node.js
\n

To guard against crashing the Node.js process, developers can either register\na listener for the process.on('uncaughtException') event or use the\n[domain][] module (Note, however, that the domain module has been\ndeprecated).\n\n

\n
const myEmitter = new MyEmitter();\n\nprocess.on('uncaughtException', (err) => {\n  console.log('whoops! there was an error');\n});\n\nmyEmitter.emit('error', new Error('whoops!'));\n  // Prints: whoops! there was an error
\n

As a best practice, developers should always register listeners for the\n'error' event:\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('error', (err) => {\n  console.log('whoops! there was an error');\n});\nmyEmitter.emit('error', new Error('whoops!'));\n  // Prints: whoops! there was an error
\n", "type": "module", "displayName": "Error events" } ], "classes": [ { "textRaw": "Class: EventEmitter", "type": "class", "name": "EventEmitter", "desc": "

The EventEmitter class is defined and exposed by the events module:\n\n

\n
const EventEmitter = require('events');
\n

All EventEmitters emit the event 'newListener' when new listeners are\nadded and 'removeListener' when a listener is removed.\n\n

\n", "events": [ { "textRaw": "Event: 'newListener'", "type": "event", "name": "newListener", "params": [], "desc": "

The EventEmitter instance will emit it's own 'newListener' event before\na listener is added to it's internal array of listeners.\n\n

\n

Listeners registered for the 'newListener' event will be passed the event\nname and a reference to the listener being added.\n\n

\n

The fact that the event is triggered before adding the listener has a subtle\nbut important side effect: any additional listeners registered to the same\nname within the 'newListener' callback will be inserted before the\nlistener that is in the process of being added.\n\n

\n
const myEmitter = new MyEmitter();\n// Only do this once so we don't loop forever\nmyEmitter.once('newListener', (event, listener) => {\n  if (event === 'event') {\n    // Insert a new listener in front\n    myEmitter.on('event', () => {\n      console.log('B');\n    });\n  }\n});\nmyEmitter.on('event', () => {\n  console.log('A');\n});\nmyEmitter.emit('event');\n  // Prints:\n  //   B\n  //   A
\n" }, { "textRaw": "Event: 'removeListener'", "type": "event", "name": "removeListener", "params": [], "desc": "

The 'removeListener' event is emitted after a listener is removed.\n\n

\n" } ], "methods": [ { "textRaw": "EventEmitter.listenerCount(emitter, event)", "type": "method", "name": "listenerCount", "stability": 0, "stabilityText": "Deprecated: Use [`emitter.listenerCount()`][] instead.", "desc": "

A class method that returns the number of listeners for the given event\nregistered on the given emitter.\n\n

\n
const myEmitter = new MyEmitter();\nmyEmitter.on('event', () => {});\nmyEmitter.on('event', () => {});\nconsole.log(EventEmitter.listenerCount(myEmitter, 'event'));\n  // Prints: 2
\n", "signatures": [ { "params": [ { "name": "emitter" }, { "name": "event" } ] } ] }, { "textRaw": "emitter.addListener(event, listener)", "type": "method", "name": "addListener", "desc": "

Alias for emitter.on(event, listener).\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.emit(event[, arg1][, arg2][, ...])", "type": "method", "name": "emit", "desc": "

Synchronously calls each of the listeners registered for event, in the order\nthey were registered, passing the supplied arguments to each.\n\n

\n

Returns true if event had listeners, false otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "arg1", "optional": true }, { "name": "arg2", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "emitter.getMaxListeners()", "type": "method", "name": "getMaxListeners", "desc": "

Returns the current max listener value for the EventEmitter which is either\nset by [emitter.setMaxListeners(n)][] or defaults to\n[EventEmitter.defaultMaxListeners][].\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "emitter.listenerCount(event)", "type": "method", "name": "listenerCount", "signatures": [ { "params": [ { "textRaw": "`event` {Value} The type of event ", "name": "event", "type": "Value", "desc": "The type of event" } ] }, { "params": [ { "name": "event" } ] } ], "desc": "

Returns the number of listeners listening to the event type.\n\n

\n" }, { "textRaw": "emitter.listeners(event)", "type": "method", "name": "listeners", "desc": "

Returns a copy of the array of listeners for the specified event.\n\n

\n
server.on('connection', (stream) => {\n  console.log('someone connected!');\n});\nconsole.log(util.inspect(server.listeners('connection')));\n  // Prints: [ [Function] ]
\n", "signatures": [ { "params": [ { "name": "event" } ] } ] }, { "textRaw": "emitter.on(event, listener)", "type": "method", "name": "on", "desc": "

Adds the listener function to the end of the listeners array for the\nspecified event. No checks are made to see if the listener has already\nbeen added. Multiple calls passing the same combination of event and\nlistener will result in the listener being added, and called, multiple\ntimes.\n\n

\n
server.on('connection', (stream) => {\n  console.log('someone connected!');\n});
\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.once(event, listener)", "type": "method", "name": "once", "desc": "

Adds a one time listener function for the event. This listener is\ninvoked only the next time event is triggered, after which it is removed.\n\n

\n
server.once('connection', (stream) => {\n  console.log('Ah, we have our first user!');\n});
\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.removeAllListeners([event])", "type": "method", "name": "removeAllListeners", "desc": "

Removes all listeners, or those of the specified event.\n\n

\n

Note that it is bad practice to remove listeners added elsewhere in the code,\nparticularly when the EventEmitter instance was created by some other\ncomponent or module (e.g. sockets or file streams).\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event", "optional": true } ] } ] }, { "textRaw": "emitter.removeListener(event, listener)", "type": "method", "name": "removeListener", "desc": "

Removes the specified listener from the listener array for the specified\nevent.\n\n

\n
var callback = function(stream) {\n  console.log('someone connected!');\n};\nserver.on('connection', callback);\n// ...\nserver.removeListener('connection', callback);
\n

removeListener will remove, at most, one instance of a listener from the\nlistener array. If any single listener has been added multiple times to the\nlistener array for the specified event, then removeListener must be called\nmultiple times to remove each instance.\n\n

\n

Because listeners are managed using an internal array, calling this will\nchange the position indices of any listener registered after the listener\nbeing removed. This will not impact the order in which listeners are called,\nbut it will means that any copies of the listener array as returned by\nthe emitter.listeners() method will need to be recreated.\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "event" }, { "name": "listener" } ] } ] }, { "textRaw": "emitter.setMaxListeners(n)", "type": "method", "name": "setMaxListeners", "desc": "

By default EventEmitters will print a warning if more than 10 listeners are\nadded for a particular event. This is a useful default that helps finding\nmemory leaks. Obviously, not all events should be limited to just 10 listeners.\nThe emitter.setMaxListeners() method allows the limit to be modified for this\nspecific EventEmitter instance. The value can be set to Infinity (or 0)\nfor to indicate an unlimited number of listeners.\n\n

\n

Returns a reference to the EventEmitter so calls can be chained.\n\n

\n", "signatures": [ { "params": [ { "name": "n" } ] } ] } ], "properties": [ { "textRaw": "EventEmitter.defaultMaxListeners", "name": "defaultMaxListeners", "desc": "

By default, a maximum of 10 listeners can be registered for any single\nevent. This limit can be changed for individual EventEmitter instances\nusing the [emitter.setMaxListeners(n)][] method. To change the default\nfor all EventEmitter instances, the EventEmitter.defaultMaxListeners\nproperty can be used.\n\n

\n

Take caution when setting the EventEmitter.defaultMaxListeners because the\nchange effects all EventEmitter instances, including those created before\nthe change is made. However, calling [emitter.setMaxListeners(n)][] still has\nprecedence over EventEmitter.defaultMaxListeners.\n\n

\n

Note that this is not a hard limit. The EventEmitter instance will allow\nmore listeners to be added but will output a trace warning to stderr indicating\nthat a possible EventEmitter memory leak has been detected. For any single\nEventEmitter, the emitter.getMaxListeners() and emitter.setMaxListeners()\nmethods can be used to temporarily avoid this warning:\n\n

\n
emitter.setMaxListeners(emitter.getMaxListeners() + 1);\nemitter.once('event', () => {\n  // do stuff\n  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));\n});
\n" } ] } ] } ] } node-v4.2.6/doc/api/events.markdown000644 000766 000024 00000031454 12650222326 017343 0ustar00iojsstaff000000 000000 # Events Stability: 2 - Stable Much of the Node.js core API is built around an idiomatic asynchronous event-driven architecture in which certain kinds of objects (called "emitters") periodically emit named events that cause Function objects ("listeners") to be called. For instance: a [`net.Server`][] object emits an event each time a peer connects to it; a [`fs.ReadStream`][] emits an event when the file is opened; a [stream][] emits an event whenever data is available to be read. All objects that emit events are instances of the `EventEmitter` class. These objects expose an `eventEmitter.on()` function that allows one or more Functions to be attached to named events emitted by the object. Typically, event names are camel-cased strings but any valid JavaScript property key can be used. When the `EventEmitter` object emits an event, all of the Functions attached to that specific event are called _synchronously_. Any values returned by the called listeners are _ignored_ and will be discarded. The following example shows a simple `EventEmitter` instance with a single listener. The `eventEmitter.on()` method is used to register listeners, while the `eventEmitter.emit()` method is used to trigger the event. const EventEmitter = require('events'); const util = require('util'); function MyEmitter() { EventEmitter.call(this); } util.inherits(MyEmitter, EventEmitter); const myEmitter = new MyEmitter(); myEmitter.on('event', function() { console.log('an event occurred!'); }); myEmitter.emit('event'); Any object can become an `EventEmitter` through inheritance. The example above uses the traditional Node.js style prototypical inheritance using the `util.inherits()` method. It is, however, possible to use ES6 classes as well: const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', function() { console.log('an event occurred!'); }); myEmitter.emit('event'); ## Passing arguments and `this` to listeners The `eventEmitter.emit()` method allows an arbitrary set of arguments to be passed to the listener functions. It is important to keep in mind that when an ordinary listener function is called by the `EventEmitter`, the standard `this` keyword is intentionally set to reference the `EventEmitter` to which the listener is attached. const myEmitter = new MyEmitter(); myEmitter.on('event', function(a, b) { console.log(a, b, this); // Prints: // a b MyEmitter { // domain: null, // _events: { event: [Function] }, // _eventsCount: 1, // _maxListeners: undefined } }); myEmitter.emit('event', 'a', 'b'); It is possible to use ES6 Arrow Functions as listeners, however, when doing so, the `this` keyword will no longer reference the `EventEmitter` instance: const myEmitter = new MyEmitter(); myEmitter.on('event', (a, b) => { console.log(a, b, this); // Prints: a b {} }); myEmitter.emit('event', 'a', 'b'); ## Asynchronous vs. Synchronous The `EventListener` calls all listeners synchronously in the order in which they were registered. This is important to ensure the proper sequencing of events and to avoid race conditions or logic errors. When appropriate, listener functions can switch to an asynchronous mode of operation using the `setImmediate()` or `process.nextTick()` methods: const myEmitter = new MyEmitter(); myEmitter.on('event', (a, b) => { setImmediate(() => { console.log('this happens asynchronously'); }); }); myEmitter.emit('event', 'a', 'b'); ## Handling events only once When a listener is registered using the `eventEmitter.on()` method, that listener will be invoked _every time_ the named event is emitted. const myEmitter = new MyEmitter(); var m = 0; myEmitter.on('event', () => { console.log(++m); }); myEmitter.emit('event'); // Prints: 1 myEmitter.emit('event'); // Prints: 2 Using the `eventEmitter.once()` method, it is possible to register a listener that is immediately unregistered after it is called. const myEmitter = new MyEmitter(); var m = 0; myEmitter.once('event', () => { console.log(++m); }); myEmitter.emit('event'); // Prints: 1 myEmitter.emit('event'); // Ignored ## Error events When an error occurs within an `EventEmitter` instance, the typical action is for an `'error'` event to be emitted. These are treated as a special case within Node.js. If an `EventEmitter` does _not_ have at least one listener registered for the `'error'` event, and an `'error'` event is emitted, the error is thrown, a stack trace is printed, and the Node.js process exits. const myEmitter = new MyEmitter(); myEmitter.emit('error', new Error('whoops!')); // Throws and crashes Node.js To guard against crashing the Node.js process, developers can either register a listener for the `process.on('uncaughtException')` event or use the [`domain`][] module (_Note, however, that the `domain` module has been deprecated_). const myEmitter = new MyEmitter(); process.on('uncaughtException', (err) => { console.log('whoops! there was an error'); }); myEmitter.emit('error', new Error('whoops!')); // Prints: whoops! there was an error As a best practice, developers should always register listeners for the `'error'` event: const myEmitter = new MyEmitter(); myEmitter.on('error', (err) => { console.log('whoops! there was an error'); }); myEmitter.emit('error', new Error('whoops!')); // Prints: whoops! there was an error ## Class: EventEmitter The `EventEmitter` class is defined and exposed by the `events` module: const EventEmitter = require('events'); All EventEmitters emit the event `'newListener'` when new listeners are added and `'removeListener'` when a listener is removed. ### Event: 'newListener' * `event` {String|Symbol} The event name * `listener` {Function} The event handler function The `EventEmitter` instance will emit it's own `'newListener'` event *before* a listener is added to it's internal array of listeners. Listeners registered for the `'newListener'` event will be passed the event name and a reference to the listener being added. The fact that the event is triggered before adding the listener has a subtle but important side effect: any *additional* listeners registered to the same `name` *within* the `'newListener'` callback will be inserted *before* the listener that is in the process of being added. const myEmitter = new MyEmitter(); // Only do this once so we don't loop forever myEmitter.once('newListener', (event, listener) => { if (event === 'event') { // Insert a new listener in front myEmitter.on('event', () => { console.log('B'); }); } }); myEmitter.on('event', () => { console.log('A'); }); myEmitter.emit('event'); // Prints: // B // A ### Event: 'removeListener' * `event` {String|Symbol} The event name * `listener` {Function} The event handler function The `'removeListener'` event is emitted *after* a listener is removed. ### EventEmitter.listenerCount(emitter, event) Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. A class method that returns the number of listeners for the given `event` registered on the given `emitter`. const myEmitter = new MyEmitter(); myEmitter.on('event', () => {}); myEmitter.on('event', () => {}); console.log(EventEmitter.listenerCount(myEmitter, 'event')); // Prints: 2 ### EventEmitter.defaultMaxListeners By default, a maximum of `10` listeners can be registered for any single event. This limit can be changed for individual `EventEmitter` instances using the [`emitter.setMaxListeners(n)`][] method. To change the default for *all* `EventEmitter` instances, the `EventEmitter.defaultMaxListeners` property can be used. Take caution when setting the `EventEmitter.defaultMaxListeners` because the change effects *all* `EventEmitter` instances, including those created before the change is made. However, calling [`emitter.setMaxListeners(n)`][] still has precedence over `EventEmitter.defaultMaxListeners`. Note that this is not a hard limit. The `EventEmitter` instance will allow more listeners to be added but will output a trace warning to stderr indicating that a `possible EventEmitter memory leak` has been detected. For any single `EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` methods can be used to temporarily avoid this warning: emitter.setMaxListeners(emitter.getMaxListeners() + 1); emitter.once('event', () => { // do stuff emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); }); ### emitter.addListener(event, listener) Alias for `emitter.on(event, listener)`. ### emitter.emit(event[, arg1][, arg2][, ...]) Synchronously calls each of the listeners registered for `event`, in the order they were registered, passing the supplied arguments to each. Returns `true` if event had listeners, `false` otherwise. ### emitter.getMaxListeners() Returns the current max listener value for the `EventEmitter` which is either set by [`emitter.setMaxListeners(n)`][] or defaults to [`EventEmitter.defaultMaxListeners`][]. ### emitter.listenerCount(event) * `event` {Value} The type of event Returns the number of listeners listening to the `event` type. ### emitter.listeners(event) Returns a copy of the array of listeners for the specified `event`. server.on('connection', (stream) => { console.log('someone connected!'); }); console.log(util.inspect(server.listeners('connection'))); // Prints: [ [Function] ] ### emitter.on(event, listener) Adds the `listener` function to the end of the listeners array for the specified `event`. No checks are made to see if the `listener` has already been added. Multiple calls passing the same combination of `event` and `listener` will result in the `listener` being added, and called, multiple times. server.on('connection', (stream) => { console.log('someone connected!'); }); Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.once(event, listener) Adds a **one time** `listener` function for the `event`. This listener is invoked only the next time `event` is triggered, after which it is removed. server.once('connection', (stream) => { console.log('Ah, we have our first user!'); }); Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.removeAllListeners([event]) Removes all listeners, or those of the specified `event`. Note that it is bad practice to remove listeners added elsewhere in the code, particularly when the `EventEmitter` instance was created by some other component or module (e.g. sockets or file streams). Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.removeListener(event, listener) Removes the specified `listener` from the listener array for the specified `event`. var callback = function(stream) { console.log('someone connected!'); }; server.on('connection', callback); // ... server.removeListener('connection', callback); `removeListener` will remove, at most, one instance of a listener from the listener array. If any single listener has been added multiple times to the listener array for the specified `event`, then `removeListener` must be called multiple times to remove each instance. Because listeners are managed using an internal array, calling this will change the position indices of any listener registered *after* the listener being removed. This will not impact the order in which listeners are called, but it will means that any copies of the listener array as returned by the `emitter.listeners()` method will need to be recreated. Returns a reference to the `EventEmitter` so calls can be chained. ### emitter.setMaxListeners(n) By default EventEmitters will print a warning if more than `10` listeners are added for a particular event. This is a useful default that helps finding memory leaks. Obviously, not all events should be limited to just 10 listeners. The `emitter.setMaxListeners()` method allows the limit to be modified for this specific `EventEmitter` instance. The value can be set to `Infinity` (or `0`) for to indicate an unlimited number of listeners. Returns a reference to the `EventEmitter` so calls can be chained. [`net.Server`]: net.html#net_class_net_server [`fs.ReadStream`]: fs.html#fs_class_fs_readstream [`emitter.setMaxListeners(n)`]: #events_emitter_setmaxlisteners_n [`EventEmitter.defaultMaxListeners`]: #events_eventemitter_defaultmaxlisteners [`emitter.listenerCount()`]: #events_emitter_listenercount_event [`domain`]: domain.html [stream]: stream.html node-v4.2.6/doc/api/fs.html000644 000766 000024 00000170467 12650222331 015575 0ustar00iojsstaff000000 000000 File System Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

File System#

Stability: 2 - Stable

File I/O is provided by simple wrappers around standard POSIX functions. To use this module do require('fs'). All the methods have asynchronous and synchronous forms.

The asynchronous form always takes a completion callback as its last argument. The arguments passed to the completion callback depend on the method, but the first argument is always reserved for an exception. If the operation was completed successfully, then the first argument will be null or undefined.

When using the synchronous form any exceptions are immediately thrown. You can use try/catch to handle exceptions or allow them to bubble up.

Here is an example of the asynchronous version:

const fs = require('fs');

fs.unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

Here is the synchronous version:

const fs = require('fs');

fs.unlinkSync('/tmp/hello');
console.log('successfully deleted /tmp/hello');

With the asynchronous methods there is no guaranteed ordering. So the following is prone to error:

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  console.log('renamed complete');
});
fs.stat('/tmp/world', (err, stats) => {
  if (err) throw err;
  console.log(`stats: ${JSON.stringify(stats)}`);
});

It could be that fs.stat is executed before fs.rename. The correct way to do this is to chain the callbacks.

fs.rename('/tmp/hello', '/tmp/world', (err) => {
  if (err) throw err;
  fs.stat('/tmp/world', (err, stats) => {
    if (err) throw err;
    console.log(`stats: ${JSON.stringify(stats)}`);
  });
});

In busy processes, the programmer is strongly encouraged to use the asynchronous versions of these calls. The synchronous versions will block the entire process until they complete--halting all connections.

The relative path to a filename can be used. Remember, however, that this path will be relative to process.cwd().

Most fs functions let you omit the callback argument. If you do, a default callback is used that rethrows errors. To get a trace to the original call site, set the NODE_DEBUG environment variable:

$ cat script.js
function bad() {
  require('fs').readFile('/');
}
bad();

$ env NODE_DEBUG=fs node script.js
fs.js:66
        throw err;
              ^
Error: EISDIR, read
    at rethrow (fs.js:61:21)
    at maybeCallback (fs.js:79:42)
    at Object.fs.readFile (fs.js:153:18)
    at bad (/path/to/script.js:2:17)
    at Object.<anonymous> (/path/to/script.js:5:1)
    <etc.>

Class: fs.FSWatcher#

Objects returned from fs.watch() are of this type.

Event: 'change'#

  • event String The type of fs change
  • filename String The filename that changed (if relevant/available)

Emitted when something changes in a watched directory or file. See more details in fs.watch().

Event: 'error'#

  • error Error object

Emitted when an error occurs.

watcher.close()#

Stop watching for changes on the given fs.FSWatcher.

Class: fs.ReadStream#

ReadStream is a Readable Stream.

Event: 'open'#

  • fd Integer file descriptor used by the ReadStream.

Emitted when the ReadStream's file is opened.

Class: fs.Stats#

Objects returned from fs.stat(), fs.lstat() and fs.fstat() and their synchronous counterparts are of this type.

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (only valid with fs.lstat())
  • stats.isFIFO()
  • stats.isSocket()

For a regular file util.inspect(stats) would return a string very similar to this:

{ dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }

Please note that atime, mtime, birthtime, and ctime are instances of Date object and to compare the values of these objects you should use appropriate methods. For most general uses getTime() will return the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC and this integer should be sufficient for any comparison, however there are additional methods which can be used for displaying fuzzy information. More details can be found in the MDN JavaScript Reference page.

Stat Time Values#

The times in the stat object have the following semantics:

  • atime "Access Time" - Time when file data last accessed. Changed by the mknod(2), utimes(2), and read(2) system calls.
  • mtime "Modified Time" - Time when file data last modified. Changed by the mknod(2), utimes(2), and write(2) system calls.
  • ctime "Change Time" - Time when file status was last changed (inode data modification). Changed by the chmod(2), chown(2), link(2), mknod(2), rename(2), unlink(2), utimes(2), read(2), and write(2) system calls.
  • birthtime "Birth Time" - Time of file creation. Set once when the file is created. On filesystems where birthtime is not available, this field may instead hold either the ctime or 1970-01-01T00:00Z (ie, unix epoch timestamp 0). On Darwin and other FreeBSD variants, also set if the atime is explicitly set to an earlier value than the current birthtime using the utimes(2) system call.

Prior to Node v0.12, the ctime held the birthtime on Windows systems. Note that as of v0.12, ctime is not "creation time", and on Unix systems, it never was.

Class: fs.WriteStream#

WriteStream is a Writable Stream.

Event: 'open'#

  • fd Integer file descriptor used by the WriteStream.

Emitted when the WriteStream's file is opened.

writeStream.bytesWritten#

The number of bytes written so far. Does not include data that is still queued for writing.

fs.access(path[, mode], callback)#

Tests a user's permissions for the file specified by path. mode is an optional integer that specifies the accessibility checks to be performed. The following constants define the possible values of mode. It is possible to create a mask consisting of the bitwise OR of two or more values.

  • fs.F_OK - File is visible to the calling process. This is useful for determining if a file exists, but says nothing about rwx permissions. Default if no mode is specified.
  • fs.R_OK - File can be read by the calling process.
  • fs.W_OK - File can be written by the calling process.
  • fs.X_OK - File can be executed by the calling process. This has no effect on Windows (will behave like fs.F_OK).

The final argument, callback, is a callback function that is invoked with a possible error argument. If any of the accessibility checks fail, the error argument will be populated. The following example checks if the file /etc/passwd can be read and written by the current process.

fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) {
  console.log(err ? 'no access!' : 'can read/write');
});

fs.accessSync(path[, mode])#

Synchronous version of fs.access(). This throws if any accessibility checks fail, and does nothing otherwise.

fs.appendFile(file, data[, options], callback)#

  • file String | Integer filename or file descriptor
  • data String | Buffer
  • options Object | String
    • encoding String | Null default = 'utf8'
    • mode Number default = 0o666
    • flag String default = 'a'
  • callback Function

Asynchronously append data to a file, creating the file if it does not yet exist. data can be a string or a buffer.

Example:

fs.appendFile('message.txt', 'data to append', (err) => {
  if (err) throw err;
  console.log('The "data to append" was appended to file!');
});

If options is a string, then it specifies the encoding. Example:

fs.appendFile('message.txt', 'data to append', 'utf8', callback);

Any specified file descriptor has to have been opened for appending.

Note: Specified file descriptors will not be closed automatically.

fs.appendFileSync(file, data[, options])#

The synchronous version of fs.appendFile(). Returns undefined.

fs.chmod(path, mode, callback)#

Asynchronous chmod(2). No arguments other than a possible exception are given to the completion callback.

fs.chmodSync(path, mode)#

Synchronous chmod(2). Returns undefined.

fs.chown(path, uid, gid, callback)#

Asynchronous chown(2). No arguments other than a possible exception are given to the completion callback.

fs.chownSync(path, uid, gid)#

Synchronous chown(2). Returns undefined.

fs.close(fd, callback)#

Asynchronous close(2). No arguments other than a possible exception are given to the completion callback.

fs.closeSync(fd)#

Synchronous close(2). Returns undefined.

fs.createReadStream(path[, options])#

Returns a new ReadStream object. (See Readable Stream).

Be aware that, unlike the default value set for highWaterMark on a readable stream (16 kb), the stream returned by this method has a default value of 64 kb for the same parameter.

options is an object or string with the following defaults:

{ flags: 'r',
  encoding: null,
  fd: null,
  mode: 0o666,
  autoClose: true
}

options can include start and end values to read a range of bytes from the file instead of the entire file. Both start and end are inclusive and start at 0. The encoding can be any one of those accepted by Buffer.

If fd is specified, ReadStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. Note that fd should be blocking; non-blocking fds should be passed to net.Socket.

If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is your responsibility to close it and make sure there's no file descriptor leak. If autoClose is set to true (default behavior), on error or end the file descriptor will be closed automatically.

mode sets the file mode (permission and sticky bits), but only if the file was created.

An example to read the last 10 bytes of a file which is 100 bytes long:

fs.createReadStream('sample.txt', {start: 90, end: 99});

If options is a string, then it specifies the encoding.

fs.createWriteStream(path[, options])#

Returns a new WriteStream object. (See Writable Stream).

options is an object or string with the following defaults:

{ flags: 'w',
  defaultEncoding: 'utf8',
  fd: null,
  mode: 0o666 }

options may also include a start option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a flags mode of r+ rather than the default mode w. The defaultEncoding can be any one of those accepted by Buffer.

Like ReadStream, if fd is specified, WriteStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. Note that fd should be blocking; non-blocking fds should be passed to net.Socket.

If options is a string, then it specifies the encoding.

fs.exists(path, callback)#

Stability: 0 - Deprecated: Use fs.stat() or fs.access() instead.

Test whether or not the given path exists by checking with the file system. Then call the callback argument with either true or false. Example:

fs.exists('/etc/passwd', (exists) => {
  console.log(exists ? 'it\'s there' : 'no passwd!');
});

fs.exists() should not be used to check if a file exists before calling fs.open(). Doing so introduces a race condition since other processes may change the file's state between the two calls. Instead, user code should call fs.open() directly and handle the error raised if the file is non-existent.

fs.existsSync(path)#

Stability: 0 - Deprecated: Use fs.statSync() or fs.accessSync() instead.

Synchronous version of fs.exists(). Returns true if the file exists, false otherwise.

fs.fchmod(fd, mode, callback)#

Asynchronous fchmod(2). No arguments other than a possible exception are given to the completion callback.

fs.fchmodSync(fd, mode)#

Synchronous fchmod(2). Returns undefined.

fs.fchown(fd, uid, gid, callback)#

Asynchronous fchown(2). No arguments other than a possible exception are given to the completion callback.

fs.fchownSync(fd, uid, gid)#

Synchronous fchown(2). Returns undefined.

fs.fstat(fd, callback)#

Asynchronous fstat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. fstat() is identical to stat(), except that the file to be stat-ed is specified by the file descriptor fd.

fs.fstatSync(fd)#

Synchronous fstat(2). Returns an instance of fs.Stats.

fs.fsync(fd, callback)#

Asynchronous fsync(2). No arguments other than a possible exception are given to the completion callback.

fs.fsyncSync(fd)#

Synchronous fsync(2). Returns undefined.

fs.ftruncate(fd, len, callback)#

Asynchronous ftruncate(2). No arguments other than a possible exception are given to the completion callback.

fs.ftruncateSync(fd, len)#

Synchronous ftruncate(2). Returns undefined.

fs.futimes(fd, atime, mtime, callback)#

Change the file timestamps of a file referenced by the supplied file descriptor.

fs.futimesSync(fd, atime, mtime)#

Synchronous version of fs.futimes(). Returns undefined.

fs.lchmod(path, mode, callback)#

Asynchronous lchmod(2). No arguments other than a possible exception are given to the completion callback.

Only available on Mac OS X.

fs.lchmodSync(path, mode)#

Synchronous lchmod(2). Returns undefined.

fs.lchown(path, uid, gid, callback)#

Asynchronous lchown(2). No arguments other than a possible exception are given to the completion callback.

fs.lchownSync(path, uid, gid)#

Synchronous lchown(2). Returns undefined.

fs.link(srcpath, dstpath, callback)#

Asynchronous link(2). No arguments other than a possible exception are given to the completion callback.

fs.linkSync(srcpath, dstpath)#

Synchronous link(2). Returns undefined.

fs.lstat(path, callback)#

Asynchronous lstat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to.

fs.lstatSync(path)#

Synchronous lstat(2). Returns an instance of fs.Stats.

fs.mkdir(path[, mode], callback)#

Asynchronous mkdir(2). No arguments other than a possible exception are given to the completion callback. mode defaults to 0o777.

fs.mkdirSync(path[, mode])#

Synchronous mkdir(2). Returns undefined.

fs.open(path, flags[, mode], callback)#

Asynchronous file open. See open(2). flags can be:

  • 'r' - Open file for reading. An exception occurs if the file does not exist.

  • 'r+' - Open file for reading and writing. An exception occurs if the file does not exist.

  • 'rs' - Open file for reading in synchronous mode. Instructs the operating system to bypass the local file system cache.

    This is primarily useful for opening files on NFS mounts as it allows you to skip the potentially stale local cache. It has a very real impact on I/O performance so don't use this flag unless you need it.

    Note that this doesn't turn fs.open() into a synchronous blocking call. If that's what you want then you should be using fs.openSync()

  • 'rs+' - Open file for reading and writing, telling the OS to open it synchronously. See notes for 'rs' about using this with caution.

  • 'w' - Open file for writing. The file is created (if it does not exist) or truncated (if it exists).

  • 'wx' - Like 'w' but fails if path exists.

  • 'w+' - Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).

  • 'wx+' - Like 'w+' but fails if path exists.

  • 'a' - Open file for appending. The file is created if it does not exist.

  • 'ax' - Like 'a' but fails if path exists.

  • 'a+' - Open file for reading and appending. The file is created if it does not exist.

  • 'ax+' - Like 'a+' but fails if path exists.

mode sets the file mode (permission and sticky bits), but only if the file was created. It defaults to 0666, readable and writeable.

The callback gets two arguments (err, fd).

The exclusive flag 'x' (O_EXCL flag in open(2)) ensures that path is newly created. On POSIX systems, path is considered to exist even if it is a symlink to a non-existent file. The exclusive flag may or may not work with network file systems.

flags can also be a number as documented by open(2); commonly used constants are available from require('constants'). On Windows, flags are translated to their equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE, or O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.openSync(path, flags[, mode])#

Synchronous version of fs.open(). Returns an integer representing the file descriptor.

fs.read(fd, buffer, offset, length, position, callback)#

Read data from the file specified by fd.

buffer is the buffer that the data will be written to.

offset is the offset in the buffer to start writing at.

length is an integer specifying the number of bytes to read.

position is an integer specifying where to begin reading from in the file. If position is null, data will be read from the current file position.

The callback is given the three arguments, (err, bytesRead, buffer).

fs.readdir(path, callback)#

Asynchronous readdir(3). Reads the contents of a directory. The callback gets two arguments (err, files) where files is an array of the names of the files in the directory excluding '.' and '..'.

fs.readdirSync(path)#

Synchronous readdir(3). Returns an array of filenames excluding '.' and '..'.

fs.readFile(file[, options], callback)#

  • file String | Integer filename or file descriptor
  • options Object | String
    • encoding String | Null default = null
    • flag String default = 'r'
  • callback Function

Asynchronously reads the entire contents of a file. Example:

fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  console.log(data);
});

The callback is passed two arguments (err, data), where data is the contents of the file.

If no encoding is specified, then the raw buffer is returned.

If options is a string, then it specifies the encoding. Example:

fs.readFile('/etc/passwd', 'utf8', callback);

Any specified file descriptor has to support reading.

Note: Specified file descriptors will not be closed automatically.

fs.readFileSync(file[, options])#

Synchronous version of fs.readFile. Returns the contents of the file.

If the encoding option is specified then this function returns a string. Otherwise it returns a buffer.

fs.readlink(path, callback)#

Asynchronous readlink(2). The callback gets two arguments (err, linkString).

fs.readlinkSync(path)#

Synchronous readlink(2). Returns the symbolic link's string value.

fs.realpath(path[, cache], callback)#

Asynchronous realpath(2). The callback gets two arguments (err, resolvedPath). May use process.cwd to resolve relative paths. cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths.

Example:

var cache = {'/etc':'/private/etc'};
fs.realpath('/etc/passwd', cache, (err, resolvedPath) => {
  if (err) throw err;
  console.log(resolvedPath);
});

fs.readSync(fd, buffer, offset, length, position)#

Synchronous version of fs.read(). Returns the number of bytesRead.

fs.realpathSync(path[, cache])#

Synchronous realpath(2). Returns the resolved path. cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths.

fs.rename(oldPath, newPath, callback)#

Asynchronous rename(2). No arguments other than a possible exception are given to the completion callback.

fs.renameSync(oldPath, newPath)#

Synchronous rename(2). Returns undefined.

fs.rmdir(path, callback)#

Asynchronous rmdir(2). No arguments other than a possible exception are given to the completion callback.

fs.rmdirSync(path)#

Synchronous rmdir(2). Returns undefined.

fs.stat(path, callback)#

Asynchronous stat(2). The callback gets two arguments (err, stats) where stats is a fs.Stats object. See the fs.Stats section below for more information.

fs.statSync(path)#

Synchronous stat(2). Returns an instance of fs.Stats.

fs.symlink(target, path[, type], callback)#

Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms). Note that Windows junction points require the destination path to be absolute. When using 'junction', the target argument will automatically be normalized to absolute path.

Here is an example below:

fs.symlink('./foo', './new-port');

It would create a symlic link named with "new-port" that points to "foo".

fs.symlinkSync(target, path[, type])#

Synchronous symlink(2). Returns undefined.

fs.truncate(path, len, callback)#

Asynchronous truncate(2). No arguments other than a possible exception are given to the completion callback. A file descriptor can also be passed as the first argument. In this case, fs.ftruncate() is called.

fs.truncateSync(path, len)#

Synchronous truncate(2). Returns undefined.

fs.unlink(path, callback)#

Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback.

fs.unlinkSync(path)#

Synchronous unlink(2). Returns undefined.

fs.unwatchFile(filename[, listener])#

Stop watching for changes on filename. If listener is specified, only that particular listener is removed. Otherwise, all listeners are removed and you have effectively stopped watching filename.

Calling fs.unwatchFile() with a filename that is not being watched is a no-op, not an error.

Note: fs.watch() is more efficient than fs.watchFile() and fs.unwatchFile(). fs.watch() should be used instead of fs.watchFile() and fs.unwatchFile() when possible.

fs.utimes(path, atime, mtime, callback)#

Change file timestamps of the file referenced by the supplied path.

Note: the arguments atime and mtime of the following related functions does follow the below rules:

  • If the value is a numberable string like '123456789', the value would get converted to corresponding number.
  • If the value is NaN or Infinity, the value would get converted to Date.now().

fs.utimesSync(path, atime, mtime)#

Synchronous version of fs.utimes(). Returns undefined.

fs.watch(filename[, options][, listener])#

Watch for changes on filename, where filename is either a file or a directory. The returned object is a fs.FSWatcher.

The second argument is optional. The options if provided should be an object. The supported boolean members are persistent and recursive. persistent indicates whether the process should continue to run as long as files are being watched. recursive indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See Caveats below).

The default is { persistent: true, recursive: false }.

The listener callback gets two arguments (event, filename). event is either 'rename' or 'change', and filename is the name of the file which triggered the event.

Caveats#

The fs.watch API is not 100% consistent across platforms, and is unavailable in some situations.

The recursive option is only supported on OS X and Windows.

Availability#

This feature depends on the underlying operating system providing a way to be notified of filesystem changes.

  • On Linux systems, this uses inotify.
  • On BSD systems, this uses kqueue.
  • On OS X, this uses kqueue for files and 'FSEvents' for directories.
  • On SunOS systems (including Solaris and SmartOS), this uses event ports.
  • On Windows systems, this feature depends on ReadDirectoryChangesW.

If the underlying functionality is not available for some reason, then fs.watch will not be able to function. For example, watching files or directories on network file systems (NFS, SMB, etc.) often doesn't work reliably or at all.

You can still use fs.watchFile, which uses stat polling, but it is slower and less reliable.

Filename Argument#

Providing filename argument in the callback is only supported on Linux and Windows. Even on supported platforms, filename is not always guaranteed to be provided. Therefore, don't assume that filename argument is always provided in the callback, and have some fallback logic if it is null.

fs.watch('somedir', (event, filename) => {
  console.log(`event is: ${event}`);
  if (filename) {
    console.log(`filename provided: ${filename}`);
  } else {
    console.log('filename not provided');
  }
});

fs.watchFile(filename[, options], listener)#

Watch for changes on filename. The callback listener will be called each time the file is accessed.

The options argument may be omitted. If provided, it should be an object. The options object may contain a boolean named persistent that indicates whether the process should continue to run as long as files are being watched. The options object may specify an interval property indicating how often the target should be polled in milliseconds. The default is { persistent: true, interval: 5007 }.

The listener gets two arguments the current stat object and the previous stat object:

fs.watchFile('message.text', (curr, prev) => {
  console.log(`the current mtime is: ${curr.mtime}`);
  console.log(`the previous mtime was: ${prev.mtime}`);
});

These stat objects are instances of fs.Stat.

If you want to be notified when the file was modified, not just accessed, you need to compare curr.mtime and prev.mtime.

Note: when an fs.watchFile operation results in an ENOENT error, it will invoke the listener once, with all the fields zeroed (or, for dates, the Unix Epoch). In Windows, blksize and blocks fields will be undefined, instead of zero. If the file is created later on, the listener will be called again, with the latest stat objects. This is a change in functionality since v0.10.

Note: fs.watch() is more efficient than fs.watchFile and fs.unwatchFile. fs.watch should be used instead of fs.watchFile and fs.unwatchFile when possible.

fs.write(fd, buffer, offset, length[, position], callback)#

Write buffer to the file specified by fd.

offset and length determine the part of the buffer to be written.

position refers to the offset from the beginning of the file where this data should be written. If typeof position !== 'number', the data will be written at the current position. See pwrite(2).

The callback will be given three arguments (err, written, buffer) where written specifies how many bytes were written from buffer.

Note that it is unsafe to use fs.write multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.write(fd, data[, position[, encoding]], callback)#

Write data to the file specified by fd. If data is not a Buffer instance then the value will be coerced to a string.

position refers to the offset from the beginning of the file where this data should be written. If typeof position !== 'number' the data will be written at the current position. See pwrite(2).

encoding is the expected string encoding.

The callback will receive the arguments (err, written, string) where written specifies how many bytes the passed string required to be written. Note that bytes written is not the same as string characters. See Buffer.byteLength.

Unlike when writing buffer, the entire string must be written. No substring may be specified. This is because the byte offset of the resulting data may not be the same as the string offset.

Note that it is unsafe to use fs.write multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file.

fs.writeFile(file, data[, options], callback)#

  • file String | Integer filename or file descriptor
  • data String | Buffer
  • options Object | String
    • encoding String | Null default = 'utf8'
    • mode Number default = 0o666
    • flag String default = 'w'
  • callback Function

Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer.

The encoding option is ignored if data is a buffer. It defaults to 'utf8'.

Example:

fs.writeFile('message.txt', 'Hello Node.js', (err) => {
  if (err) throw err;
  console.log('It\'s saved!');
});

If options is a string, then it specifies the encoding. Example:

fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);

Any specified file descriptor has to support writing.

Note that it is unsafe to use fs.writeFile multiple times on the same file without waiting for the callback. For this scenario, fs.createWriteStream is strongly recommended.

Note: Specified file descriptors will not be closed automatically.

fs.writeFileSync(file, data[, options])#

The synchronous version of fs.writeFile(). Returns undefined.

fs.writeSync(fd, buffer, offset, length[, position])#

fs.writeSync(fd, data[, position[, encoding]])#

Synchronous versions of fs.write(). Returns the number of bytes written.

node-v4.2.6/doc/api/fs.json000644 000766 000024 00000224567 12650222331 015603 0ustar00iojsstaff000000 000000 { "source": "doc/api/fs.markdown", "modules": [ { "textRaw": "File System", "name": "fs", "stability": 2, "stabilityText": "Stable", "desc": "

File I/O is provided by simple wrappers around standard POSIX functions. To\nuse this module do require('fs'). All the methods have asynchronous and\nsynchronous forms.\n\n

\n

The asynchronous form always takes a completion callback as its last argument.\nThe arguments passed to the completion callback depend on the method, but the\nfirst argument is always reserved for an exception. If the operation was\ncompleted successfully, then the first argument will be null or undefined.\n\n

\n

When using the synchronous form any exceptions are immediately thrown.\nYou can use try/catch to handle exceptions or allow them to bubble up.\n\n

\n

Here is an example of the asynchronous version:\n\n

\n
const fs = require('fs');\n\nfs.unlink('/tmp/hello', (err) => {\n  if (err) throw err;\n  console.log('successfully deleted /tmp/hello');\n});
\n

Here is the synchronous version:\n\n

\n
const fs = require('fs');\n\nfs.unlinkSync('/tmp/hello');\nconsole.log('successfully deleted /tmp/hello');
\n

With the asynchronous methods there is no guaranteed ordering. So the\nfollowing is prone to error:\n\n

\n
fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  console.log('renamed complete');\n});\nfs.stat('/tmp/world', (err, stats) => {\n  if (err) throw err;\n  console.log(`stats: ${JSON.stringify(stats)}`);\n});
\n

It could be that fs.stat is executed before fs.rename.\nThe correct way to do this is to chain the callbacks.\n\n

\n
fs.rename('/tmp/hello', '/tmp/world', (err) => {\n  if (err) throw err;\n  fs.stat('/tmp/world', (err, stats) => {\n    if (err) throw err;\n    console.log(`stats: ${JSON.stringify(stats)}`);\n  });\n});
\n

In busy processes, the programmer is strongly encouraged to use the\nasynchronous versions of these calls. The synchronous versions will block\nthe entire process until they complete--halting all connections.\n\n

\n

The relative path to a filename can be used. Remember, however, that this path\nwill be relative to process.cwd().\n\n

\n

Most fs functions let you omit the callback argument. If you do, a default\ncallback is used that rethrows errors. To get a trace to the original call\nsite, set the NODE_DEBUG environment variable:\n\n

\n
$ cat script.js\nfunction bad() {\n  require('fs').readFile('/');\n}\nbad();\n\n$ env NODE_DEBUG=fs node script.js\nfs.js:66\n        throw err;\n              ^\nError: EISDIR, read\n    at rethrow (fs.js:61:21)\n    at maybeCallback (fs.js:79:42)\n    at Object.fs.readFile (fs.js:153:18)\n    at bad (/path/to/script.js:2:17)\n    at Object.<anonymous> (/path/to/script.js:5:1)\n    <etc.>
\n", "classes": [ { "textRaw": "Class: fs.FSWatcher", "type": "class", "name": "fs.FSWatcher", "desc": "

Objects returned from fs.watch() are of this type.\n\n

\n", "events": [ { "textRaw": "Event: 'change'", "type": "event", "name": "change", "params": [], "desc": "

Emitted when something changes in a watched directory or file.\nSee more details in [fs.watch()][].\n\n

\n" }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs.\n\n

\n" } ], "methods": [ { "textRaw": "watcher.close()", "type": "method", "name": "close", "desc": "

Stop watching for changes on the given fs.FSWatcher.\n\n

\n", "signatures": [ { "params": [] } ] } ] }, { "textRaw": "Class: fs.ReadStream", "type": "class", "name": "fs.ReadStream", "desc": "

ReadStream is a [Readable Stream][].\n\n

\n", "events": [ { "textRaw": "Event: 'open'", "type": "event", "name": "open", "params": [], "desc": "

Emitted when the ReadStream's file is opened.\n\n

\n" } ] }, { "textRaw": "Class: fs.Stats", "type": "class", "name": "fs.Stats", "desc": "

Objects returned from [fs.stat()][], [fs.lstat()][] and [fs.fstat()][] and their\nsynchronous counterparts are of this type.\n\n

\n
    \n
  • stats.isFile()
  • \n
  • stats.isDirectory()
  • \n
  • stats.isBlockDevice()
  • \n
  • stats.isCharacterDevice()
  • \n
  • stats.isSymbolicLink() (only valid with [fs.lstat()][])
  • \n
  • stats.isFIFO()
  • \n
  • stats.isSocket()
  • \n
\n

For a regular file [util.inspect(stats)][] would return a string very\nsimilar to this:\n\n

\n
{ dev: 2114,\n  ino: 48064969,\n  mode: 33188,\n  nlink: 1,\n  uid: 85,\n  gid: 100,\n  rdev: 0,\n  size: 527,\n  blksize: 4096,\n  blocks: 8,\n  atime: Mon, 10 Oct 2011 23:24:11 GMT,\n  mtime: Mon, 10 Oct 2011 23:24:11 GMT,\n  ctime: Mon, 10 Oct 2011 23:24:11 GMT,\n  birthtime: Mon, 10 Oct 2011 23:24:11 GMT }
\n

Please note that atime, mtime, birthtime, and ctime are\ninstances of [Date][MDN-Date] object and to compare the values of\nthese objects you should use appropriate methods. For most general\nuses [getTime()][MDN-Date-getTime] will return the number of\nmilliseconds elapsed since 1 January 1970 00:00:00 UTC and this\ninteger should be sufficient for any comparison, however there are\nadditional methods which can be used for displaying fuzzy information.\nMore details can be found in the [MDN JavaScript Reference][MDN-Date]\npage.\n\n

\n", "modules": [ { "textRaw": "Stat Time Values", "name": "stat_time_values", "desc": "

The times in the stat object have the following semantics:\n\n

\n
    \n
  • atime "Access Time" - Time when file data last accessed. Changed\nby the mknod(2), utimes(2), and read(2) system calls.
  • \n
  • mtime "Modified Time" - Time when file data last modified.\nChanged by the mknod(2), utimes(2), and write(2) system calls.
  • \n
  • ctime "Change Time" - Time when file status was last changed\n(inode data modification). Changed by the chmod(2), chown(2),\nlink(2), mknod(2), rename(2), unlink(2), utimes(2),\nread(2), and write(2) system calls.
  • \n
  • birthtime "Birth Time" - Time of file creation. Set once when the\nfile is created. On filesystems where birthtime is not available,\nthis field may instead hold either the ctime or\n1970-01-01T00:00Z (ie, unix epoch timestamp 0). On Darwin and\nother FreeBSD variants, also set if the atime is explicitly set to\nan earlier value than the current birthtime using the utimes(2)\nsystem call.
  • \n
\n

Prior to Node v0.12, the ctime held the birthtime on Windows\nsystems. Note that as of v0.12, ctime is not "creation time", and\non Unix systems, it never was.\n\n

\n", "type": "module", "displayName": "Stat Time Values" } ] }, { "textRaw": "Class: fs.WriteStream", "type": "class", "name": "fs.WriteStream", "desc": "

WriteStream is a [Writable Stream][].\n\n

\n", "events": [ { "textRaw": "Event: 'open'", "type": "event", "name": "open", "params": [], "desc": "

Emitted when the WriteStream's file is opened.\n\n

\n" } ], "properties": [ { "textRaw": "writeStream.bytesWritten", "name": "bytesWritten", "desc": "

The number of bytes written so far. Does not include data that is still queued\nfor writing.\n\n

\n" } ] } ], "methods": [ { "textRaw": "fs.access(path[, mode], callback)", "type": "method", "name": "access", "desc": "

Tests a user's permissions for the file specified by path. mode is an\noptional integer that specifies the accessibility checks to be performed. The\nfollowing constants define the possible values of mode. It is possible to\ncreate a mask consisting of the bitwise OR of two or more values.\n\n

\n
    \n
  • fs.F_OK - File is visible to the calling process. This is useful for\ndetermining if a file exists, but says nothing about rwx permissions.\nDefault if no mode is specified.
  • \n
  • fs.R_OK - File can be read by the calling process.
  • \n
  • fs.W_OK - File can be written by the calling process.
  • \n
  • fs.X_OK - File can be executed by the calling process. This has no effect\non Windows (will behave like fs.F_OK).
  • \n
\n

The final argument, callback, is a callback function that is invoked with\na possible error argument. If any of the accessibility checks fail, the error\nargument will be populated. The following example checks if the file\n/etc/passwd can be read and written by the current process.\n\n

\n
fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) {\n  console.log(err ? 'no access!' : 'can read/write');\n});
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.accessSync(path[, mode])", "type": "method", "name": "accessSync", "desc": "

Synchronous version of [fs.access()][]. This throws if any accessibility checks\nfail, and does nothing otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.appendFile(file, data[, options], callback)", "type": "method", "name": "appendFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`data` {String | Buffer} ", "name": "data", "type": "String | Buffer" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `'utf8'` ", "name": "encoding", "type": "String | Null", "desc": "default = `'utf8'`" }, { "textRaw": "`mode` {Number} default = `0o666` ", "name": "mode", "type": "Number", "desc": "default = `0o666`" }, { "textRaw": "`flag` {String} default = `'a'` ", "name": "flag", "type": "String", "desc": "default = `'a'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously append data to a file, creating the file if it does not yet exist.\ndata can be a string or a buffer.\n\n

\n

Example:\n\n

\n
fs.appendFile('message.txt', 'data to append', (err) => {\n  if (err) throw err;\n  console.log('The "data to append" was appended to file!');\n});
\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.appendFile('message.txt', 'data to append', 'utf8', callback);
\n

Any specified file descriptor has to have been opened for appending.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.appendFileSync(file, data[, options])", "type": "method", "name": "appendFileSync", "desc": "

The synchronous version of [fs.appendFile()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.chmod(path, mode, callback)", "type": "method", "name": "chmod", "desc": "

Asynchronous chmod(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.chmodSync(path, mode)", "type": "method", "name": "chmodSync", "desc": "

Synchronous chmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.chown(path, uid, gid, callback)", "type": "method", "name": "chown", "desc": "

Asynchronous chown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.chownSync(path, uid, gid)", "type": "method", "name": "chownSync", "desc": "

Synchronous chown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.close(fd, callback)", "type": "method", "name": "close", "desc": "

Asynchronous close(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.closeSync(fd)", "type": "method", "name": "closeSync", "desc": "

Synchronous close(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.createReadStream(path[, options])", "type": "method", "name": "createReadStream", "desc": "

Returns a new [ReadStream][] object. (See [Readable Stream][]).\n\n

\n

Be aware that, unlike the default value set for highWaterMark on a\nreadable stream (16 kb), the stream returned by this method has a\ndefault value of 64 kb for the same parameter.\n\n

\n

options is an object or string with the following defaults:\n\n

\n
{ flags: 'r',\n  encoding: null,\n  fd: null,\n  mode: 0o666,\n  autoClose: true\n}
\n

options can include start and end values to read a range of bytes from\nthe file instead of the entire file. Both start and end are inclusive and\nstart at 0. The encoding can be any one of those accepted by [Buffer][].\n\n

\n

If fd is specified, ReadStream will ignore the path argument and will use\nthe specified file descriptor. This means that no 'open' event will be emitted.\nNote that fd should be blocking; non-blocking fds should be passed to\n[net.Socket][].\n\n

\n

If autoClose is false, then the file descriptor won't be closed, even if\nthere's an error. It is your responsibility to close it and make sure\nthere's no file descriptor leak. If autoClose is set to true (default\nbehavior), on error or end the file descriptor will be closed\nautomatically.\n\n

\n

mode sets the file mode (permission and sticky bits), but only if the\nfile was created.\n\n

\n

An example to read the last 10 bytes of a file which is 100 bytes long:\n\n

\n
fs.createReadStream('sample.txt', {start: 90, end: 99});
\n

If options is a string, then it specifies the encoding.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.createWriteStream(path[, options])", "type": "method", "name": "createWriteStream", "desc": "

Returns a new [WriteStream][] object. (See [Writable Stream][]).\n\n

\n

options is an object or string with the following defaults:\n\n

\n
{ flags: 'w',\n  defaultEncoding: 'utf8',\n  fd: null,\n  mode: 0o666 }
\n

options may also include a start option to allow writing data at\nsome position past the beginning of the file. Modifying a file rather\nthan replacing it may require a flags mode of r+ rather than the\ndefault mode w. The defaultEncoding can be any one of those accepted by [Buffer][].\n\n

\n

Like [ReadStream][], if fd is specified, WriteStream will ignore the\npath argument and will use the specified file descriptor. This means that no\n'open' event will be emitted. Note that fd should be blocking; non-blocking\nfds should be passed to [net.Socket][].\n\n

\n

If options is a string, then it specifies the encoding.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.exists(path, callback)", "type": "method", "name": "exists", "stability": 0, "stabilityText": "Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead.", "desc": "

Test whether or not the given path exists by checking with the file system.\nThen call the callback argument with either true or false. Example:\n\n

\n
fs.exists('/etc/passwd', (exists) => {\n  console.log(exists ? 'it\\'s there' : 'no passwd!');\n});
\n

fs.exists() should not be used to check if a file exists before calling\nfs.open(). Doing so introduces a race condition since other processes may\nchange the file's state between the two calls. Instead, user code should\ncall fs.open() directly and handle the error raised if the file is\nnon-existent.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.existsSync(path)", "type": "method", "name": "existsSync", "stability": 0, "stabilityText": "Deprecated: Use [`fs.statSync()`][] or [`fs.accessSync()`][] instead.", "desc": "

Synchronous version of [fs.exists()][].\nReturns true if the file exists, false otherwise.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.fchmod(fd, mode, callback)", "type": "method", "name": "fchmod", "desc": "

Asynchronous fchmod(2). No arguments other than a possible exception\nare given to the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fchmodSync(fd, mode)", "type": "method", "name": "fchmodSync", "desc": "

Synchronous fchmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.fchown(fd, uid, gid, callback)", "type": "method", "name": "fchown", "desc": "

Asynchronous fchown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fchownSync(fd, uid, gid)", "type": "method", "name": "fchownSync", "desc": "

Synchronous fchown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.fstat(fd, callback)", "type": "method", "name": "fstat", "desc": "

Asynchronous fstat(2). The callback gets two arguments (err, stats) where\nstats is a fs.Stats object. fstat() is identical to [stat()][], except that\nthe file to be stat-ed is specified by the file descriptor fd.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fstatSync(fd)", "type": "method", "name": "fstatSync", "desc": "

Synchronous fstat(2). Returns an instance of fs.Stats.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.fsync(fd, callback)", "type": "method", "name": "fsync", "desc": "

Asynchronous fsync(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.fsyncSync(fd)", "type": "method", "name": "fsyncSync", "desc": "

Synchronous fsync(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "fs.ftruncate(fd, len, callback)", "type": "method", "name": "ftruncate", "desc": "

Asynchronous ftruncate(2). No arguments other than a possible exception are\ngiven to the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "len" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.ftruncateSync(fd, len)", "type": "method", "name": "ftruncateSync", "desc": "

Synchronous ftruncate(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "len" } ] } ] }, { "textRaw": "fs.futimes(fd, atime, mtime, callback)", "type": "method", "name": "futimes", "desc": "

Change the file timestamps of a file referenced by the supplied file\ndescriptor.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "atime" }, { "name": "mtime" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.futimesSync(fd, atime, mtime)", "type": "method", "name": "futimesSync", "desc": "

Synchronous version of [fs.futimes()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "atime" }, { "name": "mtime" } ] } ] }, { "textRaw": "fs.lchmod(path, mode, callback)", "type": "method", "name": "lchmod", "desc": "

Asynchronous lchmod(2). No arguments other than a possible exception\nare given to the completion callback.\n\n

\n

Only available on Mac OS X.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lchmodSync(path, mode)", "type": "method", "name": "lchmodSync", "desc": "

Synchronous lchmod(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode" } ] } ] }, { "textRaw": "fs.lchown(path, uid, gid, callback)", "type": "method", "name": "lchown", "desc": "

Asynchronous lchown(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lchownSync(path, uid, gid)", "type": "method", "name": "lchownSync", "desc": "

Synchronous lchown(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "uid" }, { "name": "gid" } ] } ] }, { "textRaw": "fs.link(srcpath, dstpath, callback)", "type": "method", "name": "link", "desc": "

Asynchronous link(2). No arguments other than a possible exception are given to\nthe completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "srcpath" }, { "name": "dstpath" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.linkSync(srcpath, dstpath)", "type": "method", "name": "linkSync", "desc": "

Synchronous link(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "srcpath" }, { "name": "dstpath" } ] } ] }, { "textRaw": "fs.lstat(path, callback)", "type": "method", "name": "lstat", "desc": "

Asynchronous lstat(2). The callback gets two arguments (err, stats) where\nstats is a fs.Stats object. lstat() is identical to stat(), except that if\npath is a symbolic link, then the link itself is stat-ed, not the file that it\nrefers to.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.lstatSync(path)", "type": "method", "name": "lstatSync", "desc": "

Synchronous lstat(2). Returns an instance of fs.Stats.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.mkdir(path[, mode], callback)", "type": "method", "name": "mkdir", "desc": "

Asynchronous mkdir(2). No arguments other than a possible exception are given\nto the completion callback. mode defaults to 0o777.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.mkdirSync(path[, mode])", "type": "method", "name": "mkdirSync", "desc": "

Synchronous mkdir(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.open(path, flags[, mode], callback)", "type": "method", "name": "open", "desc": "

Asynchronous file open. See open(2). flags can be:\n\n

\n
    \n
  • 'r' - Open file for reading.\nAn exception occurs if the file does not exist.

    \n
  • \n
  • 'r+' - Open file for reading and writing.\nAn exception occurs if the file does not exist.

    \n
  • \n
  • 'rs' - Open file for reading in synchronous mode. Instructs the operating\nsystem to bypass the local file system cache.

    \n

    This is primarily useful for opening files on NFS mounts as it allows you to\nskip the potentially stale local cache. It has a very real impact on I/O\nperformance so don't use this flag unless you need it.

    \n

    Note that this doesn't turn fs.open() into a synchronous blocking call.\nIf that's what you want then you should be using fs.openSync()

    \n
  • \n
  • 'rs+' - Open file for reading and writing, telling the OS to open it\nsynchronously. See notes for 'rs' about using this with caution.

    \n
  • \n
  • 'w' - Open file for writing.\nThe file is created (if it does not exist) or truncated (if it exists).

    \n
  • \n
  • 'wx' - Like 'w' but fails if path exists.

    \n
  • \n
  • 'w+' - Open file for reading and writing.\nThe file is created (if it does not exist) or truncated (if it exists).

    \n
  • \n
  • 'wx+' - Like 'w+' but fails if path exists.

    \n
  • \n
  • 'a' - Open file for appending.\nThe file is created if it does not exist.

    \n
  • \n
  • 'ax' - Like 'a' but fails if path exists.

    \n
  • \n
  • 'a+' - Open file for reading and appending.\nThe file is created if it does not exist.

    \n
  • \n
  • 'ax+' - Like 'a+' but fails if path exists.

    \n
  • \n
\n

mode sets the file mode (permission and sticky bits), but only if the file was\ncreated. It defaults to 0666, readable and writeable.\n\n

\n

The callback gets two arguments (err, fd).\n\n

\n

The exclusive flag 'x' (O_EXCL flag in open(2)) ensures that path is newly\ncreated. On POSIX systems, path is considered to exist even if it is a symlink\nto a non-existent file. The exclusive flag may or may not work with network file\nsystems.\n\n

\n

flags can also be a number as documented by open(2); commonly used constants\nare available from require('constants'). On Windows, flags are translated to\ntheir equivalent ones where applicable, e.g. O_WRONLY to FILE_GENERIC_WRITE,\nor O_EXCL|O_CREAT to CREATE_NEW, as accepted by CreateFileW.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "flags" }, { "name": "mode", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.openSync(path, flags[, mode])", "type": "method", "name": "openSync", "desc": "

Synchronous version of [fs.open()][]. Returns an integer representing the file\ndescriptor.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "flags" }, { "name": "mode", "optional": true } ] } ] }, { "textRaw": "fs.read(fd, buffer, offset, length, position, callback)", "type": "method", "name": "read", "desc": "

Read data from the file specified by fd.\n\n

\n

buffer is the buffer that the data will be written to.\n\n

\n

offset is the offset in the buffer to start writing at.\n\n

\n

length is an integer specifying the number of bytes to read.\n\n

\n

position is an integer specifying where to begin reading from in the file.\nIf position is null, data will be read from the current file position.\n\n

\n

The callback is given the three arguments, (err, bytesRead, buffer).\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readdir(path, callback)", "type": "method", "name": "readdir", "desc": "

Asynchronous readdir(3). Reads the contents of a directory.\nThe callback gets two arguments (err, files) where files is an array of\nthe names of the files in the directory excluding '.' and '..'.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readdirSync(path)", "type": "method", "name": "readdirSync", "desc": "

Synchronous readdir(3). Returns an array of filenames excluding '.' and\n'..'.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.readFile(file[, options], callback)", "type": "method", "name": "readFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `null` ", "name": "encoding", "type": "String | Null", "desc": "default = `null`" }, { "textRaw": "`flag` {String} default = `'r'` ", "name": "flag", "type": "String", "desc": "default = `'r'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously reads the entire contents of a file. Example:\n\n

\n
fs.readFile('/etc/passwd', (err, data) => {\n  if (err) throw err;\n  console.log(data);\n});
\n

The callback is passed two arguments (err, data), where data is the\ncontents of the file.\n\n

\n

If no encoding is specified, then the raw buffer is returned.\n\n

\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.readFile('/etc/passwd', 'utf8', callback);
\n

Any specified file descriptor has to support reading.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.readFileSync(file[, options])", "type": "method", "name": "readFileSync", "desc": "

Synchronous version of [fs.readFile][]. Returns the contents of the file.\n\n

\n

If the encoding option is specified then this function returns a\nstring. Otherwise it returns a buffer.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.readlink(path, callback)", "type": "method", "name": "readlink", "desc": "

Asynchronous readlink(2). The callback gets two arguments (err,\nlinkString).\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readlinkSync(path)", "type": "method", "name": "readlinkSync", "desc": "

Synchronous readlink(2). Returns the symbolic link's string value.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.realpath(path[, cache], callback)", "type": "method", "name": "realpath", "desc": "

Asynchronous realpath(2). The callback gets two arguments (err,\nresolvedPath). May use process.cwd to resolve relative paths. cache is an\nobject literal of mapped paths that can be used to force a specific path\nresolution or avoid additional fs.stat calls for known real paths.\n\n

\n

Example:\n\n

\n
var cache = {'/etc':'/private/etc'};\nfs.realpath('/etc/passwd', cache, (err, resolvedPath) => {\n  if (err) throw err;\n  console.log(resolvedPath);\n});
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "cache", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.readSync(fd, buffer, offset, length, position)", "type": "method", "name": "readSync", "desc": "

Synchronous version of [fs.read()][]. Returns the number of bytesRead.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position" } ] } ] }, { "textRaw": "fs.realpathSync(path[, cache])", "type": "method", "name": "realpathSync", "desc": "

Synchronous realpath(2). Returns the resolved path. cache is an\nobject literal of mapped paths that can be used to force a specific path\nresolution or avoid additional fs.stat calls for known real paths.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "cache", "optional": true } ] } ] }, { "textRaw": "fs.rename(oldPath, newPath, callback)", "type": "method", "name": "rename", "desc": "

Asynchronous rename(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "oldPath" }, { "name": "newPath" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.renameSync(oldPath, newPath)", "type": "method", "name": "renameSync", "desc": "

Synchronous rename(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "oldPath" }, { "name": "newPath" } ] } ] }, { "textRaw": "fs.rmdir(path, callback)", "type": "method", "name": "rmdir", "desc": "

Asynchronous rmdir(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.rmdirSync(path)", "type": "method", "name": "rmdirSync", "desc": "

Synchronous rmdir(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.stat(path, callback)", "type": "method", "name": "stat", "desc": "

Asynchronous stat(2). The callback gets two arguments (err, stats) where\nstats is a [fs.Stats][] object. See the [fs.Stats][] section below for more\ninformation.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.statSync(path)", "type": "method", "name": "statSync", "desc": "

Synchronous stat(2). Returns an instance of [fs.Stats][].\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.symlink(target, path[, type], callback)", "type": "method", "name": "symlink", "desc": "

Asynchronous symlink(2). No arguments other than a possible exception are given\nto the completion callback.\nThe type argument can be set to 'dir', 'file', or 'junction' (default\nis 'file') and is only available on Windows (ignored on other platforms).\nNote that Windows junction points require the destination path to be absolute. When using\n'junction', the target argument will automatically be normalized to absolute path.\n\n

\n

Here is an example below:\n\n

\n
fs.symlink('./foo', './new-port');
\n

It would create a symlic link named with "new-port" that points to "foo".\n\n

\n", "signatures": [ { "params": [ { "name": "target" }, { "name": "path" }, { "name": "type", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.symlinkSync(target, path[, type])", "type": "method", "name": "symlinkSync", "desc": "

Synchronous symlink(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "target" }, { "name": "path" }, { "name": "type", "optional": true } ] } ] }, { "textRaw": "fs.truncate(path, len, callback)", "type": "method", "name": "truncate", "desc": "

Asynchronous truncate(2). No arguments other than a possible exception are\ngiven to the completion callback. A file descriptor can also be passed as the\nfirst argument. In this case, fs.ftruncate() is called.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "len" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.truncateSync(path, len)", "type": "method", "name": "truncateSync", "desc": "

Synchronous truncate(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "len" } ] } ] }, { "textRaw": "fs.unlink(path, callback)", "type": "method", "name": "unlink", "desc": "

Asynchronous unlink(2). No arguments other than a possible exception are given\nto the completion callback.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.unlinkSync(path)", "type": "method", "name": "unlinkSync", "desc": "

Synchronous unlink(2). Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "fs.unwatchFile(filename[, listener])", "type": "method", "name": "unwatchFile", "desc": "

Stop watching for changes on filename. If listener is specified, only that\nparticular listener is removed. Otherwise, all listeners are removed and you\nhave effectively stopped watching filename.\n\n

\n

Calling fs.unwatchFile() with a filename that is not being watched is a\nno-op, not an error.\n\n

\n

Note: [fs.watch()][] is more efficient than fs.watchFile() and fs.unwatchFile().\nfs.watch() should be used instead of fs.watchFile() and fs.unwatchFile()\nwhen possible.\n\n

\n", "signatures": [ { "params": [ { "name": "filename" }, { "name": "listener", "optional": true } ] } ] }, { "textRaw": "fs.utimes(path, atime, mtime, callback)", "type": "method", "name": "utimes", "desc": "

Change file timestamps of the file referenced by the supplied path.\n\n

\n

Note: the arguments atime and mtime of the following related functions does\nfollow the below rules:\n\n

\n
    \n
  • If the value is a numberable string like '123456789', the value would get\nconverted to corresponding number.
  • \n
  • If the value is NaN or Infinity, the value would get converted to\nDate.now().
  • \n
\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "atime" }, { "name": "mtime" }, { "name": "callback" } ] } ] }, { "textRaw": "fs.utimesSync(path, atime, mtime)", "type": "method", "name": "utimesSync", "desc": "

Synchronous version of [fs.utimes()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "atime" }, { "name": "mtime" } ] } ] }, { "textRaw": "fs.watch(filename[, options][, listener])", "type": "method", "name": "watch", "desc": "

Watch for changes on filename, where filename is either a file or a\ndirectory. The returned object is a [fs.FSWatcher][].\n\n

\n

The second argument is optional. The options if provided should be an object.\nThe supported boolean members are persistent and recursive. persistent\nindicates whether the process should continue to run as long as files are being\nwatched. recursive indicates whether all subdirectories should be watched, or\nonly the current directory. This applies when a directory is specified, and only\non supported platforms (See Caveats below).\n\n

\n

The default is { persistent: true, recursive: false }.\n\n

\n

The listener callback gets two arguments (event, filename). event is either\n'rename' or 'change', and filename is the name of the file which triggered\nthe event.\n\n

\n", "miscs": [ { "textRaw": "Caveats", "name": "Caveats", "type": "misc", "desc": "

The fs.watch API is not 100% consistent across platforms, and is\nunavailable in some situations.\n\n

\n

The recursive option is only supported on OS X and Windows.\n\n

\n", "miscs": [ { "textRaw": "Availability", "name": "Availability", "type": "misc", "desc": "

This feature depends on the underlying operating system providing a way\nto be notified of filesystem changes.\n\n

\n
    \n
  • On Linux systems, this uses inotify.
  • \n
  • On BSD systems, this uses kqueue.
  • \n
  • On OS X, this uses kqueue for files and 'FSEvents' for directories.
  • \n
  • On SunOS systems (including Solaris and SmartOS), this uses event ports.
  • \n
  • On Windows systems, this feature depends on ReadDirectoryChangesW.
  • \n
\n

If the underlying functionality is not available for some reason, then\nfs.watch will not be able to function. For example, watching files or\ndirectories on network file systems (NFS, SMB, etc.) often doesn't work\nreliably or at all.\n\n

\n

You can still use fs.watchFile, which uses stat polling, but it is slower and\nless reliable.\n\n

\n" }, { "textRaw": "Filename Argument", "name": "Filename Argument", "type": "misc", "desc": "

Providing filename argument in the callback is only supported on Linux and\nWindows. Even on supported platforms, filename is not always guaranteed to\nbe provided. Therefore, don't assume that filename argument is always\nprovided in the callback, and have some fallback logic if it is null.\n\n

\n
fs.watch('somedir', (event, filename) => {\n  console.log(`event is: ${event}`);\n  if (filename) {\n    console.log(`filename provided: ${filename}`);\n  } else {\n    console.log('filename not provided');\n  }\n});
\n" } ] } ], "signatures": [ { "params": [ { "name": "filename" }, { "name": "options", "optional": true }, { "name": "listener", "optional": true } ] } ] }, { "textRaw": "fs.watchFile(filename[, options], listener)", "type": "method", "name": "watchFile", "desc": "

Watch for changes on filename. The callback listener will be called each\ntime the file is accessed.\n\n

\n

The options argument may be omitted. If provided, it should be an object. The\noptions object may contain a boolean named persistent that indicates\nwhether the process should continue to run as long as files are being watched.\nThe options object may specify an interval property indicating how often the\ntarget should be polled in milliseconds. The default is\n{ persistent: true, interval: 5007 }.\n\n

\n

The listener gets two arguments the current stat object and the previous\nstat object:\n\n

\n
fs.watchFile('message.text', (curr, prev) => {\n  console.log(`the current mtime is: ${curr.mtime}`);\n  console.log(`the previous mtime was: ${prev.mtime}`);\n});
\n

These stat objects are instances of fs.Stat.\n\n

\n

If you want to be notified when the file was modified, not just accessed,\nyou need to compare curr.mtime and prev.mtime.\n\n

\n

Note: when an fs.watchFile operation results in an ENOENT error, it will\n invoke the listener once, with all the fields zeroed (or, for dates, the Unix\n Epoch). In Windows, blksize and blocks fields will be undefined, instead\n of zero. If the file is created later on, the listener will be called again,\n with the latest stat objects. This is a change in functionality since v0.10.\n\n

\n

Note: [fs.watch()][] is more efficient than fs.watchFile and fs.unwatchFile.\nfs.watch should be used instead of fs.watchFile and fs.unwatchFile\nwhen possible.\n\n

\n", "signatures": [ { "params": [ { "name": "filename" }, { "name": "options", "optional": true }, { "name": "listener" } ] } ] }, { "textRaw": "fs.write(fd, buffer, offset, length[, position], callback)", "type": "method", "name": "write", "desc": "

Write buffer to the file specified by fd.\n\n

\n

offset and length determine the part of the buffer to be written.\n\n

\n

position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number', the data will be written\nat the current position. See pwrite(2).\n\n

\n

The callback will be given three arguments (err, written, buffer) where\nwritten specifies how many bytes were written from buffer.\n\n

\n

Note that it is unsafe to use fs.write multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.write(fd, data[, position[, encoding]], callback)", "type": "method", "name": "write", "desc": "

Write data to the file specified by fd. If data is not a Buffer instance\nthen the value will be coerced to a string.\n\n

\n

position refers to the offset from the beginning of the file where this data\nshould be written. If typeof position !== 'number' the data will be written at\nthe current position. See pwrite(2).\n\n

\n

encoding is the expected string encoding.\n\n

\n

The callback will receive the arguments (err, written, string) where written\nspecifies how many bytes the passed string required to be written. Note that\nbytes written is not the same as string characters. See [Buffer.byteLength][].\n\n

\n

Unlike when writing buffer, the entire string must be written. No substring\nmay be specified. This is because the byte offset of the resulting data may not\nbe the same as the string offset.\n\n

\n

Note that it is unsafe to use fs.write multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

On Linux, positional writes don't work when the file is opened in append mode.\nThe kernel ignores the position argument and always appends the data to\nthe end of the file.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "fs.writeFile(file, data[, options], callback)", "type": "method", "name": "writeFile", "signatures": [ { "params": [ { "textRaw": "`file` {String | Integer} filename or file descriptor ", "name": "file", "type": "String | Integer", "desc": "filename or file descriptor" }, { "textRaw": "`data` {String | Buffer} ", "name": "data", "type": "String | Buffer" }, { "textRaw": "`options` {Object | String} ", "options": [ { "textRaw": "`encoding` {String | Null} default = `'utf8'` ", "name": "encoding", "type": "String | Null", "desc": "default = `'utf8'`" }, { "textRaw": "`mode` {Number} default = `0o666` ", "name": "mode", "type": "Number", "desc": "default = `0o666`" }, { "textRaw": "`flag` {String} default = `'w'` ", "name": "flag", "type": "String", "desc": "default = `'w'`" } ], "name": "options", "type": "Object | String", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ], "desc": "

Asynchronously writes data to a file, replacing the file if it already exists.\ndata can be a string or a buffer.\n\n

\n

The encoding option is ignored if data is a buffer. It defaults\nto 'utf8'.\n\n

\n

Example:\n\n

\n
fs.writeFile('message.txt', 'Hello Node.js', (err) => {\n  if (err) throw err;\n  console.log('It\\'s saved!');\n});
\n

If options is a string, then it specifies the encoding. Example:\n\n

\n
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);
\n

Any specified file descriptor has to support writing.\n\n

\n

Note that it is unsafe to use fs.writeFile multiple times on the same file\nwithout waiting for the callback. For this scenario,\nfs.createWriteStream is strongly recommended.\n\n

\n

Note: Specified file descriptors will not be closed automatically.\n\n

\n" }, { "textRaw": "fs.writeFileSync(file, data[, options])", "type": "method", "name": "writeFileSync", "desc": "

The synchronous version of [fs.writeFile()][]. Returns undefined.\n\n

\n", "signatures": [ { "params": [ { "name": "file" }, { "name": "data" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "fs.writeSync(fd, buffer, offset, length[, position])", "type": "method", "name": "writeSync", "desc": "

Synchronous versions of [fs.write()][]. Returns the number of bytes written.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true } ] }, { "params": [ { "name": "fd" }, { "name": "buffer" }, { "name": "offset" }, { "name": "length" }, { "name": "position", "optional": true } ] } ] }, { "textRaw": "fs.writeSync(fd, data[, position[, encoding]])", "type": "method", "name": "writeSync", "desc": "

Synchronous versions of [fs.write()][]. Returns the number of bytes written.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" }, { "name": "data" }, { "name": "position" }, { "name": "encoding]", "optional": true } ] } ] } ], "type": "module", "displayName": "fs" } ] } node-v4.2.6/doc/api/fs.markdown000644 000766 000024 00000100062 12650222326 016437 0ustar00iojsstaff000000 000000 # File System Stability: 2 - Stable File I/O is provided by simple wrappers around standard POSIX functions. To use this module do `require('fs')`. All the methods have asynchronous and synchronous forms. The asynchronous form always takes a completion callback as its last argument. The arguments passed to the completion callback depend on the method, but the first argument is always reserved for an exception. If the operation was completed successfully, then the first argument will be `null` or `undefined`. When using the synchronous form any exceptions are immediately thrown. You can use try/catch to handle exceptions or allow them to bubble up. Here is an example of the asynchronous version: const fs = require('fs'); fs.unlink('/tmp/hello', (err) => { if (err) throw err; console.log('successfully deleted /tmp/hello'); }); Here is the synchronous version: const fs = require('fs'); fs.unlinkSync('/tmp/hello'); console.log('successfully deleted /tmp/hello'); With the asynchronous methods there is no guaranteed ordering. So the following is prone to error: fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; console.log('renamed complete'); }); fs.stat('/tmp/world', (err, stats) => { if (err) throw err; console.log(`stats: ${JSON.stringify(stats)}`); }); It could be that `fs.stat` is executed before `fs.rename`. The correct way to do this is to chain the callbacks. fs.rename('/tmp/hello', '/tmp/world', (err) => { if (err) throw err; fs.stat('/tmp/world', (err, stats) => { if (err) throw err; console.log(`stats: ${JSON.stringify(stats)}`); }); }); In busy processes, the programmer is _strongly encouraged_ to use the asynchronous versions of these calls. The synchronous versions will block the entire process until they complete--halting all connections. The relative path to a filename can be used. Remember, however, that this path will be relative to `process.cwd()`. Most fs functions let you omit the callback argument. If you do, a default callback is used that rethrows errors. To get a trace to the original call site, set the `NODE_DEBUG` environment variable: $ cat script.js function bad() { require('fs').readFile('/'); } bad(); $ env NODE_DEBUG=fs node script.js fs.js:66 throw err; ^ Error: EISDIR, read at rethrow (fs.js:61:21) at maybeCallback (fs.js:79:42) at Object.fs.readFile (fs.js:153:18) at bad (/path/to/script.js:2:17) at Object. (/path/to/script.js:5:1) ## Class: fs.FSWatcher Objects returned from `fs.watch()` are of this type. ### Event: 'change' * `event` {String} The type of fs change * `filename` {String} The filename that changed (if relevant/available) Emitted when something changes in a watched directory or file. See more details in [`fs.watch()`][]. ### Event: 'error' * `error` {Error object} Emitted when an error occurs. ### watcher.close() Stop watching for changes on the given `fs.FSWatcher`. ## Class: fs.ReadStream `ReadStream` is a [Readable Stream][]. ### Event: 'open' * `fd` {Integer} file descriptor used by the ReadStream. Emitted when the ReadStream's file is opened. ## Class: fs.Stats Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and their synchronous counterparts are of this type. - `stats.isFile()` - `stats.isDirectory()` - `stats.isBlockDevice()` - `stats.isCharacterDevice()` - `stats.isSymbolicLink()` (only valid with [`fs.lstat()`][]) - `stats.isFIFO()` - `stats.isSocket()` For a regular file [`util.inspect(stats)`][] would return a string very similar to this: { dev: 2114, ino: 48064969, mode: 33188, nlink: 1, uid: 85, gid: 100, rdev: 0, size: 527, blksize: 4096, blocks: 8, atime: Mon, 10 Oct 2011 23:24:11 GMT, mtime: Mon, 10 Oct 2011 23:24:11 GMT, ctime: Mon, 10 Oct 2011 23:24:11 GMT, birthtime: Mon, 10 Oct 2011 23:24:11 GMT } Please note that `atime`, `mtime`, `birthtime`, and `ctime` are instances of [`Date`][MDN-Date] object and to compare the values of these objects you should use appropriate methods. For most general uses [`getTime()`][MDN-Date-getTime] will return the number of milliseconds elapsed since _1 January 1970 00:00:00 UTC_ and this integer should be sufficient for any comparison, however there are additional methods which can be used for displaying fuzzy information. More details can be found in the [MDN JavaScript Reference][MDN-Date] page. ### Stat Time Values The times in the stat object have the following semantics: * `atime` "Access Time" - Time when file data last accessed. Changed by the `mknod(2)`, `utimes(2)`, and `read(2)` system calls. * `mtime` "Modified Time" - Time when file data last modified. Changed by the `mknod(2)`, `utimes(2)`, and `write(2)` system calls. * `ctime` "Change Time" - Time when file status was last changed (inode data modification). Changed by the `chmod(2)`, `chown(2)`, `link(2)`, `mknod(2)`, `rename(2)`, `unlink(2)`, `utimes(2)`, `read(2)`, and `write(2)` system calls. * `birthtime` "Birth Time" - Time of file creation. Set once when the file is created. On filesystems where birthtime is not available, this field may instead hold either the `ctime` or `1970-01-01T00:00Z` (ie, unix epoch timestamp `0`). On Darwin and other FreeBSD variants, also set if the `atime` is explicitly set to an earlier value than the current `birthtime` using the `utimes(2)` system call. Prior to Node v0.12, the `ctime` held the `birthtime` on Windows systems. Note that as of v0.12, `ctime` is not "creation time", and on Unix systems, it never was. ## Class: fs.WriteStream `WriteStream` is a [Writable Stream][]. ### Event: 'open' * `fd` {Integer} file descriptor used by the WriteStream. Emitted when the WriteStream's file is opened. ### writeStream.bytesWritten The number of bytes written so far. Does not include data that is still queued for writing. ## fs.access(path[, mode], callback) Tests a user's permissions for the file specified by `path`. `mode` is an optional integer that specifies the accessibility checks to be performed. The following constants define the possible values of `mode`. It is possible to create a mask consisting of the bitwise OR of two or more values. - `fs.F_OK` - File is visible to the calling process. This is useful for determining if a file exists, but says nothing about `rwx` permissions. Default if no `mode` is specified. - `fs.R_OK` - File can be read by the calling process. - `fs.W_OK` - File can be written by the calling process. - `fs.X_OK` - File can be executed by the calling process. This has no effect on Windows (will behave like `fs.F_OK`). The final argument, `callback`, is a callback function that is invoked with a possible error argument. If any of the accessibility checks fail, the error argument will be populated. The following example checks if the file `/etc/passwd` can be read and written by the current process. fs.access('/etc/passwd', fs.R_OK | fs.W_OK, function (err) { console.log(err ? 'no access!' : 'can read/write'); }); ## fs.accessSync(path[, mode]) Synchronous version of [`fs.access()`][]. This throws if any accessibility checks fail, and does nothing otherwise. ## fs.appendFile(file, data[, options], callback) * `file` {String | Integer} filename or file descriptor * `data` {String | Buffer} * `options` {Object | String} * `encoding` {String | Null} default = `'utf8'` * `mode` {Number} default = `0o666` * `flag` {String} default = `'a'` * `callback` {Function} Asynchronously append data to a file, creating the file if it does not yet exist. `data` can be a string or a buffer. Example: fs.appendFile('message.txt', 'data to append', (err) => { if (err) throw err; console.log('The "data to append" was appended to file!'); }); If `options` is a string, then it specifies the encoding. Example: fs.appendFile('message.txt', 'data to append', 'utf8', callback); Any specified file descriptor has to have been opened for appending. _Note: Specified file descriptors will not be closed automatically._ ## fs.appendFileSync(file, data[, options]) The synchronous version of [`fs.appendFile()`][]. Returns `undefined`. ## fs.chmod(path, mode, callback) Asynchronous chmod(2). No arguments other than a possible exception are given to the completion callback. ## fs.chmodSync(path, mode) Synchronous chmod(2). Returns `undefined`. ## fs.chown(path, uid, gid, callback) Asynchronous chown(2). No arguments other than a possible exception are given to the completion callback. ## fs.chownSync(path, uid, gid) Synchronous chown(2). Returns `undefined`. ## fs.close(fd, callback) Asynchronous close(2). No arguments other than a possible exception are given to the completion callback. ## fs.closeSync(fd) Synchronous close(2). Returns `undefined`. ## fs.createReadStream(path[, options]) Returns a new [`ReadStream`][] object. (See [Readable Stream][]). Be aware that, unlike the default value set for `highWaterMark` on a readable stream (16 kb), the stream returned by this method has a default value of 64 kb for the same parameter. `options` is an object or string with the following defaults: { flags: 'r', encoding: null, fd: null, mode: 0o666, autoClose: true } `options` can include `start` and `end` values to read a range of bytes from the file instead of the entire file. Both `start` and `end` are inclusive and start at 0. The `encoding` can be any one of those accepted by [`Buffer`][]. If `fd` is specified, `ReadStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. Note that `fd` should be blocking; non-blocking `fd`s should be passed to [`net.Socket`][]. If `autoClose` is false, then the file descriptor won't be closed, even if there's an error. It is your responsibility to close it and make sure there's no file descriptor leak. If `autoClose` is set to true (default behavior), on `error` or `end` the file descriptor will be closed automatically. `mode` sets the file mode (permission and sticky bits), but only if the file was created. An example to read the last 10 bytes of a file which is 100 bytes long: fs.createReadStream('sample.txt', {start: 90, end: 99}); If `options` is a string, then it specifies the encoding. ## fs.createWriteStream(path[, options]) Returns a new [`WriteStream`][] object. (See [Writable Stream][]). `options` is an object or string with the following defaults: { flags: 'w', defaultEncoding: 'utf8', fd: null, mode: 0o666 } `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a `flags` mode of `r+` rather than the default mode `w`. The `defaultEncoding` can be any one of those accepted by [`Buffer`][]. Like [`ReadStream`][], if `fd` is specified, `WriteStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. Note that `fd` should be blocking; non-blocking `fd`s should be passed to [`net.Socket`][]. If `options` is a string, then it specifies the encoding. ## fs.exists(path, callback) Stability: 0 - Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead. Test whether or not the given path exists by checking with the file system. Then call the `callback` argument with either true or false. Example: fs.exists('/etc/passwd', (exists) => { console.log(exists ? 'it\'s there' : 'no passwd!'); }); `fs.exists()` should not be used to check if a file exists before calling `fs.open()`. Doing so introduces a race condition since other processes may change the file's state between the two calls. Instead, user code should call `fs.open()` directly and handle the error raised if the file is non-existent. ## fs.existsSync(path) Stability: 0 - Deprecated: Use [`fs.statSync()`][] or [`fs.accessSync()`][] instead. Synchronous version of [`fs.exists()`][]. Returns `true` if the file exists, `false` otherwise. ## fs.fchmod(fd, mode, callback) Asynchronous fchmod(2). No arguments other than a possible exception are given to the completion callback. ## fs.fchmodSync(fd, mode) Synchronous fchmod(2). Returns `undefined`. ## fs.fchown(fd, uid, gid, callback) Asynchronous fchown(2). No arguments other than a possible exception are given to the completion callback. ## fs.fchownSync(fd, uid, gid) Synchronous fchown(2). Returns `undefined`. ## fs.fstat(fd, callback) Asynchronous fstat(2). The callback gets two arguments `(err, stats)` where `stats` is a `fs.Stats` object. `fstat()` is identical to [`stat()`][], except that the file to be stat-ed is specified by the file descriptor `fd`. ## fs.fstatSync(fd) Synchronous fstat(2). Returns an instance of `fs.Stats`. ## fs.fsync(fd, callback) Asynchronous fsync(2). No arguments other than a possible exception are given to the completion callback. ## fs.fsyncSync(fd) Synchronous fsync(2). Returns `undefined`. ## fs.ftruncate(fd, len, callback) Asynchronous ftruncate(2). No arguments other than a possible exception are given to the completion callback. ## fs.ftruncateSync(fd, len) Synchronous ftruncate(2). Returns `undefined`. ## fs.futimes(fd, atime, mtime, callback) Change the file timestamps of a file referenced by the supplied file descriptor. ## fs.futimesSync(fd, atime, mtime) Synchronous version of [`fs.futimes()`][]. Returns `undefined`. ## fs.lchmod(path, mode, callback) Asynchronous lchmod(2). No arguments other than a possible exception are given to the completion callback. Only available on Mac OS X. ## fs.lchmodSync(path, mode) Synchronous lchmod(2). Returns `undefined`. ## fs.lchown(path, uid, gid, callback) Asynchronous lchown(2). No arguments other than a possible exception are given to the completion callback. ## fs.lchownSync(path, uid, gid) Synchronous lchown(2). Returns `undefined`. ## fs.link(srcpath, dstpath, callback) Asynchronous link(2). No arguments other than a possible exception are given to the completion callback. ## fs.linkSync(srcpath, dstpath) Synchronous link(2). Returns `undefined`. ## fs.lstat(path, callback) Asynchronous lstat(2). The callback gets two arguments `(err, stats)` where `stats` is a `fs.Stats` object. `lstat()` is identical to `stat()`, except that if `path` is a symbolic link, then the link itself is stat-ed, not the file that it refers to. ## fs.lstatSync(path) Synchronous lstat(2). Returns an instance of `fs.Stats`. ## fs.mkdir(path[, mode], callback) Asynchronous mkdir(2). No arguments other than a possible exception are given to the completion callback. `mode` defaults to `0o777`. ## fs.mkdirSync(path[, mode]) Synchronous mkdir(2). Returns `undefined`. ## fs.open(path, flags[, mode], callback) Asynchronous file open. See open(2). `flags` can be: * `'r'` - Open file for reading. An exception occurs if the file does not exist. * `'r+'` - Open file for reading and writing. An exception occurs if the file does not exist. * `'rs'` - Open file for reading in synchronous mode. Instructs the operating system to bypass the local file system cache. This is primarily useful for opening files on NFS mounts as it allows you to skip the potentially stale local cache. It has a very real impact on I/O performance so don't use this flag unless you need it. Note that this doesn't turn `fs.open()` into a synchronous blocking call. If that's what you want then you should be using `fs.openSync()` * `'rs+'` - Open file for reading and writing, telling the OS to open it synchronously. See notes for `'rs'` about using this with caution. * `'w'` - Open file for writing. The file is created (if it does not exist) or truncated (if it exists). * `'wx'` - Like `'w'` but fails if `path` exists. * `'w+'` - Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists). * `'wx+'` - Like `'w+'` but fails if `path` exists. * `'a'` - Open file for appending. The file is created if it does not exist. * `'ax'` - Like `'a'` but fails if `path` exists. * `'a+'` - Open file for reading and appending. The file is created if it does not exist. * `'ax+'` - Like `'a+'` but fails if `path` exists. `mode` sets the file mode (permission and sticky bits), but only if the file was created. It defaults to `0666`, readable and writeable. The callback gets two arguments `(err, fd)`. The exclusive flag `'x'` (`O_EXCL` flag in open(2)) ensures that `path` is newly created. On POSIX systems, `path` is considered to exist even if it is a symlink to a non-existent file. The exclusive flag may or may not work with network file systems. `flags` can also be a number as documented by open(2); commonly used constants are available from `require('constants')`. On Windows, flags are translated to their equivalent ones where applicable, e.g. `O_WRONLY` to `FILE_GENERIC_WRITE`, or `O_EXCL|O_CREAT` to `CREATE_NEW`, as accepted by CreateFileW. On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. ## fs.openSync(path, flags[, mode]) Synchronous version of [`fs.open()`][]. Returns an integer representing the file descriptor. ## fs.read(fd, buffer, offset, length, position, callback) Read data from the file specified by `fd`. `buffer` is the buffer that the data will be written to. `offset` is the offset in the buffer to start writing at. `length` is an integer specifying the number of bytes to read. `position` is an integer specifying where to begin reading from in the file. If `position` is `null`, data will be read from the current file position. The callback is given the three arguments, `(err, bytesRead, buffer)`. ## fs.readdir(path, callback) Asynchronous readdir(3). Reads the contents of a directory. The callback gets two arguments `(err, files)` where `files` is an array of the names of the files in the directory excluding `'.'` and `'..'`. ## fs.readdirSync(path) Synchronous readdir(3). Returns an array of filenames excluding `'.'` and `'..'`. ## fs.readFile(file[, options], callback) * `file` {String | Integer} filename or file descriptor * `options` {Object | String} * `encoding` {String | Null} default = `null` * `flag` {String} default = `'r'` * `callback` {Function} Asynchronously reads the entire contents of a file. Example: fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data); }); The callback is passed two arguments `(err, data)`, where `data` is the contents of the file. If no encoding is specified, then the raw buffer is returned. If `options` is a string, then it specifies the encoding. Example: fs.readFile('/etc/passwd', 'utf8', callback); Any specified file descriptor has to support reading. _Note: Specified file descriptors will not be closed automatically._ ## fs.readFileSync(file[, options]) Synchronous version of [`fs.readFile`][]. Returns the contents of the `file`. If the `encoding` option is specified then this function returns a string. Otherwise it returns a buffer. ## fs.readlink(path, callback) Asynchronous readlink(2). The callback gets two arguments `(err, linkString)`. ## fs.readlinkSync(path) Synchronous readlink(2). Returns the symbolic link's string value. ## fs.realpath(path[, cache], callback) Asynchronous realpath(2). The `callback` gets two arguments `(err, resolvedPath)`. May use `process.cwd` to resolve relative paths. `cache` is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional `fs.stat` calls for known real paths. Example: var cache = {'/etc':'/private/etc'}; fs.realpath('/etc/passwd', cache, (err, resolvedPath) => { if (err) throw err; console.log(resolvedPath); }); ## fs.readSync(fd, buffer, offset, length, position) Synchronous version of [`fs.read()`][]. Returns the number of `bytesRead`. ## fs.realpathSync(path[, cache]) Synchronous realpath(2). Returns the resolved path. `cache` is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional `fs.stat` calls for known real paths. ## fs.rename(oldPath, newPath, callback) Asynchronous rename(2). No arguments other than a possible exception are given to the completion callback. ## fs.renameSync(oldPath, newPath) Synchronous rename(2). Returns `undefined`. ## fs.rmdir(path, callback) Asynchronous rmdir(2). No arguments other than a possible exception are given to the completion callback. ## fs.rmdirSync(path) Synchronous rmdir(2). Returns `undefined`. ## fs.stat(path, callback) Asynchronous stat(2). The callback gets two arguments `(err, stats)` where `stats` is a [`fs.Stats`][] object. See the [`fs.Stats`][] section below for more information. ## fs.statSync(path) Synchronous stat(2). Returns an instance of [`fs.Stats`][]. ## fs.symlink(target, path[, type], callback) Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback. The `type` argument can be set to `'dir'`, `'file'`, or `'junction'` (default is `'file'`) and is only available on Windows (ignored on other platforms). Note that Windows junction points require the destination path to be absolute. When using `'junction'`, the `target` argument will automatically be normalized to absolute path. Here is an example below: fs.symlink('./foo', './new-port'); It would create a symlic link named with "new-port" that points to "foo". ## fs.symlinkSync(target, path[, type]) Synchronous symlink(2). Returns `undefined`. ## fs.truncate(path, len, callback) Asynchronous truncate(2). No arguments other than a possible exception are given to the completion callback. A file descriptor can also be passed as the first argument. In this case, `fs.ftruncate()` is called. ## fs.truncateSync(path, len) Synchronous truncate(2). Returns `undefined`. ## fs.unlink(path, callback) Asynchronous unlink(2). No arguments other than a possible exception are given to the completion callback. ## fs.unlinkSync(path) Synchronous unlink(2). Returns `undefined`. ## fs.unwatchFile(filename[, listener]) Stop watching for changes on `filename`. If `listener` is specified, only that particular listener is removed. Otherwise, *all* listeners are removed and you have effectively stopped watching `filename`. Calling `fs.unwatchFile()` with a filename that is not being watched is a no-op, not an error. _Note: [`fs.watch()`][] is more efficient than `fs.watchFile()` and `fs.unwatchFile()`. `fs.watch()` should be used instead of `fs.watchFile()` and `fs.unwatchFile()` when possible._ ## fs.utimes(path, atime, mtime, callback) Change file timestamps of the file referenced by the supplied path. Note: the arguments `atime` and `mtime` of the following related functions does follow the below rules: - If the value is a numberable string like `'123456789'`, the value would get converted to corresponding number. - If the value is `NaN` or `Infinity`, the value would get converted to `Date.now()`. ## fs.utimesSync(path, atime, mtime) Synchronous version of [`fs.utimes()`][]. Returns `undefined`. ## fs.watch(filename[, options][, listener]) Watch for changes on `filename`, where `filename` is either a file or a directory. The returned object is a [`fs.FSWatcher`][]. The second argument is optional. The `options` if provided should be an object. The supported boolean members are `persistent` and `recursive`. `persistent` indicates whether the process should continue to run as long as files are being watched. `recursive` indicates whether all subdirectories should be watched, or only the current directory. This applies when a directory is specified, and only on supported platforms (See Caveats below). The default is `{ persistent: true, recursive: false }`. The listener callback gets two arguments `(event, filename)`. `event` is either `'rename'` or `'change'`, and `filename` is the name of the file which triggered the event. ### Caveats The `fs.watch` API is not 100% consistent across platforms, and is unavailable in some situations. The recursive option is only supported on OS X and Windows. #### Availability This feature depends on the underlying operating system providing a way to be notified of filesystem changes. * On Linux systems, this uses `inotify`. * On BSD systems, this uses `kqueue`. * On OS X, this uses `kqueue` for files and 'FSEvents' for directories. * On SunOS systems (including Solaris and SmartOS), this uses `event ports`. * On Windows systems, this feature depends on `ReadDirectoryChangesW`. If the underlying functionality is not available for some reason, then `fs.watch` will not be able to function. For example, watching files or directories on network file systems (NFS, SMB, etc.) often doesn't work reliably or at all. You can still use `fs.watchFile`, which uses stat polling, but it is slower and less reliable. #### Filename Argument Providing `filename` argument in the callback is only supported on Linux and Windows. Even on supported platforms, `filename` is not always guaranteed to be provided. Therefore, don't assume that `filename` argument is always provided in the callback, and have some fallback logic if it is null. fs.watch('somedir', (event, filename) => { console.log(`event is: ${event}`); if (filename) { console.log(`filename provided: ${filename}`); } else { console.log('filename not provided'); } }); ## fs.watchFile(filename[, options], listener) Watch for changes on `filename`. The callback `listener` will be called each time the file is accessed. The `options` argument may be omitted. If provided, it should be an object. The `options` object may contain a boolean named `persistent` that indicates whether the process should continue to run as long as files are being watched. The `options` object may specify an `interval` property indicating how often the target should be polled in milliseconds. The default is `{ persistent: true, interval: 5007 }`. The `listener` gets two arguments the current stat object and the previous stat object: fs.watchFile('message.text', (curr, prev) => { console.log(`the current mtime is: ${curr.mtime}`); console.log(`the previous mtime was: ${prev.mtime}`); }); These stat objects are instances of `fs.Stat`. If you want to be notified when the file was modified, not just accessed, you need to compare `curr.mtime` and `prev.mtime`. _Note: when an `fs.watchFile` operation results in an `ENOENT` error, it will invoke the listener once, with all the fields zeroed (or, for dates, the Unix Epoch). In Windows, `blksize` and `blocks` fields will be `undefined`, instead of zero. If the file is created later on, the listener will be called again, with the latest stat objects. This is a change in functionality since v0.10._ _Note: [`fs.watch()`][] is more efficient than `fs.watchFile` and `fs.unwatchFile`. `fs.watch` should be used instead of `fs.watchFile` and `fs.unwatchFile` when possible._ ## fs.write(fd, buffer, offset, length[, position], callback) Write `buffer` to the file specified by `fd`. `offset` and `length` determine the part of the buffer to be written. `position` refers to the offset from the beginning of the file where this data should be written. If `typeof position !== 'number'`, the data will be written at the current position. See pwrite(2). The callback will be given three arguments `(err, written, buffer)` where `written` specifies how many _bytes_ were written from `buffer`. Note that it is unsafe to use `fs.write` multiple times on the same file without waiting for the callback. For this scenario, `fs.createWriteStream` is strongly recommended. On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. ## fs.write(fd, data[, position[, encoding]], callback) Write `data` to the file specified by `fd`. If `data` is not a Buffer instance then the value will be coerced to a string. `position` refers to the offset from the beginning of the file where this data should be written. If `typeof position !== 'number'` the data will be written at the current position. See pwrite(2). `encoding` is the expected string encoding. The callback will receive the arguments `(err, written, string)` where `written` specifies how many _bytes_ the passed string required to be written. Note that bytes written is not the same as string characters. See [`Buffer.byteLength`][]. Unlike when writing `buffer`, the entire string must be written. No substring may be specified. This is because the byte offset of the resulting data may not be the same as the string offset. Note that it is unsafe to use `fs.write` multiple times on the same file without waiting for the callback. For this scenario, `fs.createWriteStream` is strongly recommended. On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. ## fs.writeFile(file, data[, options], callback) * `file` {String | Integer} filename or file descriptor * `data` {String | Buffer} * `options` {Object | String} * `encoding` {String | Null} default = `'utf8'` * `mode` {Number} default = `0o666` * `flag` {String} default = `'w'` * `callback` {Function} Asynchronously writes data to a file, replacing the file if it already exists. `data` can be a string or a buffer. The `encoding` option is ignored if `data` is a buffer. It defaults to `'utf8'`. Example: fs.writeFile('message.txt', 'Hello Node.js', (err) => { if (err) throw err; console.log('It\'s saved!'); }); If `options` is a string, then it specifies the encoding. Example: fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback); Any specified file descriptor has to support writing. Note that it is unsafe to use `fs.writeFile` multiple times on the same file without waiting for the callback. For this scenario, `fs.createWriteStream` is strongly recommended. _Note: Specified file descriptors will not be closed automatically._ ## fs.writeFileSync(file, data[, options]) The synchronous version of [`fs.writeFile()`][]. Returns `undefined`. ## fs.writeSync(fd, buffer, offset, length[, position]) ## fs.writeSync(fd, data[, position[, encoding]]) Synchronous versions of [`fs.write()`][]. Returns the number of bytes written. [`Buffer.byteLength`]: buffer.html#buffer_class_method_buffer_bytelength_string_encoding [`Buffer`]: buffer.html#buffer_buffer [`fs.access()`]: #fs_fs_access_path_mode_callback [`fs.accessSync()`]: #fs_fs_accesssync_path_mode [`fs.appendFile()`]: fs.html#fs_fs_appendfile_file_data_options_callback [`fs.exists()`]: fs.html#fs_fs_exists_path_callback [`fs.fstat()`]: #fs_fs_fstat_fd_callback [`fs.FSWatcher`]: #fs_class_fs_fswatcher [`fs.futimes()`]: #fs_fs_futimes_fd_atime_mtime_callback [`fs.lstat()`]: #fs_fs_lstat_path_callback [`fs.open()`]: #fs_fs_open_path_flags_mode_callback [`fs.read()`]: #fs_fs_read_fd_buffer_offset_length_position_callback [`fs.readFile`]: #fs_fs_readfile_file_options_callback [`fs.stat()`]: #fs_fs_stat_path_callback [`fs.Stats`]: #fs_class_fs_stats [`fs.statSync()`]: #fs_fs_statsync_path [`fs.utimes()`]: #fs_fs_futimes_fd_atime_mtime_callback [`fs.watch()`]: #fs_fs_watch_filename_options_listener [`fs.write()`]: #fs_fs_write_fd_buffer_offset_length_position_callback [`fs.writeFile()`]: #fs_fs_writefile_file_data_options_callback [`net.Socket`]: net.html#net_class_net_socket [`ReadStream`]: #fs_class_fs_readstream [`stat()`]: fs.html#fs_fs_stat_path_callback [`util.inspect(stats)`]: util.html#util_util_inspect_object_options [`WriteStream`]: #fs_class_fs_writestream [MDN-Date-getTime]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime [MDN-Date]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date [Readable Stream]: stream.html#stream_class_stream_readable [Writable Stream]: stream.html#stream_class_stream_writable node-v4.2.6/doc/api/globals.html000644 000766 000024 00000030157 12650222331 016577 0ustar00iojsstaff000000 000000 Global Objects Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Global Objects#

These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted.

Class: Buffer#

  • {Function}

Used to handle binary data. See the buffer section.

__dirname#

  • {String}

The name of the directory that the currently executing script resides in.

Example: running node example.js from /Users/mjr

console.log(__dirname);
// /Users/mjr

__dirname isn't actually a global but rather local to each module.

__filename#

  • {String}

The filename of the code being executed. This is the resolved absolute path of this code file. For a main program this is not necessarily the same filename used in the command line. The value inside a module is the path to that module file.

Example: running node example.js from /Users/mjr

console.log(__filename);
// /Users/mjr/example.js

__filename isn't actually a global but rather local to each module.

clearInterval(t)#

Stop a timer that was previously created with setInterval(). The callback will not execute.

The timer functions are global variables. See the timers section.

clearTimeout(t)#

Stop a timer that was previously created with setTimeout(). The callback will not execute.

console#

  • {Object}

Used to print to stdout and stderr. See the console section.

exports#

A reference to the module.exports that is shorter to type. See module system documentation for details on when to use exports and when to use module.exports.

exports isn't actually a global but rather local to each module.

See the module system documentation for more information.

global#

  • {Object} The global namespace object.

In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope var something will define a global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside an Node.js module will be local to that module.

module#

  • {Object}

A reference to the current module. In particular module.exports is used for defining what a module exports and makes available through require().

module isn't actually a global but rather local to each module.

See the module system documentation for more information.

process#

  • {Object}

The process object. See the process object section.

require()#

  • {Function}

To require modules. See the Modules section. require isn't actually a global but rather local to each module.

require.cache#

  • Object

Modules are cached in this object when they are required. By deleting a key value from this object, the next require will reload the module.

require.extensions#

Stability: 0 - Deprecated
  • Object

Instruct require on how to handle certain file extensions.

Process files with the extension .sjs as .js:

require.extensions['.sjs'] = require.extensions['.js'];

Deprecated In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time.

Since the Module system is locked, this feature will probably never go away. However, it may have subtle bugs and complexities that are best left untouched.

require.resolve()#

Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.

setInterval(cb, ms)#

Run callback cb repeatedly every ms milliseconds. Note that the actual interval may vary, depending on external factors like OS timer granularity and system load. It's never less than ms but it may be longer.

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

setTimeout(cb, ms)#

Run callback cb after at least ms milliseconds. The actual delay depends on external factors like OS timer granularity and system load.

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days.

Returns an opaque value that represents the timer.

node-v4.2.6/doc/api/globals.json000644 000766 000024 00000036406 12650222331 016607 0ustar00iojsstaff000000 000000 { "source": "doc/api/globals.markdown", "globals": [ { "textRaw": "Class: Buffer", "type": "global", "name": "Buffer", "desc": "

Used to handle binary data. See the [buffer section][].\n\n

\n" }, { "textRaw": "clearInterval(t)", "type": "global", "name": "clearInterval", "desc": "

Stop a timer that was previously created with [setInterval()][]. The callback\nwill not execute.\n\n

\n

The timer functions are global variables. See the [timers][] section.\n\n

\n" }, { "textRaw": "console", "name": "console", "type": "global", "desc": "

Used to print to stdout and stderr. See the [console][] section.\n\n

\n" }, { "textRaw": "global", "name": "global", "type": "global", "desc": "

In browsers, the top-level scope is the global scope. That means that in\nbrowsers if you're in the global scope var something will define a global\nvariable. In Node.js this is different. The top-level scope is not the global\nscope; var something inside an Node.js module will be local to that module.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object. See the [process object][] section.\n\n

\n" } ], "vars": [ { "textRaw": "__dirname", "name": "__dirname", "type": "var", "desc": "

The name of the directory that the currently executing script resides in.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__dirname);\n// /Users/mjr
\n

__dirname isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "__filename", "name": "__filename", "type": "var", "desc": "

The filename of the code being executed. This is the resolved absolute path\nof this code file. For a main program this is not necessarily the same\nfilename used in the command line. The value inside a module is the path\nto that module file.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__filename);\n// /Users/mjr/example.js
\n

__filename isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "exports", "name": "exports", "type": "var", "desc": "

A reference to the module.exports that is shorter to type.\nSee [module system documentation][] for details on when to use exports and\nwhen to use module.exports.\n\n

\n

exports isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "module", "name": "module", "type": "var", "desc": "

A reference to the current module. In particular\nmodule.exports is used for defining what a module exports and makes\navailable through require().\n\n

\n

module isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "require()", "type": "var", "name": "require", "desc": "

To require modules. See the [Modules][] section. require isn't actually a\nglobal but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`cache` {Object} ", "name": "cache", "desc": "

Modules are cached in this object when they are required. By deleting a key\nvalue from this object, the next require will reload the module.\n\n

\n" }, { "textRaw": "`extensions` {Object} ", "name": "extensions", "stability": 0, "stabilityText": "Deprecated", "desc": "

Instruct require on how to handle certain file extensions.\n\n

\n

Process files with the extension .sjs as .js:\n\n

\n
require.extensions['.sjs'] = require.extensions['.js'];
\n

Deprecated In the past, this list has been used to load\nnon-JavaScript modules into Node.js by compiling them on-demand.\nHowever, in practice, there are much better ways to do this, such as\nloading modules via some other Node.js program, or compiling them to\nJavaScript ahead of time.\n\n

\n

Since the Module system is locked, this feature will probably never go\naway. However, it may have subtle bugs and complexities that are best\nleft untouched.\n\n

\n" } ], "methods": [ { "textRaw": "require.resolve()", "type": "method", "name": "resolve", "desc": "

Use the internal require() machinery to look up the location of a module,\nbut rather than loading the module, just return the resolved filename.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "clearTimeout(t)", "type": "method", "name": "clearTimeout", "desc": "

Stop a timer that was previously created with [setTimeout()][]. The callback will\nnot execute.\n\n

\n", "signatures": [ { "params": [ { "name": "t" } ] } ] }, { "textRaw": "setInterval(cb, ms)", "type": "method", "name": "setInterval", "desc": "

Run callback cb repeatedly every ms milliseconds. Note that the actual\ninterval may vary, depending on external factors like OS timer granularity and\nsystem load. It's never less than ms but it may be longer.\n\n

\n

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] }, { "textRaw": "setTimeout(cb, ms)", "type": "method", "name": "setTimeout", "desc": "

Run callback cb after at least ms milliseconds. The actual delay depends\non external factors like OS timer granularity and system load.\n\n

\n

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] } ], "miscs": [ { "textRaw": "Global Objects", "name": "Global Objects", "type": "misc", "desc": "

These objects are available in all modules. Some of these objects aren't\nactually in the global scope but in the module scope - this will be noted.\n\n

\n", "globals": [ { "textRaw": "Class: Buffer", "type": "global", "name": "Buffer", "desc": "

Used to handle binary data. See the [buffer section][].\n\n

\n" }, { "textRaw": "clearInterval(t)", "type": "global", "name": "clearInterval", "desc": "

Stop a timer that was previously created with [setInterval()][]. The callback\nwill not execute.\n\n

\n

The timer functions are global variables. See the [timers][] section.\n\n

\n" }, { "textRaw": "console", "name": "console", "type": "global", "desc": "

Used to print to stdout and stderr. See the [console][] section.\n\n

\n" }, { "textRaw": "global", "name": "global", "type": "global", "desc": "

In browsers, the top-level scope is the global scope. That means that in\nbrowsers if you're in the global scope var something will define a global\nvariable. In Node.js this is different. The top-level scope is not the global\nscope; var something inside an Node.js module will be local to that module.\n\n

\n" }, { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object. See the [process object][] section.\n\n

\n" } ], "vars": [ { "textRaw": "__dirname", "name": "__dirname", "type": "var", "desc": "

The name of the directory that the currently executing script resides in.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__dirname);\n// /Users/mjr
\n

__dirname isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "__filename", "name": "__filename", "type": "var", "desc": "

The filename of the code being executed. This is the resolved absolute path\nof this code file. For a main program this is not necessarily the same\nfilename used in the command line. The value inside a module is the path\nto that module file.\n\n

\n

Example: running node example.js from /Users/mjr\n\n

\n
console.log(__filename);\n// /Users/mjr/example.js
\n

__filename isn't actually a global but rather local to each module.\n\n

\n" }, { "textRaw": "exports", "name": "exports", "type": "var", "desc": "

A reference to the module.exports that is shorter to type.\nSee [module system documentation][] for details on when to use exports and\nwhen to use module.exports.\n\n

\n

exports isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "module", "name": "module", "type": "var", "desc": "

A reference to the current module. In particular\nmodule.exports is used for defining what a module exports and makes\navailable through require().\n\n

\n

module isn't actually a global but rather local to each module.\n\n

\n

See the [module system documentation][] for more information.\n\n

\n" }, { "textRaw": "require()", "type": "var", "name": "require", "desc": "

To require modules. See the [Modules][] section. require isn't actually a\nglobal but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`cache` {Object} ", "name": "cache", "desc": "

Modules are cached in this object when they are required. By deleting a key\nvalue from this object, the next require will reload the module.\n\n

\n" }, { "textRaw": "`extensions` {Object} ", "name": "extensions", "stability": 0, "stabilityText": "Deprecated", "desc": "

Instruct require on how to handle certain file extensions.\n\n

\n

Process files with the extension .sjs as .js:\n\n

\n
require.extensions['.sjs'] = require.extensions['.js'];
\n

Deprecated In the past, this list has been used to load\nnon-JavaScript modules into Node.js by compiling them on-demand.\nHowever, in practice, there are much better ways to do this, such as\nloading modules via some other Node.js program, or compiling them to\nJavaScript ahead of time.\n\n

\n

Since the Module system is locked, this feature will probably never go\naway. However, it may have subtle bugs and complexities that are best\nleft untouched.\n\n

\n" } ], "methods": [ { "textRaw": "require.resolve()", "type": "method", "name": "resolve", "desc": "

Use the internal require() machinery to look up the location of a module,\nbut rather than loading the module, just return the resolved filename.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "clearTimeout(t)", "type": "method", "name": "clearTimeout", "desc": "

Stop a timer that was previously created with [setTimeout()][]. The callback will\nnot execute.\n\n

\n", "signatures": [ { "params": [ { "name": "t" } ] } ] }, { "textRaw": "setInterval(cb, ms)", "type": "method", "name": "setInterval", "desc": "

Run callback cb repeatedly every ms milliseconds. Note that the actual\ninterval may vary, depending on external factors like OS timer granularity and\nsystem load. It's never less than ms but it may be longer.\n\n

\n

The interval must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] }, { "textRaw": "setTimeout(cb, ms)", "type": "method", "name": "setTimeout", "desc": "

Run callback cb after at least ms milliseconds. The actual delay depends\non external factors like OS timer granularity and system load.\n\n

\n

The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is\noutside that range, it's changed to 1 millisecond. Broadly speaking, a timer\ncannot span more than 24.8 days.\n\n

\n

Returns an opaque value that represents the timer.\n\n

\n", "signatures": [ { "params": [ { "name": "cb" }, { "name": "ms" } ] } ] } ] } ] } node-v4.2.6/doc/api/globals.markdown000644 000766 000024 00000011660 12650222326 017457 0ustar00iojsstaff000000 000000 # Global Objects These objects are available in all modules. Some of these objects aren't actually in the global scope but in the module scope - this will be noted. ## Class: Buffer * {Function} Used to handle binary data. See the [buffer section][]. ## __dirname * {String} The name of the directory that the currently executing script resides in. Example: running `node example.js` from `/Users/mjr` console.log(__dirname); // /Users/mjr `__dirname` isn't actually a global but rather local to each module. ## __filename * {String} The filename of the code being executed. This is the resolved absolute path of this code file. For a main program this is not necessarily the same filename used in the command line. The value inside a module is the path to that module file. Example: running `node example.js` from `/Users/mjr` console.log(__filename); // /Users/mjr/example.js `__filename` isn't actually a global but rather local to each module. ## clearInterval(t) Stop a timer that was previously created with [`setInterval()`][]. The callback will not execute. The timer functions are global variables. See the [timers][] section. ## clearTimeout(t) Stop a timer that was previously created with [`setTimeout()`][]. The callback will not execute. ## console * {Object} Used to print to stdout and stderr. See the [`console`][] section. ## exports A reference to the `module.exports` that is shorter to type. See [module system documentation][] for details on when to use `exports` and when to use `module.exports`. `exports` isn't actually a global but rather local to each module. See the [module system documentation][] for more information. ## global * {Object} The global namespace object. In browsers, the top-level scope is the global scope. That means that in browsers if you're in the global scope `var something` will define a global variable. In Node.js this is different. The top-level scope is not the global scope; `var something` inside an Node.js module will be local to that module. ## module * {Object} A reference to the current module. In particular `module.exports` is used for defining what a module exports and makes available through `require()`. `module` isn't actually a global but rather local to each module. See the [module system documentation][] for more information. ## process * {Object} The process object. See the [`process` object][] section. ## require() * {Function} To require modules. See the [Modules][] section. `require` isn't actually a global but rather local to each module. ### require.cache * {Object} Modules are cached in this object when they are required. By deleting a key value from this object, the next `require` will reload the module. ### require.extensions Stability: 0 - Deprecated * {Object} Instruct `require` on how to handle certain file extensions. Process files with the extension `.sjs` as `.js`: require.extensions['.sjs'] = require.extensions['.js']; **Deprecated** In the past, this list has been used to load non-JavaScript modules into Node.js by compiling them on-demand. However, in practice, there are much better ways to do this, such as loading modules via some other Node.js program, or compiling them to JavaScript ahead of time. Since the Module system is locked, this feature will probably never go away. However, it may have subtle bugs and complexities that are best left untouched. ### require.resolve() Use the internal `require()` machinery to look up the location of a module, but rather than loading the module, just return the resolved filename. ## setInterval(cb, ms) Run callback `cb` repeatedly every `ms` milliseconds. Note that the actual interval may vary, depending on external factors like OS timer granularity and system load. It's never less than `ms` but it may be longer. The interval must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days. Returns an opaque value that represents the timer. ## setTimeout(cb, ms) Run callback `cb` after *at least* `ms` milliseconds. The actual delay depends on external factors like OS timer granularity and system load. The timeout must be in the range of 1-2,147,483,647 inclusive. If the value is outside that range, it's changed to 1 millisecond. Broadly speaking, a timer cannot span more than 24.8 days. Returns an opaque value that represents the timer. [`console`]: console.html [`process` object]: process.html#process_process [`setInterval()`]: #globals_setinterval_cb_ms [`setTimeout()`]: #globals_settimeout_cb_ms [buffer section]: buffer.html [module system documentation]: modules.html [Modules]: modules.html#modules_modules [timers]: timers.html node-v4.2.6/doc/api/http.html000644 000766 000024 00000176446 12650222331 016147 0ustar00iojsstaff000000 000000 HTTP Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

HTTP#

Stability: 2 - Stable

To use the HTTP server and client one must require('http').

The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possibly chunk-encoded, messages. The interface is careful to never buffer entire requests or responses--the user is able to stream data.

HTTP message headers are represented by an object like this:

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }

Keys are lowercased. Values are not modified.

In order to support the full spectrum of possible HTTP applications, Node.js's HTTP API is very low-level. It deals with stream handling and message parsing only. It parses a message into headers and body but it does not parse the actual headers or the body.

See message.headers for details on how duplicate headers are handled.

The raw headers as they were received are retained in the rawHeaders property, which is an array of [key, value, key2, value2, ...]. For example, the previous message header object might have a rawHeaders list like the following:

[ 'ConTent-Length', '123456',
  'content-LENGTH', '123',
  'content-type', 'text/plain',
  'CONNECTION', 'keep-alive',
  'Host', 'mysite.com',
  'accepT', '*/*' ]

Class: http.Agent#

The HTTP Agent is used for pooling sockets used in HTTP client requests.

The HTTP Agent also defaults client requests to using Connection:keep-alive. If no pending HTTP requests are waiting on a socket to become free the socket is closed. This means that Node.js's pool has the benefit of keep-alive when under load but still does not require developers to manually close the HTTP clients using KeepAlive.

If you opt into using HTTP KeepAlive, you can create an Agent object with that flag set to true. (See the constructor options below.) Then, the Agent will keep unused sockets in a pool for later use. They will be explicitly marked so as to not keep the Node.js process running. However, it is still a good idea to explicitly destroy() KeepAlive agents when they are no longer in use, so that the Sockets will be shut down.

Sockets are removed from the agent's pool when the socket emits either a 'close' event or a special 'agentRemove' event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of:

http.get(options, (res) => {
  // Do stuff
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

Alternatively, you could just opt out of pooling entirely using agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // create a new agent just for this one request
}, (res) => {
  // Do stuff with response
})

new Agent([options])#

  • options Object Set of configurable options to set on the agent. Can have the following fields:
    • keepAlive Boolean Keep sockets around in a pool to be used by other requests in the future. Default = false
    • keepAliveMsecs Integer When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. Only relevant if keepAlive is set to true.
    • maxSockets Number Maximum number of sockets to allow per host. Default = Infinity.
    • maxFreeSockets Number Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256.

The default http.globalAgent that is used by http.request() has all of these values set to their respective defaults.

To configure any of them, you must create your own http.Agent object.

const http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.destroy()#

Destroy any sockets that are currently in use by the agent.

It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them.

agent.freeSockets#

An object which contains arrays of sockets currently awaiting use by the Agent when HTTP KeepAlive is used. Do not modify.

agent.getName(options)#

Get a unique name for a set of request options, to determine whether a connection can be reused. In the http agent, this returns host:port:localAddress. In the https agent, the name includes the CA, cert, ciphers, and other HTTPS/TLS-specific options that determine socket reusability.

agent.maxFreeSockets#

By default set to 256. For Agents supporting HTTP KeepAlive, this sets the maximum number of sockets that will be left open in the free state.

agent.maxSockets#

By default set to Infinity. Determines how many concurrent sockets the agent can have open per origin. Origin is either a 'host:port' or 'host:port:localAddress' combination.

agent.requests#

An object which contains queues of requests that have not yet been assigned to sockets. Do not modify.

agent.sockets#

An object which contains arrays of sockets currently in use by the Agent. Do not modify.

Class: http.ClientRequest#

This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued. The header is still mutable using the setHeader(name, value), getHeader(name), removeHeader(name) API. The actual header will be sent along with the first data chunk or when closing the connection.

To get the response, add a listener for 'response' to the request object. 'response' will be emitted from the request object when the response headers have been received. The 'response' event is executed with one argument which is an instance of http.IncomingMessage.

During the 'response' event, one can add listeners to the response object; particularly to listen for the 'data' event.

If no 'response' handler is added, then the response will be entirely discarded. However, if you add a 'response' event handler, then you must consume the data from the response object, either by calling response.read() whenever there is a 'readable' event, or by adding a 'data' handler, or by calling the .resume() method. Until the data is consumed, the 'end' event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error.

Note: Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not.

The request implements the Writable Stream interface. This is an EventEmitter with the following events:

Event: 'abort'#

function () { }

Emitted when the request has been aborted by the client. This event is only emitted on the first call to abort().

Event: 'connect'#

function (response, socket, head) { }

Emitted each time a server responds to a request with a CONNECT method. If this event isn't being listened for, clients receiving a CONNECT method will have their connections closed.

A client server pair that show you how to listen for the 'connect' event.

const http = require('http');
const net = require('net');
const url = require('url');

// Create an HTTP tunneling proxy
var proxy = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
proxy.on('connect', (req, cltSocket, head) => {
  // connect to an origin server
  var srvUrl = url.parse(`http://${req.url}`);
  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
    cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // make a request to a tunneling proxy
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80'
  };

  var req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});

Event: 'continue'#

function () { }

Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body.

Event: 'response'#

function (response) { }

Emitted when a response is received to this request. This event is emitted only once. The response argument will be an instance of http.IncomingMessage.

Options:

  • host: A domain name or IP address of the server to issue the request to.
  • port: Port of remote server.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath)

Event: 'socket'#

function (socket) { }

Emitted after a socket is assigned to this request.

Event: 'upgrade'#

function (response, socket, head) { }

Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed.

A client server pair that show you how to listen for the 'upgrade' event.

const http = require('http');

// Create an HTTP server
var srv = http.createServer( (req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
srv.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// now that server is running
srv.listen(1337, '127.0.0.1', () => {

  // make a request
  var options = {
    port: 1337,
    hostname: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

  var req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});

request.abort()#

Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed.

request.end([data][, encoding][, callback])#

Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. If the request is chunked, this will send the terminating '0\r\n\r\n'.

If data is specified, it is equivalent to calling response.write(data, encoding) followed by request.end(callback).

If callback is specified, it will be called when the request stream is finished.

request.flushHeaders()#

Flush the request headers.

For efficiency reasons, Node.js normally buffers the request headers until you call request.end() or write the first chunk of request data. It then tries hard to pack the request headers and data into a single TCP packet.

That's usually what you want (it saves a TCP round-trip) but not when the first data isn't sent until possibly much later. request.flushHeaders() lets you bypass the optimization and kickstart the request.

request.setNoDelay([noDelay])#

Once a socket is assigned to this request and is connected socket.setNoDelay() will be called.

request.setSocketKeepAlive([enable][, initialDelay])#

Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called.

request.setTimeout(timeout[, callback])#

Once a socket is assigned to this request and is connected socket.setTimeout() will be called.

  • timeout {Number} Milliseconds before a request is considered to be timed out.
  • callback {Function} Optional function to be called when a timeout occurs. Same as binding to the timeout event.

request.write(chunk[, encoding][, callback])#

Sends a chunk of the body. By calling this method many times, the user can stream a request body to a server--in that case it is suggested to use the ['Transfer-Encoding', 'chunked'] header line when creating the request.

The chunk argument should be a Buffer or a string.

The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.

The callback argument is optional and will be called when this chunk of data is flushed.

Returns request.

Class: http.Server#

This is an EventEmitter with the following events:

Event: 'checkContinue'#

function (request, response) { }

Emitted each time a request with an http Expect: 100-continue is received. If this event isn't listened for, the server will automatically respond with a 100 Continue as appropriate.

Handling this event involves calling response.writeContinue() if the client should continue to send the request body, or generating an appropriate HTTP response (e.g., 400 Bad Request) if the client should not continue to send the request body.

Note that when this event is emitted and handled, the 'request' event will not be emitted.

Event: 'clientError'#

function (exception, socket) { }

If a client connection emits an 'error' event, it will be forwarded here.

socket is the net.Socket object that the error originated from.

Event: 'close'#

function () { }

Emitted when the server closes.

Event: 'connect'#

function (request, socket, head) { }

Emitted each time a client requests a http CONNECT method. If this event isn't listened for, then clients requesting a CONNECT method will have their connections closed.

  • request is the arguments for the http request, as it is in the request event.
  • socket is the network socket between the server and client.
  • head is an instance of Buffer, the first packet of the tunneling stream, this may be empty.

After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket.

Event: 'connection'#

function (socket) { }

When a new TCP stream is established. socket is an object of type net.Socket. Usually users will not want to access this event. In particular, the socket will not emit 'readable' events because of how the protocol parser attaches to the socket. The socket can also be accessed at request.connection.

Event: 'request'#

function (request, response) { }

Emitted each time there is a request. Note that there may be multiple requests per connection (in the case of keep-alive connections). request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse.

Event: 'upgrade'#

function (request, socket, head) { }

Emitted each time a client requests a http upgrade. If this event isn't listened for, then clients requesting an upgrade will have their connections closed.

  • request is the arguments for the http request, as it is in the request event.
  • socket is the network socket between the server and client.
  • head is an instance of Buffer, the first packet of the upgraded stream, this may be empty.

After this event is emitted, the request's socket will not have a 'data' event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket.

server.close([callback])#

Stops the server from accepting new connections. See net.Server.close().

server.listen(handle[, callback])#

  • handle Object
  • callback Function

The handle object can be set to either a server or socket (anything with an underlying _handle member), or a {fd: <n>} object.

This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket.

Listening on a file descriptor is not supported on Windows.

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen().

Returns server.

server.listen(path[, callback])#

Start a UNIX socket server listening for connections on the given path.

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen(path).

server.listen(port[, hostname][, backlog][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

To listen to a unix socket, supply a filename instead of port and hostname.

Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. The default value of this parameter is 511 (not 512).

This function is asynchronous. The last parameter callback will be added as a listener for the 'listening' event. See also net.Server.listen(port).

server.maxHeadersCount#

Limits maximum incoming headers count, equal to 1000 by default. If set to 0 - no limit will be applied.

server.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Sets the timeout value for sockets, and emits a 'timeout' event on the Server object, passing the socket as an argument, if a timeout occurs.

If there is a 'timeout' event listener on the Server object, then it will be called with the timed-out socket as an argument.

By default, the Server's timeout value is 2 minutes, and sockets are destroyed automatically if they time out. However, if you assign a callback to the Server's 'timeout' event, then you are responsible for handling socket timeouts.

Returns server.

server.timeout#

  • Number Default = 120000 (2 minutes)

The number of milliseconds of inactivity before a socket is presumed to have timed out.

Note that the socket timeout logic is set up on connection, so changing this value only affects new connections to the server, not any existing connections.

Set to 0 to disable any kind of automatic timeout behavior on incoming connections.

Class: http.ServerResponse#

This object is created internally by a HTTP server--not by the user. It is passed as the second parameter to the 'request' event.

The response implements the Writable Stream interface. This is an EventEmitter with the following events:

Event: 'close'#

function () { }

Indicates that the underlying connection was terminated before response.end() was called or able to flush.

Event: 'finish'#

function () { }

Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet.

After this event, no more events will be emitted on the response object.

response.addTrailers(headers)#

This method adds HTTP trailing headers (a header but at the end of the message) to the response.

Trailers will only be emitted if chunked encoding is used for the response; if it is not (e.g., if the request was HTTP/1.0), they will be silently discarded.

Note that HTTP requires the Trailer header to be sent if you intend to emit trailers, with a list of the header fields in its value. E.g.,

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
response.end();

Attempting to set a trailer field name that contains invalid characters will result in a TypeError being thrown.

response.end([data][, encoding][, callback])#

This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, response.end(), MUST be called on each response.

If data is specified, it is equivalent to calling response.write(data, encoding) followed by response.end(callback).

If callback is specified, it will be called when the response stream is finished.

response.finished#

Boolean value that indicates whether the response has completed. Starts as false. After response.end() executes, the value will be true.

response.getHeader(name)#

Reads out a header that's already been queued but not sent to the client. Note that the name is case insensitive. This can only be called before headers get implicitly flushed.

Example:

var contentType = response.getHeader('content-type');

response.headersSent#

Boolean (read-only). True if headers were sent, false otherwise.

response.removeHeader(name)#

Removes a header that's queued for implicit sending.

Example:

response.removeHeader('Content-Encoding');

response.sendDate#

When true, the Date header will be automatically generated and sent in the response if it is not already present in the headers. Defaults to true.

This should only be disabled for testing; HTTP requires the Date header in responses.

response.setHeader(name, value)#

Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here if you need to send multiple headers with the same name.

Example:

response.setHeader('Content-Type', 'text/html');

or

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

Attempting to set a header field name that contains invalid characters will result in a TypeError being thrown.

response.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Sets the Socket's timeout value to msecs. If a callback is provided, then it is added as a listener on the 'timeout' event on the response object.

If no 'timeout' listener is added to the request, the response, or the server, then sockets are destroyed when they time out. If you assign a handler on the request, the response, or the server's 'timeout' events, then it is your responsibility to handle timed out sockets.

Returns response.

response.statusCode#

When using implicit headers (not calling response.writeHead() explicitly), this property controls the status code that will be sent to the client when the headers get flushed.

Example:

response.statusCode = 404;

After response header was sent to the client, this property indicates the status code which was sent out.

response.statusMessage#

When using implicit headers (not calling response.writeHead() explicitly), this property controls the status message that will be sent to the client when the headers get flushed. If this is left as undefined then the standard message for the status code will be used.

Example:

response.statusMessage = 'Not found';

After response header was sent to the client, this property indicates the status message which was sent out.

response.write(chunk[, encoding][, callback])#

If this method is called and response.writeHead() has not been called, it will switch to implicit header mode and flush the implicit headers.

This sends a chunk of the response body. This method may be called multiple times to provide successive parts of the body.

chunk can be a string or a buffer. If chunk is a string, the second parameter specifies how to encode it into a byte stream. By default the encoding is 'utf8'. The last parameter callback will be called when this chunk of data is flushed.

Note: This is the raw HTTP body and has nothing to do with higher-level multi-part body encodings that may be used.

The first time response.write() is called, it will send the buffered header information and the first body to the client. The second time response.write() is called, Node.js assumes you're going to be streaming data, and sends that separately. That is, the response is buffered up to the first chunk of body.

Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is free again.

response.writeContinue()#

Sends a HTTP/1.1 100 Continue message to the client, indicating that the request body should be sent. See the 'checkContinue' event on Server.

response.writeHead(statusCode[, statusMessage][, headers])#

Sends a response header to the request. The status code is a 3-digit HTTP status code, like 404. The last argument, headers, are the response headers. Optionally one can give a human-readable statusMessage as the second argument.

Example:

var body = 'hello world';
response.writeHead(200, {
  'Content-Length': body.length,
  'Content-Type': 'text/plain' });

This method must only be called once on a message and it must be called before response.end() is called.

If you call response.write() or response.end() before calling this, the implicit/mutable headers will be calculated and call this function for you.

Note that Content-Length is given in bytes not characters. The above example works because the string 'hello world' contains only single byte characters. If the body contains higher coded characters then Buffer.byteLength() should be used to determine the number of bytes in a given encoding. And Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not.

Class: http.IncomingMessage#

An IncomingMessage object is created by http.Server or http.ClientRequest and passed as the first argument to the 'request' and 'response' event respectively. It may be used to access response status, headers and data.

It implements the Readable Stream interface, as well as the following additional events, methods, and properties.

Event: 'close'#

function () { }

Indicates that the underlying connection was closed. Just like 'end', this event occurs only once per response.

message.headers#

The request/response headers object.

Key-value pairs of header names and values. Header names are lower-cased. Example:

// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers);

Duplicates in raw headers are handled in the following ways, depending on the header name:

  • Duplicates of age, authorization, content-length, content-type, etag, expires, from, host, if-modified-since, if-unmodified-since, last-modified, location, max-forwards, proxy-authorization, referer, retry-after, or user-agent are discarded.
  • set-cookie is always an array. Duplicates are added to the array.
  • For all other headers, the values are joined together with ', '.

message.httpVersion#

In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. Probably either '1.1' or '1.0'.

Also response.httpVersionMajor is the first integer and response.httpVersionMinor is the second.

message.method#

Only valid for request obtained from http.Server.

The request method as a string. Read only. Example: 'GET', 'DELETE'.

message.rawHeaders#

The raw request/response headers list exactly as they were received.

Note that the keys and values are in the same list. It is not a list of tuples. So, the even-numbered offsets are key values, and the odd-numbered offsets are the associated values.

Header names are not lowercased, and duplicates are not merged.

// Prints something like:
//
// [ 'user-agent',
//   'this is invalid because there can be only one',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);

message.rawTrailers#

The raw request/response trailer keys and values exactly as they were received. Only populated at the 'end' event.

message.setTimeout(msecs, callback)#

  • msecs Number
  • callback Function

Calls message.connection.setTimeout(msecs, callback).

Returns message.

message.statusCode#

Only valid for response obtained from http.ClientRequest.

The 3-digit HTTP response status code. E.G. 404.

message.statusMessage#

Only valid for response obtained from http.ClientRequest.

message.socket#

The net.Socket object associated with the connection.

With HTTPS support, use request.socket.getPeerCertificate() to obtain the client's authentication details.

The HTTP response status message (reason phrase). E.G. OK or Internal Server Error.

message.trailers#

The request/response trailers object. Only populated at the 'end' event.

message.url#

Only valid for request obtained from http.Server.

Request URL string. This contains only the URL that is present in the actual HTTP request. If the request is:

GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n

Then request.url will be:

'/status?name=ryan'

If you would like to parse the URL into its parts, you can use require('url').parse(request.url). Example:

node> require('url').parse('/status?name=ryan')
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status' }

If you would like to extract the params from the query string, you can use the require('querystring').parse function, or pass true as the second argument to require('url').parse. Example:

node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: { name: 'ryan' },
  pathname: '/status' }

http.METHODS#

  • Array

A list of the HTTP methods that are supported by the parser.

http.STATUS_CODES#

  • Object

A collection of all the standard HTTP response status codes, and the short description of each. For example, http.STATUS_CODES[404] === 'Not Found'.

http.createClient([port][, host])#

Stability: 0 - Deprecated: Use http.request() instead.

Constructs a new HTTP client. port and host refer to the server to be connected to.

http.createServer([requestListener])#

Returns a new instance of http.Server.

The requestListener is a function which is automatically added to the 'request' event.

http.get(options[, callback])#

Since most requests are GET requests without bodies, Node.js provides this convenience method. The only difference between this method and http.request() is that it sets the method to GET and calls req.end() automatically.

Example:

http.get('http://www.google.com/index.html', (res) => {
  console.log(`Got response: ${res.statusCode}`);
  // consume response body
  res.resume();
}).on('error', (e) => {
  console.log(`Got error: ${e.message}`);
});

http.globalAgent#

Global instance of Agent which is used as the default for all http client requests.

http.request(options[, callback])#

Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

Options:

  • protocol: Protocol to use. Defaults to 'http:'.
  • host: A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
  • hostname: Alias for host. To support url.parse() hostname is preferred over host.
  • family: IP address family to use when resolving host and hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.
  • port: Port of remote server. Defaults to 80.
  • localAddress: Local interface to bind for network connections.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • path: Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
  • headers: An object containing request headers.
  • auth: Basic authentication i.e. 'user:password' to compute an Authorization header.
  • agent: Controls Agent behavior. When an Agent is used request will default to Connection: keep-alive. Possible values:
    • undefined (default): use http.globalAgent for this host and port.
    • Agent object: explicitly use the passed in Agent.
    • false: opts out of connection pooling with an Agent, defaults request to Connection: close.

The optional callback parameter will be added as a one time listener for the 'response' event.

http.request() returns an instance of the http.ClientRequest class. The ClientRequest instance is a writable stream. If one needs to upload a file with a POST request, then write to the ClientRequest object.

Example:

var postData = querystring.stringify({
  'msg' : 'Hello World!'
});

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': postData.length
  }
};

var req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.')
  })
});

req.on('error', (e) => {
  console.log(`problem with request: ${e.message}`);
});

// write data to request body
req.write(postData);
req.end();

Note that in the example req.end() was called. With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.

If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an 'error' event is emitted on the returned request object. As with all 'error' events, if no listeners are registered the error will be thrown.

There are a few special headers that should be noted.

  • Sending a 'Connection: keep-alive' will notify Node.js that the connection to the server should be persisted until the next request.

  • Sending a 'Content-length' header will disable the default chunked encoding.

  • Sending an 'Expect' header will immediately send the request headers. Usually, when sending 'Expect: 100-continue', you should both set a timeout and listen for the 'continue' event. See RFC2616 Section 8.2.3 for more information.

  • Sending an Authorization header will override using the auth option to compute basic authentication.

node-v4.2.6/doc/api/http.json000644 000766 000024 00000204125 12650222331 016136 0ustar00iojsstaff000000 000000 { "source": "doc/api/http.markdown", "modules": [ { "textRaw": "HTTP", "name": "http", "stability": 2, "stabilityText": "Stable", "desc": "

To use the HTTP server and client one must require('http').\n\n

\n

The HTTP interfaces in Node.js are designed to support many features\nof the protocol which have been traditionally difficult to use.\nIn particular, large, possibly chunk-encoded, messages. The interface is\ncareful to never buffer entire requests or responses--the\nuser is able to stream data.\n\n

\n

HTTP message headers are represented by an object like this:\n\n

\n
{ 'content-length': '123',\n  'content-type': 'text/plain',\n  'connection': 'keep-alive',\n  'host': 'mysite.com',\n  'accept': '*/*' }
\n

Keys are lowercased. Values are not modified.\n\n

\n

In order to support the full spectrum of possible HTTP applications, Node.js's\nHTTP API is very low-level. It deals with stream handling and message\nparsing only. It parses a message into headers and body but it does not\nparse the actual headers or the body.\n\n

\n

See [message.headers][] for details on how duplicate headers are handled.\n\n

\n

The raw headers as they were received are retained in the rawHeaders\nproperty, which is an array of [key, value, key2, value2, ...]. For\nexample, the previous message header object might have a rawHeaders\nlist like the following:\n\n

\n
[ 'ConTent-Length', '123456',\n  'content-LENGTH', '123',\n  'content-type', 'text/plain',\n  'CONNECTION', 'keep-alive',\n  'Host', 'mysite.com',\n  'accepT', '*/*' ]
\n", "classes": [ { "textRaw": "Class: http.Agent", "type": "class", "name": "http.Agent", "desc": "

The HTTP Agent is used for pooling sockets used in HTTP client\nrequests.\n\n

\n

The HTTP Agent also defaults client requests to using\nConnection:keep-alive. If no pending HTTP requests are waiting on a\nsocket to become free the socket is closed. This means that Node.js's\npool has the benefit of keep-alive when under load but still does not\nrequire developers to manually close the HTTP clients using\nKeepAlive.\n\n

\n

If you opt into using HTTP KeepAlive, you can create an Agent object\nwith that flag set to true. (See the [constructor options][] below.)\nThen, the Agent will keep unused sockets in a pool for later use. They\nwill be explicitly marked so as to not keep the Node.js process running.\nHowever, it is still a good idea to explicitly [destroy()][] KeepAlive\nagents when they are no longer in use, so that the Sockets will be shut\ndown.\n\n

\n

Sockets are removed from the agent's pool when the socket emits either\na 'close' event or a special 'agentRemove' event. This means that if\nyou intend to keep one HTTP request open for a long time and don't\nwant it to stay in the pool you can do something along the lines of:\n\n

\n
http.get(options, (res) => {\n  // Do stuff\n}).on('socket', (socket) => {\n  socket.emit('agentRemove');\n});
\n

Alternatively, you could just opt out of pooling entirely using\nagent:false:\n\n

\n
http.get({\n  hostname: 'localhost',\n  port: 80,\n  path: '/',\n  agent: false  // create a new agent just for this one request\n}, (res) => {\n  // Do stuff with response\n})
\n", "methods": [ { "textRaw": "agent.destroy()", "type": "method", "name": "destroy", "desc": "

Destroy any sockets that are currently in use by the agent.\n\n

\n

It is usually not necessary to do this. However, if you are using an\nagent with KeepAlive enabled, then it is best to explicitly shut down\nthe agent when you know that it will no longer be used. Otherwise,\nsockets may hang open for quite a long time before the server\nterminates them.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "agent.getName(options)", "type": "method", "name": "getName", "desc": "

Get a unique name for a set of request options, to determine whether a\nconnection can be reused. In the http agent, this returns\nhost:port:localAddress. In the https agent, the name includes the\nCA, cert, ciphers, and other HTTPS/TLS-specific options that determine\nsocket reusability.\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] } ], "properties": [ { "textRaw": "agent.freeSockets", "name": "freeSockets", "desc": "

An object which contains arrays of sockets currently awaiting use by\nthe Agent when HTTP KeepAlive is used. Do not modify.\n\n

\n" }, { "textRaw": "agent.maxFreeSockets", "name": "maxFreeSockets", "desc": "

By default set to 256. For Agents supporting HTTP KeepAlive, this\nsets the maximum number of sockets that will be left open in the free\nstate.\n\n

\n" }, { "textRaw": "agent.maxSockets", "name": "maxSockets", "desc": "

By default set to Infinity. Determines how many concurrent sockets the agent\ncan have open per origin. Origin is either a 'host:port' or\n'host:port:localAddress' combination.\n\n

\n" }, { "textRaw": "agent.requests", "name": "requests", "desc": "

An object which contains queues of requests that have not yet been assigned to\nsockets. Do not modify.\n\n

\n" }, { "textRaw": "agent.sockets", "name": "sockets", "desc": "

An object which contains arrays of sockets currently in use by the\nAgent. Do not modify.\n\n

\n" } ], "signatures": [ { "params": [ { "textRaw": "`options` {Object} Set of configurable options to set on the agent. Can have the following fields: ", "options": [ { "textRaw": "`keepAlive` {Boolean} Keep sockets around in a pool to be used by other requests in the future. Default = `false` ", "name": "keepAlive", "type": "Boolean", "desc": "Keep sockets around in a pool to be used by other requests in the future. Default = `false`" }, { "textRaw": "`keepAliveMsecs` {Integer} When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = `1000`. Only relevant if `keepAlive` is set to `true`. ", "name": "keepAliveMsecs", "type": "Integer", "desc": "When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = `1000`. Only relevant if `keepAlive` is set to `true`." }, { "textRaw": "`maxSockets` {Number} Maximum number of sockets to allow per host. Default = `Infinity`. ", "name": "maxSockets", "type": "Number", "desc": "Maximum number of sockets to allow per host. Default = `Infinity`." }, { "textRaw": "`maxFreeSockets` {Number} Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`. Default = `256`. ", "name": "maxFreeSockets", "type": "Number", "desc": "Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`. Default = `256`." } ], "name": "options", "type": "Object", "desc": "Set of configurable options to set on the agent. Can have the following fields:", "optional": true } ], "desc": "

The default [http.globalAgent][] that is used by [http.request()][] has all\nof these values set to their respective defaults.\n\n

\n

To configure any of them, you must create your own [http.Agent][] object.\n\n

\n
const http = require('http');\nvar keepAliveAgent = new http.Agent({ keepAlive: true });\noptions.agent = keepAliveAgent;\nhttp.request(options, onResponseCallback);
\n" }, { "params": [ { "name": "options", "optional": true } ], "desc": "

The default [http.globalAgent][] that is used by [http.request()][] has all\nof these values set to their respective defaults.\n\n

\n

To configure any of them, you must create your own [http.Agent][] object.\n\n

\n
const http = require('http');\nvar keepAliveAgent = new http.Agent({ keepAlive: true });\noptions.agent = keepAliveAgent;\nhttp.request(options, onResponseCallback);
\n" } ] }, { "textRaw": "Class: http.ClientRequest", "type": "class", "name": "http.ClientRequest", "desc": "

This object is created internally and returned from [http.request()][]. It\nrepresents an in-progress request whose header has already been queued. The\nheader is still mutable using the setHeader(name, value), getHeader(name),\nremoveHeader(name) API. The actual header will be sent along with the first\ndata chunk or when closing the connection.\n\n

\n

To get the response, add a listener for 'response' to the request object.\n'response' will be emitted from the request object when the response\nheaders have been received. The 'response' event is executed with one\nargument which is an instance of [http.IncomingMessage][].\n\n

\n

During the 'response' event, one can add listeners to the\nresponse object; particularly to listen for the 'data' event.\n\n

\n

If no 'response' handler is added, then the response will be\nentirely discarded. However, if you add a 'response' event handler,\nthen you must consume the data from the response object, either by\ncalling response.read() whenever there is a 'readable' event, or\nby adding a 'data' handler, or by calling the .resume() method.\nUntil the data is consumed, the 'end' event will not fire. Also, until\nthe data is read it will consume memory that can eventually lead to a\n'process out of memory' error.\n\n

\n

Note: Node.js does not check whether Content-Length and the length of the body\nwhich has been transmitted are equal or not.\n\n

\n

The request implements the [Writable Stream][] interface. This is an\n[EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'abort'", "type": "event", "name": "abort", "desc": "

function () { }\n\n

\n

Emitted when the request has been aborted by the client. This event is only\nemitted on the first call to abort().\n\n

\n", "params": [] }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

function (response, socket, head) { }\n\n

\n

Emitted each time a server responds to a request with a CONNECT method. If this\nevent isn't being listened for, clients receiving a CONNECT method will have\ntheir connections closed.\n\n

\n

A client server pair that show you how to listen for the 'connect' event.\n\n

\n
const http = require('http');\nconst net = require('net');\nconst url = require('url');\n\n// Create an HTTP tunneling proxy\nvar proxy = http.createServer( (req, res) => {\n  res.writeHead(200, {'Content-Type': 'text/plain'});\n  res.end('okay');\n});\nproxy.on('connect', (req, cltSocket, head) => {\n  // connect to an origin server\n  var srvUrl = url.parse(`http://${req.url}`);\n  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {\n    cltSocket.write('HTTP/1.1 200 Connection Established\\r\\n' +\n                    'Proxy-agent: Node.js-Proxy\\r\\n' +\n                    '\\r\\n');\n    srvSocket.write(head);\n    srvSocket.pipe(cltSocket);\n    cltSocket.pipe(srvSocket);\n  });\n});\n\n// now that proxy is running\nproxy.listen(1337, '127.0.0.1', () => {\n\n  // make a request to a tunneling proxy\n  var options = {\n    port: 1337,\n    hostname: '127.0.0.1',\n    method: 'CONNECT',\n    path: 'www.google.com:80'\n  };\n\n  var req = http.request(options);\n  req.end();\n\n  req.on('connect', (res, socket, head) => {\n    console.log('got connected!');\n\n    // make a request over an HTTP tunnel\n    socket.write('GET / HTTP/1.1\\r\\n' +\n                 'Host: www.google.com:80\\r\\n' +\n                 'Connection: close\\r\\n' +\n                 '\\r\\n');\n    socket.on('data', (chunk) => {\n      console.log(chunk.toString());\n    });\n    socket.on('end', () => {\n      proxy.close();\n    });\n  });\n});
\n", "params": [] }, { "textRaw": "Event: 'continue'", "type": "event", "name": "continue", "desc": "

function () { }\n\n

\n

Emitted when the server sends a '100 Continue' HTTP response, usually because\nthe request contained 'Expect: 100-continue'. This is an instruction that\nthe client should send the request body.\n\n

\n", "params": [] }, { "textRaw": "Event: 'response'", "type": "event", "name": "response", "desc": "

function (response) { }\n\n

\n

Emitted when a response is received to this request. This event is emitted only\nonce. The response argument will be an instance of [http.IncomingMessage][].\n\n

\n

Options:\n\n

\n
    \n
  • host: A domain name or IP address of the server to issue the request to.
  • \n
  • port: Port of remote server.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath)
  • \n
\n", "params": [] }, { "textRaw": "Event: 'socket'", "type": "event", "name": "socket", "desc": "

function (socket) { }\n\n

\n

Emitted after a socket is assigned to this request.\n\n

\n", "params": [] }, { "textRaw": "Event: 'upgrade'", "type": "event", "name": "upgrade", "desc": "

function (response, socket, head) { }\n\n

\n

Emitted each time a server responds to a request with an upgrade. If this\nevent isn't being listened for, clients receiving an upgrade header will have\ntheir connections closed.\n\n

\n

A client server pair that show you how to listen for the 'upgrade' event.\n\n

\n
const http = require('http');\n\n// Create an HTTP server\nvar srv = http.createServer( (req, res) => {\n  res.writeHead(200, {'Content-Type': 'text/plain'});\n  res.end('okay');\n});\nsrv.on('upgrade', (req, socket, head) => {\n  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\\r\\n' +\n               'Upgrade: WebSocket\\r\\n' +\n               'Connection: Upgrade\\r\\n' +\n               '\\r\\n');\n\n  socket.pipe(socket); // echo back\n});\n\n// now that server is running\nsrv.listen(1337, '127.0.0.1', () => {\n\n  // make a request\n  var options = {\n    port: 1337,\n    hostname: '127.0.0.1',\n    headers: {\n      'Connection': 'Upgrade',\n      'Upgrade': 'websocket'\n    }\n  };\n\n  var req = http.request(options);\n  req.end();\n\n  req.on('upgrade', (res, socket, upgradeHead) => {\n    console.log('got upgraded!');\n    socket.end();\n    process.exit(0);\n  });\n});
\n", "params": [] } ], "methods": [ { "textRaw": "request.abort()", "type": "method", "name": "abort", "desc": "

Marks the request as aborting. Calling this will cause remaining data\nin the response to be dropped and the socket to be destroyed.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "request.end([data][, encoding][, callback])", "type": "method", "name": "end", "desc": "

Finishes sending the request. If any parts of the body are\nunsent, it will flush them to the stream. If the request is\nchunked, this will send the terminating '0\\r\\n\\r\\n'.\n\n

\n

If data is specified, it is equivalent to calling\n[response.write(data, encoding)][] followed by request.end(callback).\n\n

\n

If callback is specified, it will be called when the request stream\nis finished.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "request.flushHeaders()", "type": "method", "name": "flushHeaders", "desc": "

Flush the request headers.\n\n

\n

For efficiency reasons, Node.js normally buffers the request headers until you\ncall request.end() or write the first chunk of request data. It then tries\nhard to pack the request headers and data into a single TCP packet.\n\n

\n

That's usually what you want (it saves a TCP round-trip) but not when the first\ndata isn't sent until possibly much later. request.flushHeaders() lets you bypass\nthe optimization and kickstart the request.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "request.setNoDelay([noDelay])", "type": "method", "name": "setNoDelay", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setNoDelay()][] will be called.\n\n

\n", "signatures": [ { "params": [ { "name": "noDelay", "optional": true } ] } ] }, { "textRaw": "request.setSocketKeepAlive([enable][, initialDelay])", "type": "method", "name": "setSocketKeepAlive", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setKeepAlive()][] will be called.\n\n

\n", "signatures": [ { "params": [ { "name": "enable", "optional": true }, { "name": "initialDelay", "optional": true } ] } ] }, { "textRaw": "request.setTimeout(timeout[, callback])", "type": "method", "name": "setTimeout", "desc": "

Once a socket is assigned to this request and is connected\n[socket.setTimeout()][] will be called.\n\n

\n
    \n
  • timeout {Number} Milliseconds before a request is considered to be timed out.
  • \n
  • callback {Function} Optional function to be called when a timeout occurs. Same as binding to the timeout event.
  • \n
\n", "signatures": [ { "params": [ { "name": "timeout" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "request.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "desc": "

Sends a chunk of the body. By calling this method\nmany times, the user can stream a request body to a\nserver--in that case it is suggested to use the\n['Transfer-Encoding', 'chunked'] header line when\ncreating the request.\n\n

\n

The chunk argument should be a [Buffer][] or a string.\n\n

\n

The encoding argument is optional and only applies when chunk is a string.\nDefaults to 'utf8'.\n\n

\n

The callback argument is optional and will be called when this chunk of data\nis flushed.\n\n

\n

Returns request.\n\n

\n", "signatures": [ { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] } ] }, { "textRaw": "Class: http.Server", "type": "class", "name": "http.Server", "desc": "

This is an [EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'checkContinue'", "type": "event", "name": "checkContinue", "desc": "

function (request, response) { }\n\n

\n

Emitted each time a request with an http Expect: 100-continue is received.\nIf this event isn't listened for, the server will automatically respond\nwith a 100 Continue as appropriate.\n\n

\n

Handling this event involves calling [response.writeContinue()][] if the client\nshould continue to send the request body, or generating an appropriate HTTP\nresponse (e.g., 400 Bad Request) if the client should not continue to send the\nrequest body.\n\n

\n

Note that when this event is emitted and handled, the 'request' event will\nnot be emitted.\n\n

\n", "params": [] }, { "textRaw": "Event: 'clientError'", "type": "event", "name": "clientError", "desc": "

function (exception, socket) { }\n\n

\n

If a client connection emits an 'error' event, it will be forwarded here.\n\n

\n

socket is the [net.Socket][] object that the error originated from.\n\n

\n", "params": [] }, { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Emitted when the server closes.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

function (request, socket, head) { }\n\n

\n

Emitted each time a client requests a http CONNECT method. If this event isn't\nlistened for, then clients requesting a CONNECT method will have their\nconnections closed.\n\n

\n
    \n
  • request is the arguments for the http request, as it is in the request\nevent.
  • \n
  • socket is the network socket between the server and client.
  • \n
  • head is an instance of Buffer, the first packet of the tunneling stream,\nthis may be empty.
  • \n
\n

After this event is emitted, the request's socket will not have a 'data'\nevent listener, meaning you will need to bind to it in order to handle data\nsent to the server on that socket.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connection'", "type": "event", "name": "connection", "desc": "

function (socket) { }\n\n

\n

When a new TCP stream is established. socket is an object of type\n[net.Socket][]. Usually users will not want to access this event. In\nparticular, the socket will not emit 'readable' events because of how\nthe protocol parser attaches to the socket. The socket can also be\naccessed at request.connection.\n\n

\n", "params": [] }, { "textRaw": "Event: 'request'", "type": "event", "name": "request", "desc": "

function (request, response) { }\n\n

\n

Emitted each time there is a request. Note that there may be multiple requests\nper connection (in the case of keep-alive connections).\n request is an instance of [http.IncomingMessage][] and response is\nan instance of [http.ServerResponse][].\n\n

\n", "params": [] }, { "textRaw": "Event: 'upgrade'", "type": "event", "name": "upgrade", "desc": "

function (request, socket, head) { }\n\n

\n

Emitted each time a client requests a http upgrade. If this event isn't\nlistened for, then clients requesting an upgrade will have their connections\nclosed.\n\n

\n
    \n
  • request is the arguments for the http request, as it is in the request\nevent.
  • \n
  • socket is the network socket between the server and client.
  • \n
  • head is an instance of Buffer, the first packet of the upgraded stream,\nthis may be empty.
  • \n
\n

After this event is emitted, the request's socket will not have a 'data'\nevent listener, meaning you will need to bind to it in order to handle data\nsent to the server on that socket.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections. See [net.Server.close()][].\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(handle[, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`handle` {Object} ", "name": "handle", "type": "Object" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "handle" }, { "name": "callback", "optional": true } ] } ], "desc": "

The handle object can be set to either a server or socket (anything\nwith an underlying _handle member), or a {fd: <n>} object.\n\n

\n

This will cause the server to accept connections on the specified\nhandle, but it is presumed that the file descriptor or handle has\nalready been bound to a port or domain socket.\n\n

\n

Listening on a file descriptor is not supported on Windows.\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen()][].\n\n

\n

Returns server.\n\n

\n" }, { "textRaw": "server.listen(path[, callback])", "type": "method", "name": "listen", "desc": "

Start a UNIX socket server listening for connections on the given path.\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen(path)][].\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(port[, hostname][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

To listen to a unix socket, supply a filename instead of port and hostname.\n\n

\n

Backlog is the maximum length of the queue of pending connections.\nThe actual length will be determined by your OS through sysctl settings such as\ntcp_max_syn_backlog and somaxconn on linux. The default value of this\nparameter is 511 (not 512).\n\n

\n

This function is asynchronous. The last parameter callback will be added as\na listener for the 'listening' event. See also [net.Server.listen(port)][].\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Sets the timeout value for sockets, and emits a 'timeout' event on\nthe Server object, passing the socket as an argument, if a timeout\noccurs.\n\n

\n

If there is a 'timeout' event listener on the Server object, then it\nwill be called with the timed-out socket as an argument.\n\n

\n

By default, the Server's timeout value is 2 minutes, and sockets are\ndestroyed automatically if they time out. However, if you assign a\ncallback to the Server's 'timeout' event, then you are responsible\nfor handling socket timeouts.\n\n

\n

Returns server.\n\n

\n" } ], "properties": [ { "textRaw": "server.maxHeadersCount", "name": "maxHeadersCount", "desc": "

Limits maximum incoming headers count, equal to 1000 by default. If set to 0 -\nno limit will be applied.\n\n

\n" }, { "textRaw": "`timeout` {Number} Default = 120000 (2 minutes) ", "name": "timeout", "desc": "

The number of milliseconds of inactivity before a socket is presumed\nto have timed out.\n\n

\n

Note that the socket timeout logic is set up on connection, so\nchanging this value only affects new connections to the server, not\nany existing connections.\n\n

\n

Set to 0 to disable any kind of automatic timeout behavior on incoming\nconnections.\n\n

\n", "shortDesc": "Default = 120000 (2 minutes)" } ] }, { "textRaw": "Class: http.ServerResponse", "type": "class", "name": "http.ServerResponse", "desc": "

This object is created internally by a HTTP server--not by the user. It is\npassed as the second parameter to the 'request' event.\n\n

\n

The response implements the [Writable Stream][] interface. This is an\n[EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Indicates that the underlying connection was terminated before\n[response.end()][] was called or able to flush.\n\n

\n", "params": [] }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

function () { }\n\n

\n

Emitted when the response has been sent. More specifically, this event is\nemitted when the last segment of the response headers and body have been\nhanded off to the operating system for transmission over the network. It\ndoes not imply that the client has received anything yet.\n\n

\n

After this event, no more events will be emitted on the response object.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "response.addTrailers(headers)", "type": "method", "name": "addTrailers", "desc": "

This method adds HTTP trailing headers (a header but at the end of the\nmessage) to the response.\n\n

\n

Trailers will only be emitted if chunked encoding is used for the\nresponse; if it is not (e.g., if the request was HTTP/1.0), they will\nbe silently discarded.\n\n

\n

Note that HTTP requires the Trailer header to be sent if you intend to\nemit trailers, with a list of the header fields in its value. E.g.,\n\n

\n
response.writeHead(200, { 'Content-Type': 'text/plain',\n                          'Trailer': 'Content-MD5' });\nresponse.write(fileData);\nresponse.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});\nresponse.end();
\n

Attempting to set a trailer field name that contains invalid characters will\nresult in a [TypeError][] being thrown.\n\n

\n", "signatures": [ { "params": [ { "name": "headers" } ] } ] }, { "textRaw": "response.end([data][, encoding][, callback])", "type": "method", "name": "end", "desc": "

This method signals to the server that all of the response headers and body\nhave been sent; that server should consider this message complete.\nThe method, response.end(), MUST be called on each response.\n\n

\n

If data is specified, it is equivalent to calling\n[response.write(data, encoding)][] followed by response.end(callback).\n\n

\n

If callback is specified, it will be called when the response stream\nis finished.\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "response.getHeader(name)", "type": "method", "name": "getHeader", "desc": "

Reads out a header that's already been queued but not sent to the client. Note\nthat the name is case insensitive. This can only be called before headers get\nimplicitly flushed.\n\n

\n

Example:\n\n

\n
var contentType = response.getHeader('content-type');
\n", "signatures": [ { "params": [ { "name": "name" } ] } ] }, { "textRaw": "response.removeHeader(name)", "type": "method", "name": "removeHeader", "desc": "

Removes a header that's queued for implicit sending.\n\n

\n

Example:\n\n

\n
response.removeHeader('Content-Encoding');
\n", "signatures": [ { "params": [ { "name": "name" } ] } ] }, { "textRaw": "response.setHeader(name, value)", "type": "method", "name": "setHeader", "desc": "

Sets a single header value for implicit headers. If this header already exists\nin the to-be-sent headers, its value will be replaced. Use an array of strings\nhere if you need to send multiple headers with the same name.\n\n

\n

Example:\n\n

\n
response.setHeader('Content-Type', 'text/html');
\n

or\n\n

\n
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
\n

Attempting to set a header field name that contains invalid characters will\nresult in a [TypeError][] being thrown.\n\n

\n", "signatures": [ { "params": [ { "name": "name" }, { "name": "value" } ] } ] }, { "textRaw": "response.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Sets the Socket's timeout value to msecs. If a callback is\nprovided, then it is added as a listener on the 'timeout' event on\nthe response object.\n\n

\n

If no 'timeout' listener is added to the request, the response, or\nthe server, then sockets are destroyed when they time out. If you\nassign a handler on the request, the response, or the server's\n'timeout' events, then it is your responsibility to handle timed out\nsockets.\n\n

\n

Returns response.\n\n

\n" }, { "textRaw": "response.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "desc": "

If this method is called and [response.writeHead()][] has not been called,\nit will switch to implicit header mode and flush the implicit headers.\n\n

\n

This sends a chunk of the response body. This method may\nbe called multiple times to provide successive parts of the body.\n\n

\n

chunk can be a string or a buffer. If chunk is a string,\nthe second parameter specifies how to encode it into a byte stream.\nBy default the encoding is 'utf8'. The last parameter callback\nwill be called when this chunk of data is flushed.\n\n

\n

Note: This is the raw HTTP body and has nothing to do with\nhigher-level multi-part body encodings that may be used.\n\n

\n

The first time [response.write()][] is called, it will send the buffered\nheader information and the first body to the client. The second time\n[response.write()][] is called, Node.js assumes you're going to be streaming\ndata, and sends that separately. That is, the response is buffered up to the\nfirst chunk of body.\n\n

\n

Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n'drain' will be emitted when the buffer is free again.\n\n

\n", "signatures": [ { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "response.writeContinue()", "type": "method", "name": "writeContinue", "desc": "

Sends a HTTP/1.1 100 Continue message to the client, indicating that\nthe request body should be sent. See the ['checkContinue'][] event on Server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "response.writeHead(statusCode[, statusMessage][, headers])", "type": "method", "name": "writeHead", "desc": "

Sends a response header to the request. The status code is a 3-digit HTTP\nstatus code, like 404. The last argument, headers, are the response headers.\nOptionally one can give a human-readable statusMessage as the second\nargument.\n\n

\n

Example:\n\n

\n
var body = 'hello world';\nresponse.writeHead(200, {\n  'Content-Length': body.length,\n  'Content-Type': 'text/plain' });
\n

This method must only be called once on a message and it must\nbe called before [response.end()][] is called.\n\n

\n

If you call [response.write()][] or [response.end()][] before calling this, the\nimplicit/mutable headers will be calculated and call this function for you.\n\n

\n

Note that Content-Length is given in bytes not characters. The above example\nworks because the string 'hello world' contains only single byte characters.\nIf the body contains higher coded characters then Buffer.byteLength()\nshould be used to determine the number of bytes in a given encoding.\nAnd Node.js does not check whether Content-Length and the length of the body\nwhich has been transmitted are equal or not.\n\n

\n", "signatures": [ { "params": [ { "name": "statusCode" }, { "name": "statusMessage", "optional": true }, { "name": "headers", "optional": true } ] } ] } ], "properties": [ { "textRaw": "response.finished", "name": "finished", "desc": "

Boolean value that indicates whether the response has completed. Starts\nas false. After [response.end()][] executes, the value will be true.\n\n

\n" }, { "textRaw": "response.headersSent", "name": "headersSent", "desc": "

Boolean (read-only). True if headers were sent, false otherwise.\n\n

\n" }, { "textRaw": "response.sendDate", "name": "sendDate", "desc": "

When true, the Date header will be automatically generated and sent in\nthe response if it is not already present in the headers. Defaults to true.\n\n

\n

This should only be disabled for testing; HTTP requires the Date header\nin responses.\n\n

\n" }, { "textRaw": "response.statusCode", "name": "statusCode", "desc": "

When using implicit headers (not calling [response.writeHead()][] explicitly),\nthis property controls the status code that will be sent to the client when\nthe headers get flushed.\n\n

\n

Example:\n\n

\n
response.statusCode = 404;
\n

After response header was sent to the client, this property indicates the\nstatus code which was sent out.\n\n

\n" }, { "textRaw": "response.statusMessage", "name": "statusMessage", "desc": "

When using implicit headers (not calling [response.writeHead()][] explicitly), this property\ncontrols the status message that will be sent to the client when the headers get\nflushed. If this is left as undefined then the standard message for the status\ncode will be used.\n\n

\n

Example:\n\n

\n
response.statusMessage = 'Not found';
\n

After response header was sent to the client, this property indicates the\nstatus message which was sent out.\n\n

\n" } ] }, { "textRaw": "Class: http.IncomingMessage", "type": "class", "name": "http.IncomingMessage", "desc": "

An IncomingMessage object is created by [http.Server][] or\n[http.ClientRequest][] and passed as the first argument to the 'request'\nand 'response' event respectively. It may be used to access response status,\nheaders and data.\n\n

\n

It implements the [Readable Stream][] interface, as well as the\nfollowing additional events, methods, and properties.\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () { }\n\n

\n

Indicates that the underlying connection was closed.\nJust like 'end', this event occurs only once per response.\n\n

\n", "params": [] } ], "properties": [ { "textRaw": "message.headers", "name": "headers", "desc": "

The request/response headers object.\n\n

\n

Key-value pairs of header names and values. Header names are lower-cased.\nExample:\n\n

\n
// Prints something like:\n//\n// { 'user-agent': 'curl/7.22.0',\n//   host: '127.0.0.1:8000',\n//   accept: '*/*' }\nconsole.log(request.headers);
\n

Duplicates in raw headers are handled in the following ways, depending on the\nheader name:\n\n

\n
    \n
  • Duplicates of age, authorization, content-length, content-type,\netag, expires, from, host, if-modified-since, if-unmodified-since,\nlast-modified, location, max-forwards, proxy-authorization, referer,\nretry-after, or user-agent are discarded.
  • \n
  • set-cookie is always an array. Duplicates are added to the array.
  • \n
  • For all other headers, the values are joined together with ', '.
  • \n
\n" }, { "textRaw": "message.httpVersion", "name": "httpVersion", "desc": "

In case of server request, the HTTP version sent by the client. In the case of\nclient response, the HTTP version of the connected-to server.\nProbably either '1.1' or '1.0'.\n\n

\n

Also response.httpVersionMajor is the first integer and\nresponse.httpVersionMinor is the second.\n\n

\n" }, { "textRaw": "message.method", "name": "method", "desc": "

Only valid for request obtained from [http.Server][].\n\n

\n

The request method as a string. Read only. Example:\n'GET', 'DELETE'.\n\n

\n" }, { "textRaw": "message.rawHeaders", "name": "rawHeaders", "desc": "

The raw request/response headers list exactly as they were received.\n\n

\n

Note that the keys and values are in the same list. It is not a\nlist of tuples. So, the even-numbered offsets are key values, and the\nodd-numbered offsets are the associated values.\n\n

\n

Header names are not lowercased, and duplicates are not merged.\n\n

\n
// Prints something like:\n//\n// [ 'user-agent',\n//   'this is invalid because there can be only one',\n//   'User-Agent',\n//   'curl/7.22.0',\n//   'Host',\n//   '127.0.0.1:8000',\n//   'ACCEPT',\n//   '*/*' ]\nconsole.log(request.rawHeaders);
\n" }, { "textRaw": "message.rawTrailers", "name": "rawTrailers", "desc": "

The raw request/response trailer keys and values exactly as they were\nreceived. Only populated at the 'end' event.\n\n

\n" }, { "textRaw": "message.statusCode", "name": "statusCode", "desc": "

Only valid for response obtained from [http.ClientRequest][].\n\n

\n

The 3-digit HTTP response status code. E.G. 404.\n\n

\n" }, { "textRaw": "message.statusMessage", "name": "statusMessage", "desc": "

Only valid for response obtained from [http.ClientRequest][].\n\n

\n" }, { "textRaw": "message.socket", "name": "socket", "desc": "

The [net.Socket][] object associated with the connection.\n\n

\n

With HTTPS support, use [request.socket.getPeerCertificate()][] to obtain the\nclient's authentication details.\n\n

\n

The HTTP response status message (reason phrase). E.G. OK or Internal Server Error.\n\n

\n" }, { "textRaw": "message.trailers", "name": "trailers", "desc": "

The request/response trailers object. Only populated at the 'end' event.\n\n

\n" }, { "textRaw": "message.url", "name": "url", "desc": "

Only valid for request obtained from [http.Server][].\n\n

\n

Request URL string. This contains only the URL that is\npresent in the actual HTTP request. If the request is:\n\n

\n
GET /status?name=ryan HTTP/1.1\\r\\n\nAccept: text/plain\\r\\n\n\\r\\n
\n

Then request.url will be:\n\n

\n
'/status?name=ryan'
\n

If you would like to parse the URL into its parts, you can use\nrequire('url').parse(request.url). Example:\n\n

\n
node> require('url').parse('/status?name=ryan')\n{ href: '/status?name=ryan',\n  search: '?name=ryan',\n  query: 'name=ryan',\n  pathname: '/status' }
\n

If you would like to extract the params from the query string,\nyou can use the require('querystring').parse function, or pass\ntrue as the second argument to require('url').parse. Example:\n\n

\n
node> require('url').parse('/status?name=ryan', true)\n{ href: '/status?name=ryan',\n  search: '?name=ryan',\n  query: { name: 'ryan' },\n  pathname: '/status' }
\n" } ], "methods": [ { "textRaw": "message.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "signatures": [ { "params": [ { "textRaw": "`msecs` {Number} ", "name": "msecs", "type": "Number" }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" } ] }, { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ], "desc": "

Calls message.connection.setTimeout(msecs, callback).\n\n

\n

Returns message.\n\n

\n" } ] } ], "properties": [ { "textRaw": "`METHODS` {Array} ", "name": "METHODS", "desc": "

A list of the HTTP methods that are supported by the parser.\n\n

\n" }, { "textRaw": "`STATUS_CODES` {Object} ", "name": "STATUS_CODES", "desc": "

A collection of all the standard HTTP response status codes, and the\nshort description of each. For example, http.STATUS_CODES[404] === 'Not\nFound'.\n\n

\n" }, { "textRaw": "http.globalAgent", "name": "globalAgent", "desc": "

Global instance of Agent which is used as the default for all http client\nrequests.\n\n

\n" } ], "methods": [ { "textRaw": "http.createClient([port][, host])", "type": "method", "name": "createClient", "stability": 0, "stabilityText": "Deprecated: Use [`http.request()`][] instead.", "desc": "

Constructs a new HTTP client. port and host refer to the server to be\nconnected to.\n\n

\n", "signatures": [ { "params": [ { "name": "port", "optional": true }, { "name": "host", "optional": true } ] } ] }, { "textRaw": "http.createServer([requestListener])", "type": "method", "name": "createServer", "desc": "

Returns a new instance of [http.Server][].\n\n

\n

The requestListener is a function which is automatically\nadded to the 'request' event.\n\n

\n", "signatures": [ { "params": [ { "name": "requestListener", "optional": true } ] } ] }, { "textRaw": "http.get(options[, callback])", "type": "method", "name": "get", "desc": "

Since most requests are GET requests without bodies, Node.js provides this\nconvenience method. The only difference between this method and [http.request()][]\nis that it sets the method to GET and calls req.end() automatically.\n\n

\n

Example:\n\n

\n
http.get('http://www.google.com/index.html', (res) => {\n  console.log(`Got response: ${res.statusCode}`);\n  // consume response body\n  res.resume();\n}).on('error', (e) => {\n  console.log(`Got error: ${e.message}`);\n});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "http.request(options[, callback])", "type": "method", "name": "request", "desc": "

Node.js maintains several connections per server to make HTTP requests.\nThis function allows one to transparently issue requests.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

Options:\n\n

\n
    \n
  • protocol: Protocol to use. Defaults to 'http:'.
  • \n
  • host: A domain name or IP address of the server to issue the request to.\nDefaults to 'localhost'.
  • \n
  • hostname: Alias for host. To support [url.parse()][] hostname is\npreferred over host.
  • \n
  • family: IP address family to use when resolving host and hostname.\nValid values are 4 or 6. When unspecified, both IP v4 and v6 will be\nused.
  • \n
  • port: Port of remote server. Defaults to 80.
  • \n
  • localAddress: Local interface to bind for network connections.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • \n
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • \n
  • path: Request path. Defaults to '/'. Should include query string if any.\nE.G. '/index.html?page=12'. An exception is thrown when the request path\ncontains illegal characters. Currently, only spaces are rejected but that\nmay change in the future.
  • \n
  • headers: An object containing request headers.
  • \n
  • auth: Basic authentication i.e. 'user:password' to compute an\nAuthorization header.
  • \n
  • agent: Controls [Agent][] behavior. When an Agent is used request will\ndefault to Connection: keep-alive. Possible values:
      \n
    • undefined (default): use [http.globalAgent][] for this host and port.
    • \n
    • Agent object: explicitly use the passed in Agent.
    • \n
    • false: opts out of connection pooling with an Agent, defaults request to\nConnection: close.
    • \n
    \n
  • \n
\n

The optional callback parameter will be added as a one time listener for\nthe 'response' event.\n\n

\n

http.request() returns an instance of the [http.ClientRequest][]\nclass. The ClientRequest instance is a writable stream. If one needs to\nupload a file with a POST request, then write to the ClientRequest object.\n\n

\n

Example:\n\n

\n
var postData = querystring.stringify({\n  'msg' : 'Hello World!'\n});\n\nvar options = {\n  hostname: 'www.google.com',\n  port: 80,\n  path: '/upload',\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/x-www-form-urlencoded',\n    'Content-Length': postData.length\n  }\n};\n\nvar req = http.request(options, (res) => {\n  console.log(`STATUS: ${res.statusCode}`);\n  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);\n  res.setEncoding('utf8');\n  res.on('data', (chunk) => {\n    console.log(`BODY: ${chunk}`);\n  });\n  res.on('end', () => {\n    console.log('No more data in response.')\n  })\n});\n\nreq.on('error', (e) => {\n  console.log(`problem with request: ${e.message}`);\n});\n\n// write data to request body\nreq.write(postData);\nreq.end();
\n

Note that in the example req.end() was called. With http.request() one\nmust always call req.end() to signify that you're done with the request -\neven if there is no data being written to the request body.\n\n

\n

If any error is encountered during the request (be that with DNS resolution,\nTCP level errors, or actual HTTP parse errors) an 'error' event is emitted\non the returned request object. As with all 'error' events, if no listeners\nare registered the error will be thrown.\n\n

\n

There are a few special headers that should be noted.\n\n

\n
    \n
  • Sending a 'Connection: keep-alive' will notify Node.js that the connection to\nthe server should be persisted until the next request.

    \n
  • \n
  • Sending a 'Content-length' header will disable the default chunked encoding.

    \n
  • \n
  • Sending an 'Expect' header will immediately send the request headers.\nUsually, when sending 'Expect: 100-continue', you should both set a timeout\nand listen for the 'continue' event. See RFC2616 Section 8.2.3 for more\ninformation.

    \n
  • \n
  • Sending an Authorization header will override using the auth option\nto compute basic authentication.

    \n
  • \n
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] } ], "type": "module", "displayName": "HTTP" } ] } node-v4.2.6/doc/api/http.markdown000644 000766 000024 00000113365 12650222326 017020 0ustar00iojsstaff000000 000000 # HTTP Stability: 2 - Stable To use the HTTP server and client one must `require('http')`. The HTTP interfaces in Node.js are designed to support many features of the protocol which have been traditionally difficult to use. In particular, large, possibly chunk-encoded, messages. The interface is careful to never buffer entire requests or responses--the user is able to stream data. HTTP message headers are represented by an object like this: { 'content-length': '123', 'content-type': 'text/plain', 'connection': 'keep-alive', 'host': 'mysite.com', 'accept': '*/*' } Keys are lowercased. Values are not modified. In order to support the full spectrum of possible HTTP applications, Node.js's HTTP API is very low-level. It deals with stream handling and message parsing only. It parses a message into headers and body but it does not parse the actual headers or the body. See [`message.headers`][] for details on how duplicate headers are handled. The raw headers as they were received are retained in the `rawHeaders` property, which is an array of `[key, value, key2, value2, ...]`. For example, the previous message header object might have a `rawHeaders` list like the following: [ 'ConTent-Length', '123456', 'content-LENGTH', '123', 'content-type', 'text/plain', 'CONNECTION', 'keep-alive', 'Host', 'mysite.com', 'accepT', '*/*' ] ## Class: http.Agent The HTTP Agent is used for pooling sockets used in HTTP client requests. The HTTP Agent also defaults client requests to using Connection:keep-alive. If no pending HTTP requests are waiting on a socket to become free the socket is closed. This means that Node.js's pool has the benefit of keep-alive when under load but still does not require developers to manually close the HTTP clients using KeepAlive. If you opt into using HTTP KeepAlive, you can create an Agent object with that flag set to `true`. (See the [constructor options][] below.) Then, the Agent will keep unused sockets in a pool for later use. They will be explicitly marked so as to not keep the Node.js process running. However, it is still a good idea to explicitly [`destroy()`][] KeepAlive agents when they are no longer in use, so that the Sockets will be shut down. Sockets are removed from the agent's pool when the socket emits either a `'close'` event or a special `'agentRemove'` event. This means that if you intend to keep one HTTP request open for a long time and don't want it to stay in the pool you can do something along the lines of: http.get(options, (res) => { // Do stuff }).on('socket', (socket) => { socket.emit('agentRemove'); }); Alternatively, you could just opt out of pooling entirely using `agent:false`: http.get({ hostname: 'localhost', port: 80, path: '/', agent: false // create a new agent just for this one request }, (res) => { // Do stuff with response }) ### new Agent([options]) * `options` {Object} Set of configurable options to set on the agent. Can have the following fields: * `keepAlive` {Boolean} Keep sockets around in a pool to be used by other requests in the future. Default = `false` * `keepAliveMsecs` {Integer} When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = `1000`. Only relevant if `keepAlive` is set to `true`. * `maxSockets` {Number} Maximum number of sockets to allow per host. Default = `Infinity`. * `maxFreeSockets` {Number} Maximum number of sockets to leave open in a free state. Only relevant if `keepAlive` is set to `true`. Default = `256`. The default [`http.globalAgent`][] that is used by [`http.request()`][] has all of these values set to their respective defaults. To configure any of them, you must create your own [`http.Agent`][] object. ```javascript const http = require('http'); var keepAliveAgent = new http.Agent({ keepAlive: true }); options.agent = keepAliveAgent; http.request(options, onResponseCallback); ``` ### agent.destroy() Destroy any sockets that are currently in use by the agent. It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them. ### agent.freeSockets An object which contains arrays of sockets currently awaiting use by the Agent when HTTP KeepAlive is used. Do not modify. ### agent.getName(options) Get a unique name for a set of request options, to determine whether a connection can be reused. In the http agent, this returns `host:port:localAddress`. In the https agent, the name includes the CA, cert, ciphers, and other HTTPS/TLS-specific options that determine socket reusability. ### agent.maxFreeSockets By default set to 256. For Agents supporting HTTP KeepAlive, this sets the maximum number of sockets that will be left open in the free state. ### agent.maxSockets By default set to Infinity. Determines how many concurrent sockets the agent can have open per origin. Origin is either a 'host:port' or 'host:port:localAddress' combination. ### agent.requests An object which contains queues of requests that have not yet been assigned to sockets. Do not modify. ### agent.sockets An object which contains arrays of sockets currently in use by the Agent. Do not modify. ## Class: http.ClientRequest This object is created internally and returned from [`http.request()`][]. It represents an _in-progress_ request whose header has already been queued. The header is still mutable using the `setHeader(name, value)`, `getHeader(name)`, `removeHeader(name)` API. The actual header will be sent along with the first data chunk or when closing the connection. To get the response, add a listener for `'response'` to the request object. `'response'` will be emitted from the request object when the response headers have been received. The `'response'` event is executed with one argument which is an instance of [`http.IncomingMessage`][]. During the `'response'` event, one can add listeners to the response object; particularly to listen for the `'data'` event. If no `'response'` handler is added, then the response will be entirely discarded. However, if you add a `'response'` event handler, then you **must** consume the data from the response object, either by calling `response.read()` whenever there is a `'readable'` event, or by adding a `'data'` handler, or by calling the `.resume()` method. Until the data is consumed, the `'end'` event will not fire. Also, until the data is read it will consume memory that can eventually lead to a 'process out of memory' error. Note: Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not. The request implements the [Writable Stream][] interface. This is an [`EventEmitter`][] with the following events: ### Event: 'abort' `function () { }` Emitted when the request has been aborted by the client. This event is only emitted on the first call to `abort()`. ### Event: 'connect' `function (response, socket, head) { }` Emitted each time a server responds to a request with a `CONNECT` method. If this event isn't being listened for, clients receiving a `CONNECT` method will have their connections closed. A client server pair that show you how to listen for the `'connect'` event. const http = require('http'); const net = require('net'); const url = require('url'); // Create an HTTP tunneling proxy var proxy = http.createServer( (req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('okay'); }); proxy.on('connect', (req, cltSocket, head) => { // connect to an origin server var srvUrl = url.parse(`http://${req.url}`); var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => { cltSocket.write('HTTP/1.1 200 Connection Established\r\n' + 'Proxy-agent: Node.js-Proxy\r\n' + '\r\n'); srvSocket.write(head); srvSocket.pipe(cltSocket); cltSocket.pipe(srvSocket); }); }); // now that proxy is running proxy.listen(1337, '127.0.0.1', () => { // make a request to a tunneling proxy var options = { port: 1337, hostname: '127.0.0.1', method: 'CONNECT', path: 'www.google.com:80' }; var req = http.request(options); req.end(); req.on('connect', (res, socket, head) => { console.log('got connected!'); // make a request over an HTTP tunnel socket.write('GET / HTTP/1.1\r\n' + 'Host: www.google.com:80\r\n' + 'Connection: close\r\n' + '\r\n'); socket.on('data', (chunk) => { console.log(chunk.toString()); }); socket.on('end', () => { proxy.close(); }); }); }); ### Event: 'continue' `function () { }` Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body. ### Event: 'response' `function (response) { }` Emitted when a response is received to this request. This event is emitted only once. The `response` argument will be an instance of [`http.IncomingMessage`][]. Options: - `host`: A domain name or IP address of the server to issue the request to. - `port`: Port of remote server. - `socketPath`: Unix Domain Socket (use one of host:port or socketPath) ### Event: 'socket' `function (socket) { }` Emitted after a socket is assigned to this request. ### Event: 'upgrade' `function (response, socket, head) { }` Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed. A client server pair that show you how to listen for the `'upgrade'` event. const http = require('http'); // Create an HTTP server var srv = http.createServer( (req, res) => { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('okay'); }); srv.on('upgrade', (req, socket, head) => { socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 'Upgrade: WebSocket\r\n' + 'Connection: Upgrade\r\n' + '\r\n'); socket.pipe(socket); // echo back }); // now that server is running srv.listen(1337, '127.0.0.1', () => { // make a request var options = { port: 1337, hostname: '127.0.0.1', headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket' } }; var req = http.request(options); req.end(); req.on('upgrade', (res, socket, upgradeHead) => { console.log('got upgraded!'); socket.end(); process.exit(0); }); }); ### request.abort() Marks the request as aborting. Calling this will cause remaining data in the response to be dropped and the socket to be destroyed. ### request.end([data][, encoding][, callback]) Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. If the request is chunked, this will send the terminating `'0\r\n\r\n'`. If `data` is specified, it is equivalent to calling [`response.write(data, encoding)`][] followed by `request.end(callback)`. If `callback` is specified, it will be called when the request stream is finished. ### request.flushHeaders() Flush the request headers. For efficiency reasons, Node.js normally buffers the request headers until you call `request.end()` or write the first chunk of request data. It then tries hard to pack the request headers and data into a single TCP packet. That's usually what you want (it saves a TCP round-trip) but not when the first data isn't sent until possibly much later. `request.flushHeaders()` lets you bypass the optimization and kickstart the request. ### request.setNoDelay([noDelay]) Once a socket is assigned to this request and is connected [`socket.setNoDelay()`][] will be called. ### request.setSocketKeepAlive([enable][, initialDelay]) Once a socket is assigned to this request and is connected [`socket.setKeepAlive()`][] will be called. ### request.setTimeout(timeout[, callback]) Once a socket is assigned to this request and is connected [`socket.setTimeout()`][] will be called. * `timeout` {Number} Milliseconds before a request is considered to be timed out. * `callback` {Function} Optional function to be called when a timeout occurs. Same as binding to the `timeout` event. ### request.write(chunk[, encoding][, callback]) Sends a chunk of the body. By calling this method many times, the user can stream a request body to a server--in that case it is suggested to use the `['Transfer-Encoding', 'chunked']` header line when creating the request. The `chunk` argument should be a [`Buffer`][] or a string. The `encoding` argument is optional and only applies when `chunk` is a string. Defaults to `'utf8'`. The `callback` argument is optional and will be called when this chunk of data is flushed. Returns `request`. ## Class: http.Server This is an [`EventEmitter`][] with the following events: ### Event: 'checkContinue' `function (request, response) { }` Emitted each time a request with an http Expect: 100-continue is received. If this event isn't listened for, the server will automatically respond with a 100 Continue as appropriate. Handling this event involves calling [`response.writeContinue()`][] if the client should continue to send the request body, or generating an appropriate HTTP response (e.g., 400 Bad Request) if the client should not continue to send the request body. Note that when this event is emitted and handled, the `'request'` event will not be emitted. ### Event: 'clientError' `function (exception, socket) { }` If a client connection emits an `'error'` event, it will be forwarded here. `socket` is the [`net.Socket`][] object that the error originated from. ### Event: 'close' `function () { }` Emitted when the server closes. ### Event: 'connect' `function (request, socket, head) { }` Emitted each time a client requests a http `CONNECT` method. If this event isn't listened for, then clients requesting a `CONNECT` method will have their connections closed. * `request` is the arguments for the http request, as it is in the request event. * `socket` is the network socket between the server and client. * `head` is an instance of Buffer, the first packet of the tunneling stream, this may be empty. After this event is emitted, the request's socket will not have a `'data'` event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket. ### Event: 'connection' `function (socket) { }` When a new TCP stream is established. `socket` is an object of type [`net.Socket`][]. Usually users will not want to access this event. In particular, the socket will not emit `'readable'` events because of how the protocol parser attaches to the socket. The `socket` can also be accessed at `request.connection`. ### Event: 'request' `function (request, response) { }` Emitted each time there is a request. Note that there may be multiple requests per connection (in the case of keep-alive connections). `request` is an instance of [`http.IncomingMessage`][] and `response` is an instance of [`http.ServerResponse`][]. ### Event: 'upgrade' `function (request, socket, head) { }` Emitted each time a client requests a http upgrade. If this event isn't listened for, then clients requesting an upgrade will have their connections closed. * `request` is the arguments for the http request, as it is in the request event. * `socket` is the network socket between the server and client. * `head` is an instance of Buffer, the first packet of the upgraded stream, this may be empty. After this event is emitted, the request's socket will not have a `'data'` event listener, meaning you will need to bind to it in order to handle data sent to the server on that socket. ### server.close([callback]) Stops the server from accepting new connections. See [`net.Server.close()`][]. ### server.listen(handle[, callback]) * `handle` {Object} * `callback` {Function} The `handle` object can be set to either a server or socket (anything with an underlying `_handle` member), or a `{fd: }` object. This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket. Listening on a file descriptor is not supported on Windows. This function is asynchronous. The last parameter `callback` will be added as a listener for the `'listening'` event. See also [`net.Server.listen()`][]. Returns `server`. ### server.listen(path[, callback]) Start a UNIX socket server listening for connections on the given `path`. This function is asynchronous. The last parameter `callback` will be added as a listener for the `'listening'` event. See also [`net.Server.listen(path)`][]. ### server.listen(port[, hostname][, backlog][, callback]) Begin accepting connections on the specified `port` and `hostname`. If the `hostname` is omitted, the server will accept connections on any IPv6 address (`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. A port value of zero will assign a random port. To listen to a unix socket, supply a filename instead of port and hostname. Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on linux. The default value of this parameter is 511 (not 512). This function is asynchronous. The last parameter `callback` will be added as a listener for the `'listening'` event. See also [`net.Server.listen(port)`][]. ### server.maxHeadersCount Limits maximum incoming headers count, equal to 1000 by default. If set to 0 - no limit will be applied. ### server.setTimeout(msecs, callback) * `msecs` {Number} * `callback` {Function} Sets the timeout value for sockets, and emits a `'timeout'` event on the Server object, passing the socket as an argument, if a timeout occurs. If there is a `'timeout'` event listener on the Server object, then it will be called with the timed-out socket as an argument. By default, the Server's timeout value is 2 minutes, and sockets are destroyed automatically if they time out. However, if you assign a callback to the Server's `'timeout'` event, then you are responsible for handling socket timeouts. Returns `server`. ### server.timeout * {Number} Default = 120000 (2 minutes) The number of milliseconds of inactivity before a socket is presumed to have timed out. Note that the socket timeout logic is set up on connection, so changing this value only affects *new* connections to the server, not any existing connections. Set to 0 to disable any kind of automatic timeout behavior on incoming connections. ## Class: http.ServerResponse This object is created internally by a HTTP server--not by the user. It is passed as the second parameter to the `'request'` event. The response implements the [Writable Stream][] interface. This is an [`EventEmitter`][] with the following events: ### Event: 'close' `function () { }` Indicates that the underlying connection was terminated before [`response.end()`][] was called or able to flush. ### Event: 'finish' `function () { }` Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet. After this event, no more events will be emitted on the response object. ### response.addTrailers(headers) This method adds HTTP trailing headers (a header but at the end of the message) to the response. Trailers will **only** be emitted if chunked encoding is used for the response; if it is not (e.g., if the request was HTTP/1.0), they will be silently discarded. Note that HTTP requires the `Trailer` header to be sent if you intend to emit trailers, with a list of the header fields in its value. E.g., response.writeHead(200, { 'Content-Type': 'text/plain', 'Trailer': 'Content-MD5' }); response.write(fileData); response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'}); response.end(); Attempting to set a trailer field name that contains invalid characters will result in a [`TypeError`][] being thrown. ### response.end([data][, encoding][, callback]) This method signals to the server that all of the response headers and body have been sent; that server should consider this message complete. The method, `response.end()`, MUST be called on each response. If `data` is specified, it is equivalent to calling [`response.write(data, encoding)`][] followed by `response.end(callback)`. If `callback` is specified, it will be called when the response stream is finished. ### response.finished Boolean value that indicates whether the response has completed. Starts as `false`. After [`response.end()`][] executes, the value will be `true`. ### response.getHeader(name) Reads out a header that's already been queued but not sent to the client. Note that the name is case insensitive. This can only be called before headers get implicitly flushed. Example: var contentType = response.getHeader('content-type'); ### response.headersSent Boolean (read-only). True if headers were sent, false otherwise. ### response.removeHeader(name) Removes a header that's queued for implicit sending. Example: response.removeHeader('Content-Encoding'); ### response.sendDate When true, the Date header will be automatically generated and sent in the response if it is not already present in the headers. Defaults to true. This should only be disabled for testing; HTTP requires the Date header in responses. ### response.setHeader(name, value) Sets a single header value for implicit headers. If this header already exists in the to-be-sent headers, its value will be replaced. Use an array of strings here if you need to send multiple headers with the same name. Example: response.setHeader('Content-Type', 'text/html'); or response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); Attempting to set a header field name that contains invalid characters will result in a [`TypeError`][] being thrown. ### response.setTimeout(msecs, callback) * `msecs` {Number} * `callback` {Function} Sets the Socket's timeout value to `msecs`. If a callback is provided, then it is added as a listener on the `'timeout'` event on the response object. If no `'timeout'` listener is added to the request, the response, or the server, then sockets are destroyed when they time out. If you assign a handler on the request, the response, or the server's `'timeout'` events, then it is your responsibility to handle timed out sockets. Returns `response`. ### response.statusCode When using implicit headers (not calling [`response.writeHead()`][] explicitly), this property controls the status code that will be sent to the client when the headers get flushed. Example: response.statusCode = 404; After response header was sent to the client, this property indicates the status code which was sent out. ### response.statusMessage When using implicit headers (not calling [`response.writeHead()`][] explicitly), this property controls the status message that will be sent to the client when the headers get flushed. If this is left as `undefined` then the standard message for the status code will be used. Example: response.statusMessage = 'Not found'; After response header was sent to the client, this property indicates the status message which was sent out. ### response.write(chunk[, encoding][, callback]) If this method is called and [`response.writeHead()`][] has not been called, it will switch to implicit header mode and flush the implicit headers. This sends a chunk of the response body. This method may be called multiple times to provide successive parts of the body. `chunk` can be a string or a buffer. If `chunk` is a string, the second parameter specifies how to encode it into a byte stream. By default the `encoding` is `'utf8'`. The last parameter `callback` will be called when this chunk of data is flushed. **Note**: This is the raw HTTP body and has nothing to do with higher-level multi-part body encodings that may be used. The first time [`response.write()`][] is called, it will send the buffered header information and the first body to the client. The second time [`response.write()`][] is called, Node.js assumes you're going to be streaming data, and sends that separately. That is, the response is buffered up to the first chunk of body. Returns `true` if the entire data was flushed successfully to the kernel buffer. Returns `false` if all or part of the data was queued in user memory. `'drain'` will be emitted when the buffer is free again. ### response.writeContinue() Sends a HTTP/1.1 100 Continue message to the client, indicating that the request body should be sent. See the [`'checkContinue'`][] event on `Server`. ### response.writeHead(statusCode[, statusMessage][, headers]) Sends a response header to the request. The status code is a 3-digit HTTP status code, like `404`. The last argument, `headers`, are the response headers. Optionally one can give a human-readable `statusMessage` as the second argument. Example: var body = 'hello world'; response.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'text/plain' }); This method must only be called once on a message and it must be called before [`response.end()`][] is called. If you call [`response.write()`][] or [`response.end()`][] before calling this, the implicit/mutable headers will be calculated and call this function for you. Note that Content-Length is given in bytes not characters. The above example works because the string `'hello world'` contains only single byte characters. If the body contains higher coded characters then `Buffer.byteLength()` should be used to determine the number of bytes in a given encoding. And Node.js does not check whether Content-Length and the length of the body which has been transmitted are equal or not. ## Class: http.IncomingMessage An `IncomingMessage` object is created by [`http.Server`][] or [`http.ClientRequest`][] and passed as the first argument to the `'request'` and `'response'` event respectively. It may be used to access response status, headers and data. It implements the [Readable Stream][] interface, as well as the following additional events, methods, and properties. ### Event: 'close' `function () { }` Indicates that the underlying connection was closed. Just like `'end'`, this event occurs only once per response. ### message.headers The request/response headers object. Key-value pairs of header names and values. Header names are lower-cased. Example: // Prints something like: // // { 'user-agent': 'curl/7.22.0', // host: '127.0.0.1:8000', // accept: '*/*' } console.log(request.headers); Duplicates in raw headers are handled in the following ways, depending on the header name: * Duplicates of `age`, `authorization`, `content-length`, `content-type`, `etag`, `expires`, `from`, `host`, `if-modified-since`, `if-unmodified-since`, `last-modified`, `location`, `max-forwards`, `proxy-authorization`, `referer`, `retry-after`, or `user-agent` are discarded. * `set-cookie` is always an array. Duplicates are added to the array. * For all other headers, the values are joined together with ', '. ### message.httpVersion In case of server request, the HTTP version sent by the client. In the case of client response, the HTTP version of the connected-to server. Probably either `'1.1'` or `'1.0'`. Also `response.httpVersionMajor` is the first integer and `response.httpVersionMinor` is the second. ### message.method **Only valid for request obtained from [`http.Server`][].** The request method as a string. Read only. Example: `'GET'`, `'DELETE'`. ### message.rawHeaders The raw request/response headers list exactly as they were received. Note that the keys and values are in the same list. It is *not* a list of tuples. So, the even-numbered offsets are key values, and the odd-numbered offsets are the associated values. Header names are not lowercased, and duplicates are not merged. // Prints something like: // // [ 'user-agent', // 'this is invalid because there can be only one', // 'User-Agent', // 'curl/7.22.0', // 'Host', // '127.0.0.1:8000', // 'ACCEPT', // '*/*' ] console.log(request.rawHeaders); ### message.rawTrailers The raw request/response trailer keys and values exactly as they were received. Only populated at the `'end'` event. ### message.setTimeout(msecs, callback) * `msecs` {Number} * `callback` {Function} Calls `message.connection.setTimeout(msecs, callback)`. Returns `message`. ### message.statusCode **Only valid for response obtained from [`http.ClientRequest`][].** The 3-digit HTTP response status code. E.G. `404`. ### message.statusMessage **Only valid for response obtained from [`http.ClientRequest`][].** ### message.socket The [`net.Socket`][] object associated with the connection. With HTTPS support, use [`request.socket.getPeerCertificate()`][] to obtain the client's authentication details. The HTTP response status message (reason phrase). E.G. `OK` or `Internal Server Error`. ### message.trailers The request/response trailers object. Only populated at the `'end'` event. ### message.url **Only valid for request obtained from [`http.Server`][].** Request URL string. This contains only the URL that is present in the actual HTTP request. If the request is: GET /status?name=ryan HTTP/1.1\r\n Accept: text/plain\r\n \r\n Then `request.url` will be: '/status?name=ryan' If you would like to parse the URL into its parts, you can use `require('url').parse(request.url)`. Example: node> require('url').parse('/status?name=ryan') { href: '/status?name=ryan', search: '?name=ryan', query: 'name=ryan', pathname: '/status' } If you would like to extract the params from the query string, you can use the `require('querystring').parse` function, or pass `true` as the second argument to `require('url').parse`. Example: node> require('url').parse('/status?name=ryan', true) { href: '/status?name=ryan', search: '?name=ryan', query: { name: 'ryan' }, pathname: '/status' } ## http.METHODS * {Array} A list of the HTTP methods that are supported by the parser. ## http.STATUS_CODES * {Object} A collection of all the standard HTTP response status codes, and the short description of each. For example, `http.STATUS_CODES[404] === 'Not Found'`. ## http.createClient([port][, host]) Stability: 0 - Deprecated: Use [`http.request()`][] instead. Constructs a new HTTP client. `port` and `host` refer to the server to be connected to. ## http.createServer([requestListener]) Returns a new instance of [`http.Server`][]. The `requestListener` is a function which is automatically added to the `'request'` event. ## http.get(options[, callback]) Since most requests are GET requests without bodies, Node.js provides this convenience method. The only difference between this method and [`http.request()`][] is that it sets the method to GET and calls `req.end()` automatically. Example: http.get('http://www.google.com/index.html', (res) => { console.log(`Got response: ${res.statusCode}`); // consume response body res.resume(); }).on('error', (e) => { console.log(`Got error: ${e.message}`); }); ## http.globalAgent Global instance of Agent which is used as the default for all http client requests. ## http.request(options[, callback]) Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests. `options` can be an object or a string. If `options` is a string, it is automatically parsed with [`url.parse()`][]. Options: - `protocol`: Protocol to use. Defaults to `'http:'`. - `host`: A domain name or IP address of the server to issue the request to. Defaults to `'localhost'`. - `hostname`: Alias for `host`. To support [`url.parse()`][] `hostname` is preferred over `host`. - `family`: IP address family to use when resolving `host` and `hostname`. Valid values are `4` or `6`. When unspecified, both IP v4 and v6 will be used. - `port`: Port of remote server. Defaults to 80. - `localAddress`: Local interface to bind for network connections. - `socketPath`: Unix Domain Socket (use one of host:port or socketPath). - `method`: A string specifying the HTTP request method. Defaults to `'GET'`. - `path`: Request path. Defaults to `'/'`. Should include query string if any. E.G. `'/index.html?page=12'`. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future. - `headers`: An object containing request headers. - `auth`: Basic authentication i.e. `'user:password'` to compute an Authorization header. - `agent`: Controls [`Agent`][] behavior. When an Agent is used request will default to `Connection: keep-alive`. Possible values: - `undefined` (default): use [`http.globalAgent`][] for this host and port. - `Agent` object: explicitly use the passed in `Agent`. - `false`: opts out of connection pooling with an Agent, defaults request to `Connection: close`. The optional `callback` parameter will be added as a one time listener for the `'response'` event. `http.request()` returns an instance of the [`http.ClientRequest`][] class. The `ClientRequest` instance is a writable stream. If one needs to upload a file with a POST request, then write to the `ClientRequest` object. Example: var postData = querystring.stringify({ 'msg' : 'Hello World!' }); var options = { hostname: 'www.google.com', port: 80, path: '/upload', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': postData.length } }; var req = http.request(options, (res) => { console.log(`STATUS: ${res.statusCode}`); console.log(`HEADERS: ${JSON.stringify(res.headers)}`); res.setEncoding('utf8'); res.on('data', (chunk) => { console.log(`BODY: ${chunk}`); }); res.on('end', () => { console.log('No more data in response.') }) }); req.on('error', (e) => { console.log(`problem with request: ${e.message}`); }); // write data to request body req.write(postData); req.end(); Note that in the example `req.end()` was called. With `http.request()` one must always call `req.end()` to signify that you're done with the request - even if there is no data being written to the request body. If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an `'error'` event is emitted on the returned request object. As with all `'error'` events, if no listeners are registered the error will be thrown. There are a few special headers that should be noted. * Sending a 'Connection: keep-alive' will notify Node.js that the connection to the server should be persisted until the next request. * Sending a 'Content-length' header will disable the default chunked encoding. * Sending an 'Expect' header will immediately send the request headers. Usually, when sending 'Expect: 100-continue', you should both set a timeout and listen for the `'continue'` event. See RFC2616 Section 8.2.3 for more information. * Sending an Authorization header will override using the `auth` option to compute basic authentication. [`'checkContinue'`]: #http_event_checkcontinue [`'listening'`]: net.html#net_event_listening [`'response'`]: #http_event_response [`Agent`]: #http_class_http_agent [`Buffer`]: buffer.html#buffer_buffer [`destroy()`]: #http_agent_destroy [`EventEmitter`]: events.html#events_class_events_eventemitter [`http.Agent`]: #http_class_http_agent [`http.ClientRequest`]: #http_class_http_clientrequest [`http.globalAgent`]: #http_http_globalagent [`http.IncomingMessage`]: #http_http_incomingmessage [`http.request()`]: #http_http_request_options_callback [`http.Server`]: #http_class_http_server [`http.ServerResponse`]: #http_class_http_serverresponse [`message.headers`]: #http_message_headers [`net.Server.close()`]: net.html#net_server_close_callback [`net.Server.listen()`]: net.html#net_server_listen_handle_callback [`net.Server.listen(path)`]: net.html#net_server_listen_path_callback [`net.Server.listen(port)`]: net.html#net_server_listen_port_hostname_backlog_callback [`net.Socket`]: net.html#net_class_net_socket [`request.socket.getPeerCertificate()`]: tls.html#tls_tlssocket_getpeercertificate_detailed [`response.end()`]: #http_response_end_data_encoding_callback [`response.write()`]: #http_response_write_chunk_encoding_callback [`response.write(data, encoding)`]: #http_response_write_chunk_encoding_callback [`response.writeContinue()`]: #http_response_writecontinue [`response.writeHead()`]: #http_response_writehead_statuscode_statusmessage_headers [`socket.setKeepAlive()`]: net.html#net_socket_setkeepalive_enable_initialdelay [`socket.setNoDelay()`]: net.html#net_socket_setnodelay_nodelay [`socket.setTimeout()`]: net.html#net_socket_settimeout_timeout_callback [`stream.setEncoding()`]: stream.html#stream_stream_setencoding_encoding [`TypeError`]: errors.html#errors_class_typeerror [`url.parse()`]: url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost [constructor options]: #http_new_agent_options [Readable Stream]: stream.html#stream_class_stream_readable [Writable Stream]: stream.html#stream_class_stream_writable node-v4.2.6/doc/api/https.html000644 000766 000024 00000036216 12650222331 016320 0ustar00iojsstaff000000 000000 HTTPS Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


HTTPS#

Stability: 2 - Stable

HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module.

Class: https.Agent#

An Agent object for HTTPS similar to http.Agent. See https.request() for more information.

Class: https.Server#

This class is a subclass of tls.Server and emits events same as http.Server. See http.Server for more information.

server.setTimeout(msecs, callback)#

See http.Server#setTimeout().

server.timeout#

See http.Server#timeout.

https.createServer(options[, requestListener])#

Returns a new HTTPS web server object. The options is similar to tls.createServer(). The requestListener is a function which is automatically added to the 'request' event.

Example:

// curl -k https://localhost:8000/
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

Or

const https = require('https');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('server.pfx')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('hello world\n');
}).listen(8000);

server.close([callback])#

See http.close() for details.

server.listen(handle[, callback])#

server.listen(path[, callback])#

server.listen(port[, host][, backlog][, callback])#

See http.listen() for details.

https.get(options, callback)#

Like http.get() but for HTTPS.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

Example:

const https = require('https');

https.get('https://encrypted.google.com/', (res) => {
  console.log('statusCode: ', res.statusCode);
  console.log('headers: ', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });

}).on('error', (e) => {
  console.error(e);
});

https.globalAgent#

Global instance of https.Agent for all HTTPS client requests.

https.request(options, callback)#

Makes a request to a secure web server.

options can be an object or a string. If options is a string, it is automatically parsed with url.parse().

All options from http.request() are valid.

Example:

const https = require('https');

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET'
};

var req = https.request(options, (res) => {
  console.log('statusCode: ', res.statusCode);
  console.log('headers: ', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });
});
req.end();

req.on('error', (e) => {
  console.error(e);
});

The options argument has the following options

  • host: A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
  • hostname: Alias for host. To support url.parse() hostname is preferred over host.
  • family: IP address family to use when resolving host and hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.
  • port: Port of remote server. Defaults to 443.
  • localAddress: Local interface to bind for network connections.
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • path: Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
  • headers: An object containing request headers.
  • auth: Basic authentication i.e. 'user:password' to compute an Authorization header.
  • agent: Controls Agent behavior. When an Agent is used request will default to Connection: keep-alive. Possible values:
    • undefined (default): use globalAgent for this host and port.
    • Agent object: explicitly use the passed in Agent.
    • false: opts out of connection pooling with an Agent, defaults request to Connection: close.

The following options from tls.connect() can also be specified. However, a globalAgent silently ignores these.

  • pfx: Certificate, Private key and CA certificates to use for SSL. Default null.
  • key: Private key to use for SSL. Default null.
  • passphrase: A string of passphrase for the private key or pfx. Default null.
  • cert: Public x509 certificate to use. Default null.
  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.
  • rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Default true.
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

In order to specify these options, use a custom Agent.

Example:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
options.agent = new https.Agent(options);

var req = https.request(options, (res) => {
  ...
}

Alternatively, opt out of connection pooling by not using an Agent.

Example:

var options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
  agent: false
};

var req = https.request(options, (res) => {
  ...
}
node-v4.2.6/doc/api/https.json000644 000766 000024 00000031163 12650222331 016321 0ustar00iojsstaff000000 000000 { "source": "doc/api/https.markdown", "modules": [ { "textRaw": "HTTPS", "name": "https", "stability": 2, "stabilityText": "Stable", "desc": "

HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a\nseparate module.\n\n

\n", "classes": [ { "textRaw": "Class: https.Agent", "type": "class", "name": "https.Agent", "desc": "

An Agent object for HTTPS similar to [http.Agent][]. See [https.request()][]\nfor more information.\n\n

\n" }, { "textRaw": "Class: https.Server", "type": "class", "name": "https.Server", "desc": "

This class is a subclass of tls.Server and emits events same as\n[http.Server][]. See [http.Server][] for more information.\n\n

\n", "methods": [ { "textRaw": "server.setTimeout(msecs, callback)", "type": "method", "name": "setTimeout", "desc": "

See [http.Server#setTimeout()][].\n\n

\n", "signatures": [ { "params": [ { "name": "msecs" }, { "name": "callback" } ] } ] } ], "properties": [ { "textRaw": "server.timeout", "name": "timeout", "desc": "

See [http.Server#timeout][].\n\n

\n" } ] } ], "methods": [ { "textRaw": "https.createServer(options[, requestListener])", "type": "method", "name": "createServer", "desc": "

Returns a new HTTPS web server object. The options is similar to\n[tls.createServer()][]. The requestListener is a function which is\nautomatically added to the 'request' event.\n\n

\n

Example:\n\n

\n
// curl -k https://localhost:8000/\nconst https = require('https');\nconst fs = require('fs');\n\nconst options = {\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')\n};\n\nhttps.createServer(options, (req, res) => {\n  res.writeHead(200);\n  res.end('hello world\\n');\n}).listen(8000);
\n

Or\n\n

\n
const https = require('https');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('server.pfx')\n};\n\nhttps.createServer(options, (req, res) => {\n  res.writeHead(200);\n  res.end('hello world\\n');\n}).listen(8000);
\n", "methods": [ { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

See [http.close()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(path[, callback])", "type": "method", "name": "listen", "desc": "

See [http.listen()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.listen(port[, host][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

See [http.listen()][] for details.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] } ], "signatures": [ { "params": [ { "name": "options" }, { "name": "requestListener", "optional": true } ] } ] }, { "textRaw": "https.get(options, callback)", "type": "method", "name": "get", "desc": "

Like [http.get()][] but for HTTPS.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

Example:\n\n

\n
const https = require('https');\n\nhttps.get('https://encrypted.google.com/', (res) => {\n  console.log('statusCode: ', res.statusCode);\n  console.log('headers: ', res.headers);\n\n  res.on('data', (d) => {\n    process.stdout.write(d);\n  });\n\n}).on('error', (e) => {\n  console.error(e);\n});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] }, { "textRaw": "https.request(options, callback)", "type": "method", "name": "request", "desc": "

Makes a request to a secure web server.\n\n

\n

options can be an object or a string. If options is a string, it is\nautomatically parsed with [url.parse()][].\n\n

\n

All options from [http.request()][] are valid.\n\n

\n

Example:\n\n

\n
const https = require('https');\n\nvar options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET'\n};\n\nvar req = https.request(options, (res) => {\n  console.log('statusCode: ', res.statusCode);\n  console.log('headers: ', res.headers);\n\n  res.on('data', (d) => {\n    process.stdout.write(d);\n  });\n});\nreq.end();\n\nreq.on('error', (e) => {\n  console.error(e);\n});
\n

The options argument has the following options\n\n

\n
    \n
  • host: A domain name or IP address of the server to issue the request to.\nDefaults to 'localhost'.
  • \n
  • hostname: Alias for host. To support url.parse() hostname is\npreferred over host.
  • \n
  • family: IP address family to use when resolving host and hostname.\nValid values are 4 or 6. When unspecified, both IP v4 and v6 will be\nused.
  • \n
  • port: Port of remote server. Defaults to 443.
  • \n
  • localAddress: Local interface to bind for network connections.
  • \n
  • socketPath: Unix Domain Socket (use one of host:port or socketPath).
  • \n
  • method: A string specifying the HTTP request method. Defaults to 'GET'.
  • \n
  • path: Request path. Defaults to '/'. Should include query string if any.\nE.G. '/index.html?page=12'. An exception is thrown when the request path\ncontains illegal characters. Currently, only spaces are rejected but that\nmay change in the future.
  • \n
  • headers: An object containing request headers.
  • \n
  • auth: Basic authentication i.e. 'user:password' to compute an\nAuthorization header.
  • \n
  • agent: Controls [Agent][] behavior. When an Agent is used request will\ndefault to Connection: keep-alive. Possible values:
      \n
    • undefined (default): use [globalAgent][] for this host and port.
    • \n
    • Agent object: explicitly use the passed in Agent.
    • \n
    • false: opts out of connection pooling with an Agent, defaults request to\nConnection: close.
    • \n
    \n
  • \n
\n

The following options from [tls.connect()][] can also be specified. However, a\n[globalAgent][] silently ignores these.\n\n

\n
    \n
  • pfx: Certificate, Private key and CA certificates to use for SSL. Default null.
  • \n
  • key: Private key to use for SSL. Default null.
  • \n
  • passphrase: A string of passphrase for the private key or pfx. Default null.
  • \n
  • cert: Public x509 certificate to use. Default null.
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.
  • \n
  • ciphers: A string describing the ciphers to use or exclude. Consult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for\ndetails on the format.
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails. Verification happens at the connection level, before the HTTP\nrequest is sent. Default true.
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].
  • \n
\n

In order to specify these options, use a custom [Agent][].\n\n

\n

Example:\n\n

\n
var options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET',\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')\n};\noptions.agent = new https.Agent(options);\n\nvar req = https.request(options, (res) => {\n  ...\n}
\n

Alternatively, opt out of connection pooling by not using an Agent.\n\n

\n

Example:\n\n

\n
var options = {\n  hostname: 'encrypted.google.com',\n  port: 443,\n  path: '/',\n  method: 'GET',\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),\n  agent: false\n};\n\nvar req = https.request(options, (res) => {\n  ...\n}
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] } ], "properties": [ { "textRaw": "https.globalAgent", "name": "globalAgent", "desc": "

Global instance of [https.Agent][] for all HTTPS client requests.\n\n

\n" } ], "type": "module", "displayName": "HTTPS" } ] } node-v4.2.6/doc/api/https.markdown000644 000766 000024 00000016622 12650222326 017201 0ustar00iojsstaff000000 000000 # HTTPS Stability: 2 - Stable HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module. ## Class: https.Agent An Agent object for HTTPS similar to [`http.Agent`][]. See [`https.request()`][] for more information. ## Class: https.Server This class is a subclass of `tls.Server` and emits events same as [`http.Server`][]. See [`http.Server`][] for more information. ### server.setTimeout(msecs, callback) See [`http.Server#setTimeout()`][]. ### server.timeout See [`http.Server#timeout`][]. ## https.createServer(options[, requestListener]) Returns a new HTTPS web server object. The `options` is similar to [`tls.createServer()`][]. The `requestListener` is a function which is automatically added to the `'request'` event. Example: // curl -k https://localhost:8000/ const https = require('https'); const fs = require('fs'); const options = { key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') }; https.createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); Or const https = require('https'); const fs = require('fs'); const options = { pfx: fs.readFileSync('server.pfx') }; https.createServer(options, (req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); ### server.close([callback]) See [`http.close()`][] for details. ### server.listen(handle[, callback]) ### server.listen(path[, callback]) ### server.listen(port[, host][, backlog][, callback]) See [`http.listen()`][] for details. ## https.get(options, callback) Like [`http.get()`][] but for HTTPS. `options` can be an object or a string. If `options` is a string, it is automatically parsed with [`url.parse()`][]. Example: const https = require('https'); https.get('https://encrypted.google.com/', (res) => { console.log('statusCode: ', res.statusCode); console.log('headers: ', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }).on('error', (e) => { console.error(e); }); ## https.globalAgent Global instance of [`https.Agent`][] for all HTTPS client requests. ## https.request(options, callback) Makes a request to a secure web server. `options` can be an object or a string. If `options` is a string, it is automatically parsed with [`url.parse()`][]. All options from [`http.request()`][] are valid. Example: const https = require('https'); var options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET' }; var req = https.request(options, (res) => { console.log('statusCode: ', res.statusCode); console.log('headers: ', res.headers); res.on('data', (d) => { process.stdout.write(d); }); }); req.end(); req.on('error', (e) => { console.error(e); }); The options argument has the following options - `host`: A domain name or IP address of the server to issue the request to. Defaults to `'localhost'`. - `hostname`: Alias for `host`. To support `url.parse()` `hostname` is preferred over `host`. - `family`: IP address family to use when resolving `host` and `hostname`. Valid values are `4` or `6`. When unspecified, both IP v4 and v6 will be used. - `port`: Port of remote server. Defaults to 443. - `localAddress`: Local interface to bind for network connections. - `socketPath`: Unix Domain Socket (use one of host:port or socketPath). - `method`: A string specifying the HTTP request method. Defaults to `'GET'`. - `path`: Request path. Defaults to `'/'`. Should include query string if any. E.G. `'/index.html?page=12'`. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future. - `headers`: An object containing request headers. - `auth`: Basic authentication i.e. `'user:password'` to compute an Authorization header. - `agent`: Controls [`Agent`][] behavior. When an Agent is used request will default to `Connection: keep-alive`. Possible values: - `undefined` (default): use [`globalAgent`][] for this host and port. - `Agent` object: explicitly use the passed in `Agent`. - `false`: opts out of connection pooling with an Agent, defaults request to `Connection: close`. The following options from [`tls.connect()`][] can also be specified. However, a [`globalAgent`][] silently ignores these. - `pfx`: Certificate, Private key and CA certificates to use for SSL. Default `null`. - `key`: Private key to use for SSL. Default `null`. - `passphrase`: A string of passphrase for the private key or pfx. Default `null`. - `cert`: Public x509 certificate to use. Default `null`. - `ca`: A string, `Buffer` or array of strings or `Buffer`s of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections. - `ciphers`: A string describing the ciphers to use or exclude. Consult for details on the format. - `rejectUnauthorized`: If `true`, the server certificate is verified against the list of supplied CAs. An `'error'` event is emitted if verification fails. Verification happens at the connection level, *before* the HTTP request is sent. Default `true`. - `secureProtocol`: The SSL method to use, e.g. `SSLv3_method` to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant [`SSL_METHODS`][]. In order to specify these options, use a custom [`Agent`][]. Example: var options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET', key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem') }; options.agent = new https.Agent(options); var req = https.request(options, (res) => { ... } Alternatively, opt out of connection pooling by not using an `Agent`. Example: var options = { hostname: 'encrypted.google.com', port: 443, path: '/', method: 'GET', key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'), cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'), agent: false }; var req = https.request(options, (res) => { ... } [`Agent`]: #https_class_https_agent [`globalAgent`]: #https_https_globalagent [`http.Agent`]: http.html#http_class_http_agent [`http.close()`]: http.html#http_server_close_callback [`http.get()`]: http.html#http_http_get_options_callback [`http.listen()`]: http.html#http_server_listen_port_hostname_backlog_callback [`http.request()`]: http.html#http_http_request_options_callback [`http.Server#setTimeout()`]: http.html#http_server_settimeout_msecs_callback [`http.Server#timeout`]: http.html#http_server_timeout [`http.Server`]: http.html#http_class_http_server [`https.Agent`]: #https_class_https_agent [`https.request()`]: #https_https_request_options_callback [`SSL_METHODS`]: https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_PROTOCOL_METHODS [`tls.connect()`]: tls.html#tls_tls_connect_options_callback [`tls.createServer()`]: tls.html#tls_tls_createserver_options_secureconnectionlistener [`url.parse()`]: url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost node-v4.2.6/doc/api/index.html000644 000766 000024 00000012430 12650222331 016255 0ustar00iojsstaff000000 000000 Node.js v4.2.6 Manual & Documentation node-v4.2.6/doc/api/index.json000644 000766 000024 00000014366 12650222331 016274 0ustar00iojsstaff000000 000000 { "source": "doc/api/index.markdown", "desc": [ { "type": "space" }, { "type": "list_start", "ordered": false }, { "type": "list_item_start" }, { "type": "text", "text": "[About these Docs](documentation.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Synopsis](synopsis.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Assertion Testing](assert.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Buffer](buffer.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[C/C++ Addons](addons.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Child Processes](child_process.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Cluster](cluster.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Console](console.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Crypto](crypto.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Debugger](debugger.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[DNS](dns.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Domain](domain.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Errors](errors.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Events](events.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[File System](fs.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Globals](globals.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[HTTP](http.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[HTTPS](https.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Modules](modules.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Net](net.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[OS](os.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Path](path.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Process](process.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Punycode](punycode.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Query Strings](querystring.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Readline](readline.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[REPL](repl.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Stream](stream.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[String Decoder](string_decoder.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Timers](timers.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[TLS/SSL](tls.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[TTY](tty.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[UDP/Datagram](dgram.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[URL](url.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[Utilities](util.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[V8](v8.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[VM](vm.html)" }, { "type": "list_item_end" }, { "type": "list_item_start" }, { "type": "text", "text": "[ZLIB](zlib.html)" }, { "type": "space" }, { "type": "list_item_end" }, { "type": "list_end" } ] } node-v4.2.6/doc/api/index.markdown000644 000766 000024 00000000027 12650222326 017136 0ustar00iojsstaff000000 000000 @include _toc.markdown node-v4.2.6/doc/api/modules.html000644 000766 000024 00000067370 12650222331 016633 0ustar00iojsstaff000000 000000 Modules Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Modules#

Stability: 3 - Locked

Node.js has a simple module loading system. In Node.js, files and modules are in one-to-one correspondence. As an example, foo.js loads the module circle.js in the same directory.

The contents of foo.js:

const circle = require('./circle.js');
console.log( `The area of a circle of radius 4 is ${circle.area(4)}`);

The contents of circle.js:

const PI = Math.PI;

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

The module circle.js has exported the functions area() and circumference(). To add functions and objects to the root of your module, you can add them to the special exports object.

Variables local to the module will be private, as though the module was wrapped in a function. In this example the variable PI is private to circle.js.

If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.

Below, bar.js makes use of the square module, which exports a constructor:

const square = require('./square.js');
var mySquare = square(2);
console.log(`The area of my square is ${mySquare.area()}`);

The square module is defined in square.js:

// assigning to exports will not modify module, must use module.exports
module.exports = function(width) {
  return {
    area: function() {
      return width * width;
    }
  };
}

The module system is implemented in the require("module") module.

Accessing the main module#

When a file is run directly from Node.js, require.main is set to its module. That means that you can determine whether a file has been run directly by testing

require.main === module

For a file foo.js, this will be true if run via node foo.js, but false if run by require('./foo').

Because module provides a filename property (normally equivalent to __filename), the entry point of the current application can be obtained by checking require.main.filename.

Addenda: Package Manager Tips#

The semantics of Node.js's require() function were designed to be general enough to support a number of reasonable directory structures. Package manager programs such as dpkg, rpm, and npm will hopefully find it possible to build native packages from Node.js modules without modification.

Below we give a suggested directory structure that could work:

Let's say that we wanted to have the folder at /usr/lib/node/<some-package>/<some-version> hold the contents of a specific version of a package.

Packages can depend on one another. In order to install package foo, you may have to install a specific version of package bar. The bar package may itself have dependencies, and in some cases, these dependencies may even collide or form cycles.

Since Node.js looks up the realpath of any modules it loads (that is, resolves symlinks), and then looks for their dependencies in the node_modules folders as described above, this situation is very simple to resolve with the following architecture:

  • /usr/lib/node/foo/1.2.3/ - Contents of the foo package, version 1.2.3.
  • /usr/lib/node/bar/4.3.2/ - Contents of the bar package that foo depends on.
  • /usr/lib/node/foo/1.2.3/node_modules/bar - Symbolic link to /usr/lib/node/bar/4.3.2/.
  • /usr/lib/node/bar/4.3.2/node_modules/* - Symbolic links to the packages that bar depends on.

Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use.

When the code in the foo package does require('bar'), it will get the version that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar. Then, when the code in the bar package calls require('quux'), it'll get the version that is symlinked into /usr/lib/node/bar/4.3.2/node_modules/quux.

Furthermore, to make the module lookup process even more optimal, rather than putting packages directly in /usr/lib/node, we could put them in /usr/lib/node_modules/<name>/<version>. Then Node.js will not bother looking for missing dependencies in /usr/node_modules or /node_modules.

In order to make modules available to the Node.js REPL, it might be useful to also add the /usr/lib/node_modules folder to the $NODE_PATH environment variable. Since the module lookups using node_modules folders are all relative, and based on the real path of the files making the calls to require(), the packages themselves can be anywhere.

All Together...#

To get the exact filename that will be loaded when require() is called, use the require.resolve() function.

Putting together all of the above, here is the high-level algorithm in pseudocode of what require.resolve does:

require(X) from module at path Y
1. If X is a core module,
   a. return the core module
   b. STOP
2. If X begins with './' or '/' or '../'
   a. LOAD_AS_FILE(Y + X)
   b. LOAD_AS_DIRECTORY(Y + X)
3. LOAD_NODE_MODULES(X, dirname(Y))
4. THROW "not found"

LOAD_AS_FILE(X)
1. If X is a file, load X as JavaScript text.  STOP
2. If X.js is a file, load X.js as JavaScript text.  STOP
3. If X.json is a file, parse X.json to a JavaScript Object.  STOP
4. If X.node is a file, load X.node as binary addon.  STOP

LOAD_AS_DIRECTORY(X)
1. If X/package.json is a file,
   a. Parse X/package.json, and look for "main" field.
   b. let M = X + (json main field)
   c. LOAD_AS_FILE(M)
2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP
3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP
4. If X/index.node is a file, load X/index.node as binary addon.  STOP

LOAD_NODE_MODULES(X, START)
1. let DIRS=NODE_MODULES_PATHS(START)
2. for each DIR in DIRS:
   a. LOAD_AS_FILE(DIR/X)
   b. LOAD_AS_DIRECTORY(DIR/X)

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let I = count of PARTS - 1
3. let DIRS = []
4. while I >= 0,
   a. if PARTS[I] = "node_modules" CONTINUE
   c. DIR = path join(PARTS[0 .. I] + "node_modules")
   b. DIRS = DIRS + DIR
   c. let I = I - 1
5. return DIRS

Caching#

Modules are cached after the first time they are loaded. This means (among other things) that every call to require('foo') will get exactly the same object returned, if it would resolve to the same file.

Multiple calls to require('foo') may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

If you want to have a module execute code multiple times, then export a function, and call that function.

Module Caching Caveats#

Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from node_modules folders), it is not a guarantee that require('foo') will always return the exact same object, if it would resolve to different files.

Core Modules#

Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation.

The core modules are defined within Node.js's source and are located in the lib/ folder.

Core modules are always preferentially loaded if their identifier is passed to require(). For instance, require('http') will always return the built in HTTP module, even if there is a file by that name.

Cycles#

When there are circular require() calls, a module might not have finished executing when it is returned.

Consider this situation:

a.js:

console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');

b.js:

console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');

main.js:

console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.

By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:

$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true

If you have cyclic module dependencies in your program, make sure to plan accordingly.

File Modules#

If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: .js, .json, and finally .node.

.js files are interpreted as JavaScript text files, and .json files are parsed as JSON text files. .node files are interpreted as compiled addon modules loaded with dlopen.

A required module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js.

A required module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it.

Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder.

If the given path does not exist, require() will throw an Error with its code property set to 'MODULE_NOT_FOUND'.

Folders as Modules#

It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to require() as an argument.

The first is to create a package.json file in the root of the folder, which specifies a main module. An example package.json file might look like this:

{ "name" : "some-library",
  "main" : "./lib/some-library.js" }

If this was in a folder at ./some-library, then require('./some-library') would attempt to load ./some-library/lib/some-library.js.

This is the extent of Node.js's awareness of package.json files.

If there is no package.json file present in the directory, then Node.js will attempt to load an index.js or index.node file out of that directory. For example, if there was no package.json file in the above example, then require('./some-library') would attempt to load:

  • ./some-library/index.js
  • ./some-library/index.node

Loading from node_modules Folders#

If the module identifier passed to require() is not a native module, and does not begin with '/', '../', or './', then Node.js starts at the parent directory of the current module, and adds /node_modules, and attempts to load the module from that location. Node will not append node_modules to a path already ending in node_modules.

If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached.

For example, if the file at '/home/ry/projects/foo.js' called require('bar.js'), then Node.js would look in the following locations, in this order:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

This allows programs to localize their dependencies, so that they do not clash.

You can require specific files or sub modules distributed with a module by including a path suffix after the module name. For instance require('example-module/path/to/file') would resolve path/to/file relative to where example-module is located. The suffixed path follows the same module resolution semantics.

Loading from the global folders#

If the NODE_PATH environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere. (Note: On Windows, NODE_PATH is delimited by semicolons instead of colons.)

NODE_PATH was originally created to support loading modules from varying paths before the current module resolution algorithm was frozen.

NODE_PATH is still supported, but is less necessary now that the Node.js ecosystem has settled on a convention for locating dependent modules. Sometimes deployments that rely on NODE_PATH show surprising behavior when people are unaware that NODE_PATH must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the NODE_PATH is searched.

Additionally, Node.js will search in the following locations:

  • 1: $HOME/.node_modules
  • 2: $HOME/.node_libraries
  • 3: $PREFIX/lib/node

Where $HOME is the user's home directory, and $PREFIX is Node.js's configured node_prefix.

These are mostly for historic reasons. You are highly encouraged to place your dependencies locally in node_modules folders. They will be loaded faster, and more reliably.

The module Object#

  • {Object}

In each module, the module free variable is a reference to the object representing the current module. For convenience, module.exports is also accessible via the exports module-global. module isn't actually a global but rather local to each module.

module.children#

  • Array

The module objects required by this one.

module.exports#

  • Object

The module.exports object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object to module.exports. Note that assigning the desired object to exports will simply rebind the local exports variable, which is probably not what you want to do.

For example suppose we were making a module called a.js

const EventEmitter = require('events');

module.exports = new EventEmitter();

// Do some work, and after some time emit
// the 'ready' event from the module itself.
setTimeout(() => {
  module.exports.emit('ready');
}, 1000);

Then in another file we could do

const a = require('./a');
a.on('ready', () => {
  console.log('module a is ready');
});

Note that assignment to module.exports must be done immediately. It cannot be done in any callbacks. This does not work:

x.js:

setTimeout(() => {
  module.exports = { a: 'hello' };
}, 0);

y.js:

const x = require('./x');
console.log(x.a);

exports alias#

The exports variable that is available within a module starts as a reference to module.exports. As with any variable, if you assign a new value to it, it is no longer bound to the previous value.

To illustrate the behavior, imagine this hypothetical implementation of require():

function require(...) {
  // ...
  function (module, exports) {
    // Your module code here
    exports = some_func;        // re-assigns exports, exports is no longer
                                // a shortcut, and nothing is exported.
    module.exports = some_func; // makes your module export 0
  } (module, module.exports);
  return module;
}

As a guideline, if the relationship between exports and module.exports seems like magic to you, ignore exports and only use module.exports.

module.filename#

  • String

The fully resolved filename to the module.

module.id#

  • String

The identifier for the module. Typically this is the fully resolved filename.

module.loaded#

  • Boolean

Whether or not the module is done loading, or is in the process of loading.

module.parent#

  • Module Object

The module that first required this one.

module.require(id)#

  • id String
  • Return: Object module.exports from the resolved module

The module.require method provides a way to load a module as if require() was called from the original module.

Note that in order to do this, you must get a reference to the module object. Since require() returns the module.exports, and the module is typically only available within a specific module's code, it must be explicitly exported in order to be used.

node-v4.2.6/doc/api/modules.json000644 000766 000024 00000057173 12650222331 016640 0ustar00iojsstaff000000 000000 { "source": "doc/api/modules.markdown", "modules": [ { "textRaw": "Modules", "name": "module", "stability": 3, "stabilityText": "Locked", "desc": "

Node.js has a simple module loading system. In Node.js, files and modules are\nin one-to-one correspondence. As an example, foo.js loads the module\ncircle.js in the same directory.\n\n

\n

The contents of foo.js:\n\n

\n
const circle = require('./circle.js');\nconsole.log( `The area of a circle of radius 4 is ${circle.area(4)}`);
\n

The contents of circle.js:\n\n

\n
const PI = Math.PI;\n\nexports.area = function (r) {\n  return PI * r * r;\n};\n\nexports.circumference = function (r) {\n  return 2 * PI * r;\n};
\n

The module circle.js has exported the functions area() and\ncircumference(). To add functions and objects to the root of your module,\nyou can add them to the special exports object.\n\n

\n

Variables local to the module will be private, as though the module was wrapped\nin a function. In this example the variable PI is private to circle.js.\n\n

\n

If you want the root of your module's export to be a function (such as a\nconstructor) or if you want to export a complete object in one assignment\ninstead of building it one property at a time, assign it to module.exports\ninstead of exports.\n\n

\n

Below, bar.js makes use of the square module, which exports a constructor:\n\n

\n
const square = require('./square.js');\nvar mySquare = square(2);\nconsole.log(`The area of my square is ${mySquare.area()}`);
\n

The square module is defined in square.js:\n\n

\n
// assigning to exports will not modify module, must use module.exports\nmodule.exports = function(width) {\n  return {\n    area: function() {\n      return width * width;\n    }\n  };\n}
\n

The module system is implemented in the require("module") module.\n\n

\n", "miscs": [ { "textRaw": "Accessing the main module", "name": "Accessing the main module", "type": "misc", "desc": "

When a file is run directly from Node.js, require.main is set to its\nmodule. That means that you can determine whether a file has been run\ndirectly by testing\n\n

\n
require.main === module
\n

For a file foo.js, this will be true if run via node foo.js, but\nfalse if run by require('./foo').\n\n

\n

Because module provides a filename property (normally equivalent to\n__filename), the entry point of the current application can be obtained\nby checking require.main.filename.\n\n

\n" }, { "textRaw": "Addenda: Package Manager Tips", "name": "Addenda: Package Manager Tips", "type": "misc", "desc": "

The semantics of Node.js's require() function were designed to be general\nenough to support a number of reasonable directory structures. Package manager\nprograms such as dpkg, rpm, and npm will hopefully find it possible to\nbuild native packages from Node.js modules without modification.\n\n

\n

Below we give a suggested directory structure that could work:\n\n

\n

Let's say that we wanted to have the folder at\n/usr/lib/node/<some-package>/<some-version> hold the contents of a\nspecific version of a package.\n\n

\n

Packages can depend on one another. In order to install package foo, you\nmay have to install a specific version of package bar. The bar package\nmay itself have dependencies, and in some cases, these dependencies may even\ncollide or form cycles.\n\n

\n

Since Node.js looks up the realpath of any modules it loads (that is,\nresolves symlinks), and then looks for their dependencies in the\nnode_modules folders as described above, this situation is very simple to\nresolve with the following architecture:\n\n

\n
    \n
  • /usr/lib/node/foo/1.2.3/ - Contents of the foo package, version 1.2.3.
  • \n
  • /usr/lib/node/bar/4.3.2/ - Contents of the bar package that foo\ndepends on.
  • \n
  • /usr/lib/node/foo/1.2.3/node_modules/bar - Symbolic link to\n/usr/lib/node/bar/4.3.2/.
  • \n
  • /usr/lib/node/bar/4.3.2/node_modules/* - Symbolic links to the packages\nthat bar depends on.
  • \n
\n

Thus, even if a cycle is encountered, or if there are dependency\nconflicts, every module will be able to get a version of its dependency\nthat it can use.\n\n

\n

When the code in the foo package does require('bar'), it will get the\nversion that is symlinked into /usr/lib/node/foo/1.2.3/node_modules/bar.\nThen, when the code in the bar package calls require('quux'), it'll get\nthe version that is symlinked into\n/usr/lib/node/bar/4.3.2/node_modules/quux.\n\n

\n

Furthermore, to make the module lookup process even more optimal, rather\nthan putting packages directly in /usr/lib/node, we could put them in\n/usr/lib/node_modules/<name>/<version>. Then Node.js will not bother\nlooking for missing dependencies in /usr/node_modules or /node_modules.\n\n

\n

In order to make modules available to the Node.js REPL, it might be useful to\nalso add the /usr/lib/node_modules folder to the $NODE_PATH environment\nvariable. Since the module lookups using node_modules folders are all\nrelative, and based on the real path of the files making the calls to\nrequire(), the packages themselves can be anywhere.\n\n

\n" }, { "textRaw": "All Together...", "name": "All Together...", "type": "misc", "desc": "

To get the exact filename that will be loaded when require() is called, use\nthe require.resolve() function.\n\n

\n

Putting together all of the above, here is the high-level algorithm\nin pseudocode of what require.resolve does:\n\n

\n
require(X) from module at path Y\n1. If X is a core module,\n   a. return the core module\n   b. STOP\n2. If X begins with './' or '/' or '../'\n   a. LOAD_AS_FILE(Y + X)\n   b. LOAD_AS_DIRECTORY(Y + X)\n3. LOAD_NODE_MODULES(X, dirname(Y))\n4. THROW "not found"\n\nLOAD_AS_FILE(X)\n1. If X is a file, load X as JavaScript text.  STOP\n2. If X.js is a file, load X.js as JavaScript text.  STOP\n3. If X.json is a file, parse X.json to a JavaScript Object.  STOP\n4. If X.node is a file, load X.node as binary addon.  STOP\n\nLOAD_AS_DIRECTORY(X)\n1. If X/package.json is a file,\n   a. Parse X/package.json, and look for "main" field.\n   b. let M = X + (json main field)\n   c. LOAD_AS_FILE(M)\n2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP\n3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP\n4. If X/index.node is a file, load X/index.node as binary addon.  STOP\n\nLOAD_NODE_MODULES(X, START)\n1. let DIRS=NODE_MODULES_PATHS(START)\n2. for each DIR in DIRS:\n   a. LOAD_AS_FILE(DIR/X)\n   b. LOAD_AS_DIRECTORY(DIR/X)\n\nNODE_MODULES_PATHS(START)\n1. let PARTS = path split(START)\n2. let I = count of PARTS - 1\n3. let DIRS = []\n4. while I >= 0,\n   a. if PARTS[I] = "node_modules" CONTINUE\n   c. DIR = path join(PARTS[0 .. I] + "node_modules")\n   b. DIRS = DIRS + DIR\n   c. let I = I - 1\n5. return DIRS
\n" }, { "textRaw": "Caching", "name": "Caching", "type": "misc", "desc": "

Modules are cached after the first time they are loaded. This means\n(among other things) that every call to require('foo') will get\nexactly the same object returned, if it would resolve to the same file.\n\n

\n

Multiple calls to require('foo') may not cause the module code to be\nexecuted multiple times. This is an important feature. With it,\n"partially done" objects can be returned, thus allowing transitive\ndependencies to be loaded even when they would cause cycles.\n\n

\n

If you want to have a module execute code multiple times, then export a\nfunction, and call that function.\n\n

\n", "miscs": [ { "textRaw": "Module Caching Caveats", "name": "Module Caching Caveats", "type": "misc", "desc": "

Modules are cached based on their resolved filename. Since modules may\nresolve to a different filename based on the location of the calling\nmodule (loading from node_modules folders), it is not a guarantee\nthat require('foo') will always return the exact same object, if it\nwould resolve to different files.\n\n

\n" } ] }, { "textRaw": "Core Modules", "name": "Core Modules", "type": "misc", "desc": "

Node.js has several modules compiled into the binary. These modules are\ndescribed in greater detail elsewhere in this documentation.\n\n

\n

The core modules are defined within Node.js's source and are located in the\nlib/ folder.\n\n

\n

Core modules are always preferentially loaded if their identifier is\npassed to require(). For instance, require('http') will always\nreturn the built in HTTP module, even if there is a file by that name.\n\n

\n" }, { "textRaw": "Cycles", "name": "Cycles", "type": "misc", "desc": "

When there are circular require() calls, a module might not have finished\nexecuting when it is returned.\n\n

\n

Consider this situation:\n\n

\n

a.js:\n\n

\n
console.log('a starting');\nexports.done = false;\nconst b = require('./b.js');\nconsole.log('in a, b.done = %j', b.done);\nexports.done = true;\nconsole.log('a done');
\n

b.js:\n\n

\n
console.log('b starting');\nexports.done = false;\nconst a = require('./a.js');\nconsole.log('in b, a.done = %j', a.done);\nexports.done = true;\nconsole.log('b done');
\n

main.js:\n\n

\n
console.log('main starting');\nconst a = require('./a.js');\nconst b = require('./b.js');\nconsole.log('in main, a.done=%j, b.done=%j', a.done, b.done);
\n

When main.js loads a.js, then a.js in turn loads b.js. At that\npoint, b.js tries to load a.js. In order to prevent an infinite\nloop, an unfinished copy of the a.js exports object is returned to the\nb.js module. b.js then finishes loading, and its exports object is\nprovided to the a.js module.\n\n

\n

By the time main.js has loaded both modules, they're both finished.\nThe output of this program would thus be:\n\n

\n
$ node main.js\nmain starting\na starting\nb starting\nin b, a.done = false\nb done\nin a, b.done = true\na done\nin main, a.done=true, b.done=true
\n

If you have cyclic module dependencies in your program, make sure to\nplan accordingly.\n\n

\n" }, { "textRaw": "File Modules", "name": "File Modules", "type": "misc", "desc": "

If the exact filename is not found, then Node.js will attempt to load the\nrequired filename with the added extensions: .js, .json, and finally\n.node.\n\n

\n

.js files are interpreted as JavaScript text files, and .json files are\nparsed as JSON text files. .node files are interpreted as compiled addon\nmodules loaded with dlopen.\n\n

\n

A required module prefixed with '/' is an absolute path to the file. For\nexample, require('/home/marco/foo.js') will load the file at\n/home/marco/foo.js.\n\n

\n

A required module prefixed with './' is relative to the file calling\nrequire(). That is, circle.js must be in the same directory as foo.js for\nrequire('./circle') to find it.\n\n

\n

Without a leading '/', './', or '../' to indicate a file, the module must\neither be a core module or is loaded from a node_modules folder.\n\n

\n

If the given path does not exist, require() will throw an [Error][] with its\ncode property set to 'MODULE_NOT_FOUND'.\n\n

\n" }, { "textRaw": "Folders as Modules", "name": "Folders as Modules", "type": "misc", "desc": "

It is convenient to organize programs and libraries into self-contained\ndirectories, and then provide a single entry point to that library.\nThere are three ways in which a folder may be passed to require() as\nan argument.\n\n

\n

The first is to create a package.json file in the root of the folder,\nwhich specifies a main module. An example package.json file might\nlook like this:\n\n

\n
{ "name" : "some-library",\n  "main" : "./lib/some-library.js" }
\n

If this was in a folder at ./some-library, then\nrequire('./some-library') would attempt to load\n./some-library/lib/some-library.js.\n\n

\n

This is the extent of Node.js's awareness of package.json files.\n\n

\n

If there is no package.json file present in the directory, then Node.js\nwill attempt to load an index.js or index.node file out of that\ndirectory. For example, if there was no package.json file in the above\nexample, then require('./some-library') would attempt to load:\n\n

\n
    \n
  • ./some-library/index.js
  • \n
  • ./some-library/index.node
  • \n
\n" }, { "textRaw": "Loading from `node_modules` Folders", "name": "Loading from `node_modules` Folders", "type": "misc", "desc": "

If the module identifier passed to require() is not a native module,\nand does not begin with '/', '../', or './', then Node.js starts at the\nparent directory of the current module, and adds /node_modules, and\nattempts to load the module from that location. Node will not append\nnode_modules to a path already ending in node_modules.\n\n

\n

If it is not found there, then it moves to the parent directory, and so\non, until the root of the file system is reached.\n\n

\n

For example, if the file at '/home/ry/projects/foo.js' called\nrequire('bar.js'), then Node.js would look in the following locations, in\nthis order:\n\n

\n
    \n
  • /home/ry/projects/node_modules/bar.js
  • \n
  • /home/ry/node_modules/bar.js
  • \n
  • /home/node_modules/bar.js
  • \n
  • /node_modules/bar.js
  • \n
\n

This allows programs to localize their dependencies, so that they do not\nclash.\n\n

\n

You can require specific files or sub modules distributed with a module by\nincluding a path suffix after the module name. For instance\nrequire('example-module/path/to/file') would resolve path/to/file\nrelative to where example-module is located. The suffixed path follows the\nsame module resolution semantics.\n\n

\n" }, { "textRaw": "Loading from the global folders", "name": "Loading from the global folders", "type": "misc", "desc": "

If the NODE_PATH environment variable is set to a colon-delimited list\nof absolute paths, then Node.js will search those paths for modules if they\nare not found elsewhere. (Note: On Windows, NODE_PATH is delimited by\nsemicolons instead of colons.)\n\n

\n

NODE_PATH was originally created to support loading modules from\nvarying paths before the current [module resolution][] algorithm was frozen.\n\n

\n

NODE_PATH is still supported, but is less necessary now that the Node.js\necosystem has settled on a convention for locating dependent modules.\nSometimes deployments that rely on NODE_PATH show surprising behavior\nwhen people are unaware that NODE_PATH must be set. Sometimes a\nmodule's dependencies change, causing a different version (or even a\ndifferent module) to be loaded as the NODE_PATH is searched.\n\n

\n

Additionally, Node.js will search in the following locations:\n\n

\n
    \n
  • 1: $HOME/.node_modules
  • \n
  • 2: $HOME/.node_libraries
  • \n
  • 3: $PREFIX/lib/node
  • \n
\n

Where $HOME is the user's home directory, and $PREFIX is Node.js's\nconfigured node_prefix.\n\n

\n

These are mostly for historic reasons. You are highly encouraged\nto place your dependencies locally in node_modules folders. They\nwill be loaded faster, and more reliably.\n\n

\n" } ], "vars": [ { "textRaw": "The `module` Object", "name": "module", "type": "var", "desc": "

In each module, the module free variable is a reference to the object\nrepresenting the current module. For convenience, module.exports is\nalso accessible via the exports module-global. module isn't actually\na global but rather local to each module.\n\n

\n", "properties": [ { "textRaw": "`children` {Array} ", "name": "children", "desc": "

The module objects required by this one.\n\n

\n" }, { "textRaw": "`exports` {Object} ", "name": "exports", "desc": "

The module.exports object is created by the Module system. Sometimes this is\nnot acceptable; many want their module to be an instance of some class. To do\nthis, assign the desired export object to module.exports. Note that assigning\nthe desired object to exports will simply rebind the local exports variable,\nwhich is probably not what you want to do.\n\n

\n

For example suppose we were making a module called a.js\n\n

\n
const EventEmitter = require('events');\n\nmodule.exports = new EventEmitter();\n\n// Do some work, and after some time emit\n// the 'ready' event from the module itself.\nsetTimeout(() => {\n  module.exports.emit('ready');\n}, 1000);
\n

Then in another file we could do\n\n

\n
const a = require('./a');\na.on('ready', () => {\n  console.log('module a is ready');\n});
\n

Note that assignment to module.exports must be done immediately. It cannot be\ndone in any callbacks. This does not work:\n\n

\n

x.js:\n\n

\n
setTimeout(() => {\n  module.exports = { a: 'hello' };\n}, 0);
\n

y.js:\n\n

\n
const x = require('./x');\nconsole.log(x.a);
\n", "modules": [ { "textRaw": "exports alias", "name": "exports_alias", "desc": "

The exports variable that is available within a module starts as a reference\nto module.exports. As with any variable, if you assign a new value to it, it\nis no longer bound to the previous value.\n\n

\n

To illustrate the behavior, imagine this hypothetical implementation of\nrequire():\n\n

\n
function require(...) {\n  // ...\n  function (module, exports) {\n    // Your module code here\n    exports = some_func;        // re-assigns exports, exports is no longer\n                                // a shortcut, and nothing is exported.\n    module.exports = some_func; // makes your module export 0\n  } (module, module.exports);\n  return module;\n}
\n

As a guideline, if the relationship between exports and module.exports\nseems like magic to you, ignore exports and only use module.exports.\n\n

\n", "type": "module", "displayName": "exports alias" } ] }, { "textRaw": "`filename` {String} ", "name": "filename", "desc": "

The fully resolved filename to the module.\n\n

\n" }, { "textRaw": "`id` {String} ", "name": "id", "desc": "

The identifier for the module. Typically this is the fully resolved\nfilename.\n\n

\n" }, { "textRaw": "`loaded` {Boolean} ", "name": "loaded", "desc": "

Whether or not the module is done loading, or is in the process of\nloading.\n\n

\n" }, { "textRaw": "`parent` {Module Object} ", "name": "parent", "desc": "

The module that first required this one.\n\n

\n" } ], "methods": [ { "textRaw": "module.require(id)", "type": "method", "name": "require", "signatures": [ { "return": { "textRaw": "Return: {Object} `module.exports` from the resolved module ", "name": "return", "type": "Object", "desc": "`module.exports` from the resolved module" }, "params": [ { "textRaw": "`id` {String} ", "name": "id", "type": "String" } ] }, { "params": [ { "name": "id" } ] } ], "desc": "

The module.require method provides a way to load a module as if\nrequire() was called from the original module.\n\n

\n

Note that in order to do this, you must get a reference to the module\nobject. Since require() returns the module.exports, and the module is\ntypically only available within a specific module's code, it must be\nexplicitly exported in order to be used.\n\n

\n" } ] } ], "type": "module", "displayName": "module" } ] } node-v4.2.6/doc/api/modules.markdown000644 000766 000024 00000041576 12650222326 017515 0ustar00iojsstaff000000 000000 # Modules Stability: 3 - Locked Node.js has a simple module loading system. In Node.js, files and modules are in one-to-one correspondence. As an example, `foo.js` loads the module `circle.js` in the same directory. The contents of `foo.js`: const circle = require('./circle.js'); console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); The contents of `circle.js`: const PI = Math.PI; exports.area = function (r) { return PI * r * r; }; exports.circumference = function (r) { return 2 * PI * r; }; The module `circle.js` has exported the functions `area()` and `circumference()`. To add functions and objects to the root of your module, you can add them to the special `exports` object. Variables local to the module will be private, as though the module was wrapped in a function. In this example the variable `PI` is private to `circle.js`. If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to `module.exports` instead of `exports`. Below, `bar.js` makes use of the `square` module, which exports a constructor: const square = require('./square.js'); var mySquare = square(2); console.log(`The area of my square is ${mySquare.area()}`); The `square` module is defined in `square.js`: // assigning to exports will not modify module, must use module.exports module.exports = function(width) { return { area: function() { return width * width; } }; } The module system is implemented in the `require("module")` module. ## Accessing the main module When a file is run directly from Node.js, `require.main` is set to its `module`. That means that you can determine whether a file has been run directly by testing require.main === module For a file `foo.js`, this will be `true` if run via `node foo.js`, but `false` if run by `require('./foo')`. Because `module` provides a `filename` property (normally equivalent to `__filename`), the entry point of the current application can be obtained by checking `require.main.filename`. ## Addenda: Package Manager Tips The semantics of Node.js's `require()` function were designed to be general enough to support a number of reasonable directory structures. Package manager programs such as `dpkg`, `rpm`, and `npm` will hopefully find it possible to build native packages from Node.js modules without modification. Below we give a suggested directory structure that could work: Let's say that we wanted to have the folder at `/usr/lib/node//` hold the contents of a specific version of a package. Packages can depend on one another. In order to install package `foo`, you may have to install a specific version of package `bar`. The `bar` package may itself have dependencies, and in some cases, these dependencies may even collide or form cycles. Since Node.js looks up the `realpath` of any modules it loads (that is, resolves symlinks), and then looks for their dependencies in the `node_modules` folders as described above, this situation is very simple to resolve with the following architecture: * `/usr/lib/node/foo/1.2.3/` - Contents of the `foo` package, version 1.2.3. * `/usr/lib/node/bar/4.3.2/` - Contents of the `bar` package that `foo` depends on. * `/usr/lib/node/foo/1.2.3/node_modules/bar` - Symbolic link to `/usr/lib/node/bar/4.3.2/`. * `/usr/lib/node/bar/4.3.2/node_modules/*` - Symbolic links to the packages that `bar` depends on. Thus, even if a cycle is encountered, or if there are dependency conflicts, every module will be able to get a version of its dependency that it can use. When the code in the `foo` package does `require('bar')`, it will get the version that is symlinked into `/usr/lib/node/foo/1.2.3/node_modules/bar`. Then, when the code in the `bar` package calls `require('quux')`, it'll get the version that is symlinked into `/usr/lib/node/bar/4.3.2/node_modules/quux`. Furthermore, to make the module lookup process even more optimal, rather than putting packages directly in `/usr/lib/node`, we could put them in `/usr/lib/node_modules//`. Then Node.js will not bother looking for missing dependencies in `/usr/node_modules` or `/node_modules`. In order to make modules available to the Node.js REPL, it might be useful to also add the `/usr/lib/node_modules` folder to the `$NODE_PATH` environment variable. Since the module lookups using `node_modules` folders are all relative, and based on the real path of the files making the calls to `require()`, the packages themselves can be anywhere. ## All Together... To get the exact filename that will be loaded when `require()` is called, use the `require.resolve()` function. Putting together all of the above, here is the high-level algorithm in pseudocode of what require.resolve does: require(X) from module at path Y 1. If X is a core module, a. return the core module b. STOP 2. If X begins with './' or '/' or '../' a. LOAD_AS_FILE(Y + X) b. LOAD_AS_DIRECTORY(Y + X) 3. LOAD_NODE_MODULES(X, dirname(Y)) 4. THROW "not found" LOAD_AS_FILE(X) 1. If X is a file, load X as JavaScript text. STOP 2. If X.js is a file, load X.js as JavaScript text. STOP 3. If X.json is a file, parse X.json to a JavaScript Object. STOP 4. If X.node is a file, load X.node as binary addon. STOP LOAD_AS_DIRECTORY(X) 1. If X/package.json is a file, a. Parse X/package.json, and look for "main" field. b. let M = X + (json main field) c. LOAD_AS_FILE(M) 2. If X/index.js is a file, load X/index.js as JavaScript text. STOP 3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP 4. If X/index.node is a file, load X/index.node as binary addon. STOP LOAD_NODE_MODULES(X, START) 1. let DIRS=NODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) NODE_MODULES_PATHS(START) 1. let PARTS = path split(START) 2. let I = count of PARTS - 1 3. let DIRS = [] 4. while I >= 0, a. if PARTS[I] = "node_modules" CONTINUE c. DIR = path join(PARTS[0 .. I] + "node_modules") b. DIRS = DIRS + DIR c. let I = I - 1 5. return DIRS ## Caching Modules are cached after the first time they are loaded. This means (among other things) that every call to `require('foo')` will get exactly the same object returned, if it would resolve to the same file. Multiple calls to `require('foo')` may not cause the module code to be executed multiple times. This is an important feature. With it, "partially done" objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles. If you want to have a module execute code multiple times, then export a function, and call that function. ### Module Caching Caveats Modules are cached based on their resolved filename. Since modules may resolve to a different filename based on the location of the calling module (loading from `node_modules` folders), it is not a *guarantee* that `require('foo')` will always return the exact same object, if it would resolve to different files. ## Core Modules Node.js has several modules compiled into the binary. These modules are described in greater detail elsewhere in this documentation. The core modules are defined within Node.js's source and are located in the `lib/` folder. Core modules are always preferentially loaded if their identifier is passed to `require()`. For instance, `require('http')` will always return the built in HTTP module, even if there is a file by that name. ## Cycles When there are circular `require()` calls, a module might not have finished executing when it is returned. Consider this situation: `a.js`: console.log('a starting'); exports.done = false; const b = require('./b.js'); console.log('in a, b.done = %j', b.done); exports.done = true; console.log('a done'); `b.js`: console.log('b starting'); exports.done = false; const a = require('./a.js'); console.log('in b, a.done = %j', a.done); exports.done = true; console.log('b done'); `main.js`: console.log('main starting'); const a = require('./a.js'); const b = require('./b.js'); console.log('in main, a.done=%j, b.done=%j', a.done, b.done); When `main.js` loads `a.js`, then `a.js` in turn loads `b.js`. At that point, `b.js` tries to load `a.js`. In order to prevent an infinite loop, an **unfinished copy** of the `a.js` exports object is returned to the `b.js` module. `b.js` then finishes loading, and its `exports` object is provided to the `a.js` module. By the time `main.js` has loaded both modules, they're both finished. The output of this program would thus be: $ node main.js main starting a starting b starting in b, a.done = false b done in a, b.done = true a done in main, a.done=true, b.done=true If you have cyclic module dependencies in your program, make sure to plan accordingly. ## File Modules If the exact filename is not found, then Node.js will attempt to load the required filename with the added extensions: `.js`, `.json`, and finally `.node`. `.js` files are interpreted as JavaScript text files, and `.json` files are parsed as JSON text files. `.node` files are interpreted as compiled addon modules loaded with `dlopen`. A required module prefixed with `'/'` is an absolute path to the file. For example, `require('/home/marco/foo.js')` will load the file at `/home/marco/foo.js`. A required module prefixed with `'./'` is relative to the file calling `require()`. That is, `circle.js` must be in the same directory as `foo.js` for `require('./circle')` to find it. Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a `node_modules` folder. If the given path does not exist, `require()` will throw an [`Error`][] with its `code` property set to `'MODULE_NOT_FOUND'`. ## Folders as Modules It is convenient to organize programs and libraries into self-contained directories, and then provide a single entry point to that library. There are three ways in which a folder may be passed to `require()` as an argument. The first is to create a `package.json` file in the root of the folder, which specifies a `main` module. An example package.json file might look like this: { "name" : "some-library", "main" : "./lib/some-library.js" } If this was in a folder at `./some-library`, then `require('./some-library')` would attempt to load `./some-library/lib/some-library.js`. This is the extent of Node.js's awareness of package.json files. If there is no package.json file present in the directory, then Node.js will attempt to load an `index.js` or `index.node` file out of that directory. For example, if there was no package.json file in the above example, then `require('./some-library')` would attempt to load: * `./some-library/index.js` * `./some-library/index.node` ## Loading from `node_modules` Folders If the module identifier passed to `require()` is not a native module, and does not begin with `'/'`, `'../'`, or `'./'`, then Node.js starts at the parent directory of the current module, and adds `/node_modules`, and attempts to load the module from that location. Node will not append `node_modules` to a path already ending in `node_modules`. If it is not found there, then it moves to the parent directory, and so on, until the root of the file system is reached. For example, if the file at `'/home/ry/projects/foo.js'` called `require('bar.js')`, then Node.js would look in the following locations, in this order: * `/home/ry/projects/node_modules/bar.js` * `/home/ry/node_modules/bar.js` * `/home/node_modules/bar.js` * `/node_modules/bar.js` This allows programs to localize their dependencies, so that they do not clash. You can require specific files or sub modules distributed with a module by including a path suffix after the module name. For instance `require('example-module/path/to/file')` would resolve `path/to/file` relative to where `example-module` is located. The suffixed path follows the same module resolution semantics. ## Loading from the global folders If the `NODE_PATH` environment variable is set to a colon-delimited list of absolute paths, then Node.js will search those paths for modules if they are not found elsewhere. (Note: On Windows, `NODE_PATH` is delimited by semicolons instead of colons.) `NODE_PATH` was originally created to support loading modules from varying paths before the current [module resolution][] algorithm was frozen. `NODE_PATH` is still supported, but is less necessary now that the Node.js ecosystem has settled on a convention for locating dependent modules. Sometimes deployments that rely on `NODE_PATH` show surprising behavior when people are unaware that `NODE_PATH` must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the `NODE_PATH` is searched. Additionally, Node.js will search in the following locations: * 1: `$HOME/.node_modules` * 2: `$HOME/.node_libraries` * 3: `$PREFIX/lib/node` Where `$HOME` is the user's home directory, and `$PREFIX` is Node.js's configured `node_prefix`. These are mostly for historic reasons. **You are highly encouraged to place your dependencies locally in `node_modules` folders.** They will be loaded faster, and more reliably. ## The `module` Object * {Object} In each module, the `module` free variable is a reference to the object representing the current module. For convenience, `module.exports` is also accessible via the `exports` module-global. `module` isn't actually a global but rather local to each module. ### module.children * {Array} The module objects required by this one. ### module.exports * {Object} The `module.exports` object is created by the Module system. Sometimes this is not acceptable; many want their module to be an instance of some class. To do this, assign the desired export object to `module.exports`. Note that assigning the desired object to `exports` will simply rebind the local `exports` variable, which is probably not what you want to do. For example suppose we were making a module called `a.js` const EventEmitter = require('events'); module.exports = new EventEmitter(); // Do some work, and after some time emit // the 'ready' event from the module itself. setTimeout(() => { module.exports.emit('ready'); }, 1000); Then in another file we could do const a = require('./a'); a.on('ready', () => { console.log('module a is ready'); }); Note that assignment to `module.exports` must be done immediately. It cannot be done in any callbacks. This does not work: x.js: setTimeout(() => { module.exports = { a: 'hello' }; }, 0); y.js: const x = require('./x'); console.log(x.a); #### exports alias The `exports` variable that is available within a module starts as a reference to `module.exports`. As with any variable, if you assign a new value to it, it is no longer bound to the previous value. To illustrate the behavior, imagine this hypothetical implementation of `require()`: function require(...) { // ... function (module, exports) { // Your module code here exports = some_func; // re-assigns exports, exports is no longer // a shortcut, and nothing is exported. module.exports = some_func; // makes your module export 0 } (module, module.exports); return module; } As a guideline, if the relationship between `exports` and `module.exports` seems like magic to you, ignore `exports` and only use `module.exports`. ### module.filename * {String} The fully resolved filename to the module. ### module.id * {String} The identifier for the module. Typically this is the fully resolved filename. ### module.loaded * {Boolean} Whether or not the module is done loading, or is in the process of loading. ### module.parent * {Module Object} The module that first required this one. ### module.require(id) * `id` {String} * Return: {Object} `module.exports` from the resolved module The `module.require` method provides a way to load a module as if `require()` was called from the original module. Note that in order to do this, you must get a reference to the `module` object. Since `require()` returns the `module.exports`, and the `module` is typically *only* available within a specific module's code, it must be explicitly exported in order to be used. [`Error`]: errors.html#errors_class_error [module resolution]: #modules_all_together node-v4.2.6/doc/api/net.html000644 000766 000024 00000127514 12650222331 015746 0ustar00iojsstaff000000 000000 net Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

net#

Stability: 2 - Stable

The net module provides you with an asynchronous network wrapper. It contains functions for creating both servers and clients (called streams). You can include this module with require('net');.

Class: net.Server#

This class is used to create a TCP or local server.

net.Server is an EventEmitter with the following events:

Event: 'close'#

Emitted when the server closes. Note that if connections exist, this event is not emitted until all connections are ended.

Event: 'connection'#

  • Socket object The connection object

Emitted when a new connection is made. socket is an instance of net.Socket.

Event: 'error'#

  • Error Object

Emitted when an error occurs. The 'close' event will be called directly following this event. See example in discussion of server.listen.

Event: 'listening'#

Emitted when the server has been bound after calling server.listen.

server.address()#

Returns the bound address, the address family name and port of the server as reported by the operating system. Useful to find which port was assigned when giving getting an OS-assigned address. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

Example:

var server = net.createServer((socket) => {
  socket.end('goodbye\n');
});

// grab a random port.
server.listen(() => {
  address = server.address();
  console.log('opened server on %j', address);
});

Don't call server.address() until the 'listening' event has been emitted.

server.close([callback])#

Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a 'close' event. The optional callback will be called once the 'close' event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed.

server.connections#

Stability: 0 - Deprecated: Use server.getConnections instead.

The number of concurrent connections on the server.

This becomes null when sending a socket to a child with child_process.fork(). To poll forks and get current number of active connections use asynchronous server.getConnections instead.

server.getConnections(callback)#

Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks.

Callback should take two arguments err and count.

server.listen(handle[, backlog][, callback])#

  • handle Object
  • backlog Number
  • callback Function

The handle object can be set to either a server or socket (anything with an underlying _handle member), or a {fd: <n>} object.

This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket.

Listening on a file descriptor is not supported on Windows.

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

The parameter backlog behaves the same as in [server.listen(port, \[host\], \[backlog\], \[callback\])][].

server.listen(options[, callback])#

  • options Object - Required. Supports the following properties:
    • port Number - Optional.
    • host String - Optional.
    • backlog Number - Optional.
    • path String - Optional.
    • exclusive Boolean - Optional.
  • callback Function - Optional.

The port, host, and backlog properties of options, as well as the optional callback function, behave as they do on a call to [server.listen(port, \[host\], \[backlog\], \[callback\])][]. Alternatively, the path option can be used to specify a UNIX socket.

If exclusive is false (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When exclusive is true, the handle is not shared, and attempted port sharing results in an error. An example which listens on an exclusive port is shown below.

server.listen({
  host: 'localhost',
  port: 80,
  exclusive: true
});

server.listen(path[, backlog][, callback])#

  • path String
  • backlog Number
  • callback Function

Start a local socket server listening for connections on the given path.

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

On UNIX, the local domain is usually known as the UNIX domain. The path is a filesystem path name. It is subject to the same naming conventions and permissions checks as would be done on file creation, will be visible in the filesystem, and will persist until unlinked.

On Windows, the local domain is implemented using a named pipe. The path must refer to an entry in \\?\pipe\ or \\.\pipe\. Any characters are permitted, but the latter may do some processing of pipe names, such as resolving .. sequences. Despite appearances, the pipe name space is flat. Pipes will not persist, they are removed when the last reference to them is closed. Do not forget JavaScript string escaping requires paths to be specified with double-backslashes, such as:

net.createServer().listen(
    path.join('\\\\?\\pipe', process.cwd(), 'myctl'))

The parameter backlog behaves the same as in [server.listen(port, \[host\], \[backlog\], \[callback\])][].

server.listen(port[, hostname][, backlog][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. The default value of this parameter is 511 (not 512).

This function is asynchronous. When the server has been bound, 'listening' event will be emitted. The last parameter callback will be added as a listener for the 'listening' event.

One issue some users run into is getting EADDRINUSE errors. This means that another server is already running on the requested port. One way of handling this would be to wait a second and then try again. This can be done with

server.on('error', (e) => {
  if (e.code == 'EADDRINUSE') {
    console.log('Address in use, retrying...');
    setTimeout(() => {
      server.close();
      server.listen(PORT, HOST);
    }, 1000);
  }
});

(Note: All sockets in Node.js set SO_REUSEADDR already)

server.maxConnections#

Set this property to reject connections when the server's connection count gets high.

It is not recommended to use this option once a socket has been sent to a child with child_process.fork().

server.ref()#

Opposite of unref, calling ref on a previously unrefd server will not let the program exit if it's the only server left (the default behavior). If the server is refd calling ref again will have no effect.

Returns server.

server.unref()#

Calling unref on a server will allow the program to exit if this is the only active server in the event system. If the server is already unrefd calling unref again will have no effect.

Returns server.

Class: net.Socket#

This object is an abstraction of a TCP or local socket. net.Socket instances implement a duplex Stream interface. They can be created by the user and used as a client (with connect()) or they can be created by Node.js and passed to the user through the 'connection' event of a server.

new net.Socket([options])#

Construct a new socket object.

options is an object with the following defaults:

{ fd: null,
  allowHalfOpen: false,
  readable: false,
  writable: false
}

fd allows you to specify the existing file descriptor of socket. Set readable and/or writable to true to allow reads and/or writes on this socket (NOTE: Works only when fd is passed). About allowHalfOpen, refer to createServer() and 'end' event.

net.Socket instances are EventEmitter with the following events:

Event: 'close'#

  • had_error Boolean true if the socket had a transmission error.

Emitted once the socket is fully closed. The argument had_error is a boolean which says if the socket was closed due to a transmission error.

Event: 'connect'#

Emitted when a socket connection is successfully established. See connect().

Event: 'data'#

  • Buffer object

Emitted when data is received. The argument data will be a Buffer or String. Encoding of data is set by socket.setEncoding(). (See the Readable Stream section for more information.)

Note that the data will be lost if there is no listener when a Socket emits a 'data' event.

Event: 'drain'#

Emitted when the write buffer becomes empty. Can be used to throttle uploads.

See also: the return values of socket.write()

Event: 'end'#

Emitted when the other end of the socket sends a FIN packet.

By default (allowHalfOpen == false) the socket will destroy its file descriptor once it has written out its pending write queue. However, by setting allowHalfOpen == true the socket will not automatically end() its side allowing the user to write arbitrary amounts of data, with the caveat that the user is required to end() their side now.

Event: 'error'#

  • Error object

Emitted when an error occurs. The 'close' event will be called directly following this event.

Event: 'lookup'#

Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets.

  • err {Error | Null} The error object. See dns.lookup().
  • address {String} The IP address.
  • family {String | Null} The address type. See dns.lookup().

Event: 'timeout'#

Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user must manually close the connection.

See also: socket.setTimeout()

socket.address()#

Returns the bound address, the address family name and port of the socket as reported by the operating system. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

socket.bufferSize#

net.Socket has the property that socket.write() always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket - the network connection simply might be too slow. Node.js will internally queue up the data written to a socket and send it out over the wire when it is possible. (Internally it is polling on the socket's file descriptor for being writable).

The consequence of this internal buffering is that memory may grow. This property shows the number of characters currently buffered to be written. (Number of characters is approximately equal to the number of bytes to be written, but the buffer may contain strings, and the strings are lazily encoded, so the exact number of bytes is not known.)

Users who experience large or growing bufferSize should attempt to "throttle" the data flows in their program with pause() and resume().

socket.bytesRead#

The amount of received bytes.

socket.bytesWritten#

The amount of bytes sent.

socket.connect(options[, connectListener])#

Opens the connection for a given socket.

For TCP sockets, options argument should be an object which specifies:

  • port: Port the client should connect to (Required).

  • host: Host the client should connect to. Defaults to 'localhost'.

  • localAddress: Local interface to bind to for network connections.

  • localPort: Local port to bind to for network connections.

  • family : Version of IP stack. Defaults to 4.

  • lookup : Custom lookup function. Defaults to dns.lookup.

For local domain sockets, options argument should be an object which specifies:

  • path: Path the client should connect to (Required).

Normally this method is not needed, as net.createConnection opens the socket. Use this only if you are implementing a custom Socket.

This function is asynchronous. When the 'connect' event is emitted the socket is established. If there is a problem connecting, the 'connect' event will not be emitted, the 'error' event will be emitted with the exception.

The connectListener parameter will be added as a listener for the 'connect' event.

socket.connect(path[, connectListener])#

socket.connect(port[, host][, connectListener])#

As [socket.connect(options\[, connectListener\])][], with options either as either {port: port, host: host} or {path: path}.

socket.destroy()#

Ensures that no more I/O activity happens on this socket. Only necessary in case of errors (parse error or so).

socket.end([data][, encoding])#

Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data.

If data is specified, it is equivalent to calling socket.write(data, encoding) followed by socket.end().

socket.localAddress#

The string representation of the local IP address the remote client is connecting on. For example, if you are listening on '0.0.0.0' and the client connects on '192.168.1.1', the value would be '192.168.1.1'.

socket.localPort#

The numeric representation of the local port. For example, 80 or 21.

socket.pause()#

Pauses the reading of data. That is, 'data' events will not be emitted. Useful to throttle back an upload.

socket.ref()#

Opposite of unref, calling ref on a previously unrefd socket will not let the program exit if it's the only socket left (the default behavior). If the socket is refd calling ref again will have no effect.

Returns socket.

socket.remoteAddress#

The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'. Value may be undefined if the socket is destroyed (for example, if the client disconnected).

socket.remoteFamily#

The string representation of the remote IP family. 'IPv4' or 'IPv6'.

socket.remotePort#

The numeric representation of the remote port. For example, 80 or 21.

socket.resume()#

Resumes reading after a call to pause().

socket.setEncoding([encoding])#

Set the encoding for the socket as a Readable Stream. See stream.setEncoding() for more information.

socket.setKeepAlive([enable][, initialDelay])#

Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket. enable defaults to false.

Set initialDelay (in milliseconds) to set the delay between the last data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting. Defaults to 0.

Returns socket.

socket.setNoDelay([noDelay])#

Disables the Nagle algorithm. By default TCP connections use the Nagle algorithm, they buffer data before sending it off. Setting true for noDelay will immediately fire off data each time socket.write() is called. noDelay defaults to true.

Returns socket.

socket.setTimeout(timeout[, callback])#

Sets the socket to timeout after timeout milliseconds of inactivity on the socket. By default net.Socket do not have a timeout.

When an idle timeout is triggered the socket will receive a 'timeout' event but the connection will not be severed. The user must manually end() or destroy() the socket.

If timeout is 0, then the existing idle timeout is disabled.

The optional callback parameter will be added as a one time listener for the 'timeout' event.

Returns socket.

socket.unref()#

Calling unref on a socket will allow the program to exit if this is the only active socket in the event system. If the socket is already unrefd calling unref again will have no effect.

Returns socket.

socket.write(data[, encoding][, callback])#

Sends data on the socket. The second parameter specifies the encoding in the case of a string--it defaults to UTF8 encoding.

Returns true if the entire data was flushed successfully to the kernel buffer. Returns false if all or part of the data was queued in user memory. 'drain' will be emitted when the buffer is again free.

The optional callback parameter will be executed when the data is finally written out - this may not be immediately.

net.connect(options[, connectListener])#

A factory function, which returns a new net.Socket and automatically connects with the supplied options.

The options are passed to both the net.Socket constructor and the socket.connect method.

The connectListener parameter will be added as a listener for the 'connect' event once.

Here is an example of a client of the previously described echo server:

const net = require('net');
const client = net.connect({port: 8124}, () => { //'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});

To connect on the socket /tmp/echo.sock the second line would just be changed to

const client = net.connect({path: '/tmp/echo.sock'});

net.connect(path[, connectListener])#

A factory function, which returns a new unix net.Socket and automatically connects to the supplied path.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.connect(port[, host][, connectListener])#

A factory function, which returns a new net.Socket and automatically connects to the supplied port and host.

If host is omitted, 'localhost' will be assumed.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createConnection(options[, connectListener])#

A factory function, which returns a new net.Socket and automatically connects with the supplied options.

The options are passed to both the net.Socket constructor and the socket.connect method.

The connectListener parameter will be added as a listener for the 'connect' event once.

Here is an example of a client of the previously described echo server:

const net = require('net');
const client = net.connect({port: 8124},
    () => { //'connect' listener
  console.log('connected to server!');
  client.write('world!\r\n');
});
client.on('data', (data) => {
  console.log(data.toString());
  client.end();
});
client.on('end', () => {
  console.log('disconnected from server');
});

To connect on the socket /tmp/echo.sock the second line would just be changed to

const client = net.connect({path: '/tmp/echo.sock'});

net.createConnection(path[, connectListener])#

A factory function, which returns a new unix net.Socket and automatically connects to the supplied path.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createConnection(port[, host][, connectListener])#

A factory function, which returns a new net.Socket and automatically connects to the supplied port and host.

If host is omitted, 'localhost' will be assumed.

The connectListener parameter will be added as a listener for the 'connect' event once.

net.createServer([options][, connectionListener])#

Creates a new server. The connectionListener argument is automatically set as a listener for the 'connection' event.

options is an object with the following defaults:

{
  allowHalfOpen: false,
  pauseOnConnect: false
}

If allowHalfOpen is true, then the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. The socket becomes non-readable, but still writable. You should call the end() method explicitly. See 'end' event for more information.

If pauseOnConnect is true, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. This allows connections to be passed between processes without any data being read by the original process. To begin reading data from a paused socket, call resume().

Here is an example of an echo server which listens for connections on port 8124:

const net = require('net');
const server = net.createServer((c) => { //'connection' listener
  console.log('client connected');
  c.on('end', () => {
    console.log('client disconnected');
  });
  c.write('hello\r\n');
  c.pipe(c);
});
server.listen(8124, () => { //'listening' listener
  console.log('server bound');
});

Test this by using telnet:

telnet localhost 8124

To listen on the socket /tmp/echo.sock the third line from the last would just be changed to

server.listen('/tmp/echo.sock', () => { //'listening' listener

Use nc to connect to a UNIX domain socket server:

nc -U /tmp/echo.sock

net.isIP(input)#

Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.

net.isIPv4(input)#

Returns true if input is a version 4 IP address, otherwise returns false.

net.isIPv6(input)#

Returns true if input is a version 6 IP address, otherwise returns false.

[server.listen(port, \[host\], \[backlog\], \[callback\])]: #net_server_listen_port_hostname_backlog_callback [socket.connect(options\[, connectListener\])]: #net_socket_connect_options_connectlistener

node-v4.2.6/doc/api/net.json000644 000766 000024 00000140433 12650222331 015746 0ustar00iojsstaff000000 000000 { "source": "doc/api/net.markdown", "modules": [ { "textRaw": "net", "name": "net", "stability": 2, "stabilityText": "Stable", "desc": "

The net module provides you with an asynchronous network wrapper. It contains\nfunctions for creating both servers and clients (called streams). You can include\nthis module with require('net');.\n\n

\n", "classes": [ { "textRaw": "Class: net.Server", "type": "class", "name": "net.Server", "desc": "

This class is used to create a TCP or local server.\n\n

\n

net.Server is an [EventEmitter][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the server closes. Note that if connections exist, this\nevent is not emitted until all connections are ended.\n\n

\n", "params": [] }, { "textRaw": "Event: 'connection'", "type": "event", "name": "connection", "params": [], "desc": "

Emitted when a new connection is made. socket is an instance of\nnet.Socket.\n\n

\n" }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs. The ['close'][] event will be called directly\nfollowing this event. See example in discussion of server.listen.\n\n

\n" }, { "textRaw": "Event: 'listening'", "type": "event", "name": "listening", "desc": "

Emitted when the server has been bound after calling server.listen.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the server\nas reported by the operating system.\nUseful to find which port was assigned when giving getting an OS-assigned address.\nReturns an object with three properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n

Example:\n\n

\n
var server = net.createServer((socket) => {\n  socket.end('goodbye\\n');\n});\n\n// grab a random port.\nserver.listen(() => {\n  address = server.address();\n  console.log('opened server on %j', address);\n});
\n

Don't call server.address() until the 'listening' event has been emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections and keeps existing\nconnections. This function is asynchronous, the server is finally\nclosed when all connections are ended and the server emits a ['close'][] event.\nThe optional callback will be called once the 'close' event occurs. Unlike\nthat event, it will be called with an Error as its only argument if the server\nwas not open when it was closed.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.getConnections(callback)", "type": "method", "name": "getConnections", "desc": "

Asynchronously get the number of concurrent connections on the server. Works\nwhen sockets were sent to forks.\n\n

\n

Callback should take two arguments err and count.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" } ] } ] }, { "textRaw": "server.listen(handle[, backlog][, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`handle` {Object} ", "name": "handle", "type": "Object" }, { "textRaw": "`backlog` {Number} ", "name": "backlog", "type": "Number", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "handle" }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

The handle object can be set to either a server or socket (anything\nwith an underlying _handle member), or a {fd: <n>} object.\n\n

\n

This will cause the server to accept connections on the specified\nhandle, but it is presumed that the file descriptor or handle has\nalready been bound to a port or domain socket.\n\n

\n

Listening on a file descriptor is not supported on Windows.\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted.\nThe last parameter callback will be added as a listener for the\n['listening'][] event.\n\n

\n

The parameter backlog behaves the same as in\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][].\n\n

\n" }, { "textRaw": "server.listen(options[, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`options` {Object} - Required. Supports the following properties: ", "options": [ { "textRaw": "`port` {Number} - Optional. ", "name": "port", "type": "Number", "desc": "Optional." }, { "textRaw": "`host` {String} - Optional. ", "name": "host", "type": "String", "desc": "Optional." }, { "textRaw": "`backlog` {Number} - Optional. ", "name": "backlog", "type": "Number", "desc": "Optional." }, { "textRaw": "`path` {String} - Optional. ", "name": "path", "type": "String", "desc": "Optional." }, { "textRaw": "`exclusive` {Boolean} - Optional. ", "name": "exclusive", "type": "Boolean", "desc": "Optional." } ], "name": "options", "type": "Object", "desc": "Required. Supports the following properties:" }, { "textRaw": "`callback` {Function} - Optional. ", "name": "callback", "type": "Function", "desc": "Optional.", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ], "desc": "

The port, host, and backlog properties of options, as well as the\noptional callback function, behave as they do on a call to\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][]. Alternatively,\nthe path option can be used to specify a UNIX socket.\n\n

\n

If exclusive is false (default), then cluster workers will use the same\nunderlying handle, allowing connection handling duties to be shared. When\nexclusive is true, the handle is not shared, and attempted port sharing\nresults in an error. An example which listens on an exclusive port is\nshown below.\n\n

\n
server.listen({\n  host: 'localhost',\n  port: 80,\n  exclusive: true\n});
\n" }, { "textRaw": "server.listen(path[, backlog][, callback])", "type": "method", "name": "listen", "signatures": [ { "params": [ { "textRaw": "`path` {String} ", "name": "path", "type": "String" }, { "textRaw": "`backlog` {Number} ", "name": "backlog", "type": "Number", "optional": true }, { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Start a local socket server listening for connections on the given path.\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted. The last parameter callback\nwill be added as a listener for the ['listening'][] event.\n\n

\n

On UNIX, the local domain is usually known as the UNIX domain. The path is a\nfilesystem path name. It is subject to the same naming conventions and\npermissions checks as would be done on file creation, will be visible in the\nfilesystem, and will persist until unlinked.\n\n

\n

On Windows, the local domain is implemented using a named pipe. The path must\nrefer to an entry in \\\\?\\pipe\\ or \\\\.\\pipe\\. Any characters are permitted,\nbut the latter may do some processing of pipe names, such as resolving ..\nsequences. Despite appearances, the pipe name space is flat. Pipes will not\npersist, they are removed when the last reference to them is closed. Do not\nforget JavaScript string escaping requires paths to be specified with\ndouble-backslashes, such as:\n\n

\n
net.createServer().listen(\n    path.join('\\\\\\\\?\\\\pipe', process.cwd(), 'myctl'))
\n

The parameter backlog behaves the same as in\n[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])][].\n\n

\n" }, { "textRaw": "server.listen(port[, hostname][, backlog][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

Backlog is the maximum length of the queue of pending connections.\nThe actual length will be determined by your OS through sysctl settings such as\ntcp_max_syn_backlog and somaxconn on linux. The default value of this\nparameter is 511 (not 512).\n\n

\n

This function is asynchronous. When the server has been bound,\n['listening'][] event will be emitted. The last parameter callback\nwill be added as a listener for the ['listening'][] event.\n\n

\n

One issue some users run into is getting EADDRINUSE errors. This means that\nanother server is already running on the requested port. One way of handling this\nwould be to wait a second and then try again. This can be done with\n\n

\n
server.on('error', (e) => {\n  if (e.code == 'EADDRINUSE') {\n    console.log('Address in use, retrying...');\n    setTimeout(() => {\n      server.close();\n      server.listen(PORT, HOST);\n    }, 1000);\n  }\n});
\n

(Note: All sockets in Node.js set SO_REUSEADDR already)\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "backlog", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.ref()", "type": "method", "name": "ref", "desc": "

Opposite of unref, calling ref on a previously unrefd server will not\nlet the program exit if it's the only server left (the default behavior). If\nthe server is refd calling ref again will have no effect.\n\n

\n

Returns server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.unref()", "type": "method", "name": "unref", "desc": "

Calling unref on a server will allow the program to exit if this is the only\nactive server in the event system. If the server is already unrefd calling\nunref again will have no effect.\n\n

\n

Returns server.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "server.connections", "name": "connections", "stability": 0, "stabilityText": "Deprecated: Use [`server.getConnections`][] instead.", "desc": "

The number of concurrent connections on the server.\n\n

\n

This becomes null when sending a socket to a child with\n[child_process.fork()][]. To poll forks and get current number of active\nconnections use asynchronous server.getConnections instead.\n\n

\n" }, { "textRaw": "server.maxConnections", "name": "maxConnections", "desc": "

Set this property to reject connections when the server's connection count gets\nhigh.\n\n

\n

It is not recommended to use this option once a socket has been sent to a child\nwith [child_process.fork()][].\n\n

\n" } ] }, { "textRaw": "Class: net.Socket", "type": "class", "name": "net.Socket", "desc": "

This object is an abstraction of a TCP or local socket. net.Socket\ninstances implement a duplex Stream interface. They can be created by the\nuser and used as a client (with [connect()][]) or they can be created by Node.js\nand passed to the user through the 'connection' event of a server.\n\n

\n", "methods": [ { "textRaw": "new net.Socket([options])", "type": "method", "name": "Socket", "desc": "

Construct a new socket object.\n\n

\n

options is an object with the following defaults:\n\n

\n
{ fd: null,\n  allowHalfOpen: false,\n  readable: false,\n  writable: false\n}
\n

fd allows you to specify the existing file descriptor of socket.\nSet readable and/or writable to true to allow reads and/or writes on this\nsocket (NOTE: Works only when fd is passed).\nAbout allowHalfOpen, refer to createServer() and 'end' event.\n\n

\n

net.Socket instances are [EventEmitter][] with the following events:\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "socket.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nsocket as reported by the operating system. Returns an object with\nthree properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.connect(options[, connectListener])", "type": "method", "name": "connect", "desc": "

Opens the connection for a given socket.\n\n

\n

For TCP sockets, options argument should be an object which specifies:\n\n

\n
    \n
  • port: Port the client should connect to (Required).

    \n
  • \n
  • host: Host the client should connect to. Defaults to 'localhost'.

    \n
  • \n
  • localAddress: Local interface to bind to for network connections.

    \n
  • \n
  • localPort: Local port to bind to for network connections.

    \n
  • \n
  • family : Version of IP stack. Defaults to 4.

    \n
  • \n
  • lookup : Custom lookup function. Defaults to dns.lookup.

    \n
  • \n
\n

For local domain sockets, options argument should be an object which\nspecifies:\n\n

\n
    \n
  • path: Path the client should connect to (Required).
  • \n
\n

Normally this method is not needed, as net.createConnection opens the\nsocket. Use this only if you are implementing a custom Socket.\n\n

\n

This function is asynchronous. When the ['connect'][] event is emitted the\nsocket is established. If there is a problem connecting, the 'connect' event\nwill not be emitted, the ['error'][] event will be emitted with the exception.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event.\n\n

\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.connect(path[, connectListener])", "type": "method", "name": "connect", "desc": "

As [socket.connect(options\\[, connectListener\\])][],\nwith options either as either {port: port, host: host} or {path: path}.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] }, { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.connect(port[, host][, connectListener])", "type": "method", "name": "connect", "desc": "

As [socket.connect(options\\[, connectListener\\])][],\nwith options either as either {port: port, host: host} or {path: path}.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "socket.destroy()", "type": "method", "name": "destroy", "desc": "

Ensures that no more I/O activity happens on this socket. Only necessary in\ncase of errors (parse error or so).\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.end([data][, encoding])", "type": "method", "name": "end", "desc": "

Half-closes the socket. i.e., it sends a FIN packet. It is possible the\nserver will still send some data.\n\n

\n

If data is specified, it is equivalent to calling\nsocket.write(data, encoding) followed by socket.end().\n\n

\n", "signatures": [ { "params": [ { "name": "data", "optional": true }, { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "socket.pause()", "type": "method", "name": "pause", "desc": "

Pauses the reading of data. That is, ['data'][] events will not be emitted.\nUseful to throttle back an upload.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.ref()", "type": "method", "name": "ref", "desc": "

Opposite of unref, calling ref on a previously unrefd socket will not\nlet the program exit if it's the only socket left (the default behavior). If\nthe socket is refd calling ref again will have no effect.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.resume()", "type": "method", "name": "resume", "desc": "

Resumes reading after a call to [pause()][].\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.setEncoding([encoding])", "type": "method", "name": "setEncoding", "desc": "

Set the encoding for the socket as a [Readable Stream][]. See\n[stream.setEncoding()][] for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "encoding", "optional": true } ] } ] }, { "textRaw": "socket.setKeepAlive([enable][, initialDelay])", "type": "method", "name": "setKeepAlive", "desc": "

Enable/disable keep-alive functionality, and optionally set the initial\ndelay before the first keepalive probe is sent on an idle socket.\nenable defaults to false.\n\n

\n

Set initialDelay (in milliseconds) to set the delay between the last\ndata packet received and the first keepalive probe. Setting 0 for\ninitialDelay will leave the value unchanged from the default\n(or previous) setting. Defaults to 0.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "enable", "optional": true }, { "name": "initialDelay", "optional": true } ] } ] }, { "textRaw": "socket.setNoDelay([noDelay])", "type": "method", "name": "setNoDelay", "desc": "

Disables the Nagle algorithm. By default TCP connections use the Nagle\nalgorithm, they buffer data before sending it off. Setting true for\nnoDelay will immediately fire off data each time socket.write() is called.\nnoDelay defaults to true.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "noDelay", "optional": true } ] } ] }, { "textRaw": "socket.setTimeout(timeout[, callback])", "type": "method", "name": "setTimeout", "desc": "

Sets the socket to timeout after timeout milliseconds of inactivity on\nthe socket. By default net.Socket do not have a timeout.\n\n

\n

When an idle timeout is triggered the socket will receive a ['timeout'][]\nevent but the connection will not be severed. The user must manually [end()][]\nor [destroy()][] the socket.\n\n

\n

If timeout is 0, then the existing idle timeout is disabled.\n\n

\n

The optional callback parameter will be added as a one time listener for the\n['timeout'][] event.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [ { "name": "timeout" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "socket.unref()", "type": "method", "name": "unref", "desc": "

Calling unref on a socket will allow the program to exit if this is the only\nactive socket in the event system. If the socket is already unrefd calling\nunref again will have no effect.\n\n

\n

Returns socket.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "socket.write(data[, encoding][, callback])", "type": "method", "name": "write", "desc": "

Sends data on the socket. The second parameter specifies the encoding in the\ncase of a string--it defaults to UTF8 encoding.\n\n

\n

Returns true if the entire data was flushed successfully to the kernel\nbuffer. Returns false if all or part of the data was queued in user memory.\n['drain'][] will be emitted when the buffer is again free.\n\n

\n

The optional callback parameter will be executed when the data is finally\nwritten out - this may not be immediately.\n\n

\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ] } ], "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "params": [], "desc": "

Emitted once the socket is fully closed. The argument had_error is a boolean\nwhich says if the socket was closed due to a transmission error.\n\n

\n" }, { "textRaw": "Event: 'connect'", "type": "event", "name": "connect", "desc": "

Emitted when a socket connection is successfully established.\nSee [connect()][].\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Emitted when data is received. The argument data will be a Buffer or\nString. Encoding of data is set by socket.setEncoding().\n(See the [Readable Stream][] section for more information.)\n\n

\n

Note that the data will be lost if there is no listener when a Socket\nemits a 'data' event.\n\n

\n" }, { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

Emitted when the write buffer becomes empty. Can be used to throttle uploads.\n\n

\n

See also: the return values of socket.write()\n\n

\n", "params": [] }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

Emitted when the other end of the socket sends a FIN packet.\n\n

\n

By default (allowHalfOpen == false) the socket will destroy its file\ndescriptor once it has written out its pending write queue. However, by\nsetting allowHalfOpen == true the socket will not automatically end()\nits side allowing the user to write arbitrary amounts of data, with the\ncaveat that the user is required to end() their side now.\n\n

\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted when an error occurs. The 'close' event will be called directly\nfollowing this event.\n\n

\n" }, { "textRaw": "Event: 'lookup'", "type": "event", "name": "lookup", "desc": "

Emitted after resolving the hostname but before connecting.\nNot applicable to UNIX sockets.\n\n

\n
    \n
  • err {Error | Null} The error object. See [dns.lookup()][].
  • \n
  • address {String} The IP address.
  • \n
  • family {String | Null} The address type. See [dns.lookup()][].
  • \n
\n", "params": [] }, { "textRaw": "Event: 'timeout'", "type": "event", "name": "timeout", "desc": "

Emitted if the socket times out from inactivity. This is only to notify that\nthe socket has been idle. The user must manually close the connection.\n\n

\n

See also: [socket.setTimeout()][]\n\n

\n", "params": [] } ], "properties": [ { "textRaw": "socket.bufferSize", "name": "bufferSize", "desc": "

net.Socket has the property that socket.write() always works. This is to\nhelp users get up and running quickly. The computer cannot always keep up\nwith the amount of data that is written to a socket - the network connection\nsimply might be too slow. Node.js will internally queue up the data written to a\nsocket and send it out over the wire when it is possible. (Internally it is\npolling on the socket's file descriptor for being writable).\n\n

\n

The consequence of this internal buffering is that memory may grow. This\nproperty shows the number of characters currently buffered to be written.\n(Number of characters is approximately equal to the number of bytes to be\nwritten, but the buffer may contain strings, and the strings are lazily\nencoded, so the exact number of bytes is not known.)\n\n

\n

Users who experience large or growing bufferSize should attempt to\n"throttle" the data flows in their program with [pause()][] and [resume()][].\n\n

\n" }, { "textRaw": "socket.bytesRead", "name": "bytesRead", "desc": "

The amount of received bytes.\n\n

\n" }, { "textRaw": "socket.bytesWritten", "name": "bytesWritten", "desc": "

The amount of bytes sent.\n\n

\n" }, { "textRaw": "socket.localAddress", "name": "localAddress", "desc": "

The string representation of the local IP address the remote client is\nconnecting on. For example, if you are listening on '0.0.0.0' and the\nclient connects on '192.168.1.1', the value would be '192.168.1.1'.\n\n

\n" }, { "textRaw": "socket.localPort", "name": "localPort", "desc": "

The numeric representation of the local port. For example,\n80 or 21.\n\n

\n" }, { "textRaw": "socket.remoteAddress", "name": "remoteAddress", "desc": "

The string representation of the remote IP address. For example,\n'74.125.127.100' or '2001:4860:a005::68'. Value may be undefined if\nthe socket is destroyed (for example, if the client disconnected).\n\n

\n" }, { "textRaw": "socket.remoteFamily", "name": "remoteFamily", "desc": "

The string representation of the remote IP family. 'IPv4' or 'IPv6'.\n\n

\n" }, { "textRaw": "socket.remotePort", "name": "remotePort", "desc": "

The numeric representation of the remote port. For example,\n80 or 21.\n\n

\n" } ] } ], "methods": [ { "textRaw": "net.connect(options[, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects with the supplied options.\n\n

\n

The options are passed to both the [net.Socket][] constructor and the\n[socket.connect][] method.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n

Here is an example of a client of the previously described echo server:\n\n

\n
const net = require('net');\nconst client = net.connect({port: 8124}, () => { //'connect' listener\n  console.log('connected to server!');\n  client.write('world!\\r\\n');\n});\nclient.on('data', (data) => {\n  console.log(data.toString());\n  client.end();\n});\nclient.on('end', () => {\n  console.log('disconnected from server');\n});
\n

To connect on the socket /tmp/echo.sock the second line would just be\nchanged to\n\n

\n
const client = net.connect({path: '/tmp/echo.sock'});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.connect(path[, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new unix [net.Socket][] and automatically\nconnects to the supplied path.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.connect(port[, host][, connectListener])", "type": "method", "name": "connect", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects to the supplied port and host.\n\n

\n

If host is omitted, 'localhost' will be assumed.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(options[, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects with the supplied options.\n\n

\n

The options are passed to both the [net.Socket][] constructor and the\n[socket.connect][] method.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n

Here is an example of a client of the previously described echo server:\n\n

\n
const net = require('net');\nconst client = net.connect({port: 8124},\n    () => { //'connect' listener\n  console.log('connected to server!');\n  client.write('world!\\r\\n');\n});\nclient.on('data', (data) => {\n  console.log(data.toString());\n  client.end();\n});\nclient.on('end', () => {\n  console.log('disconnected from server');\n});
\n

To connect on the socket /tmp/echo.sock the second line would just be\nchanged to\n\n

\n
const client = net.connect({path: '/tmp/echo.sock'});
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(path[, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new unix [net.Socket][] and automatically\nconnects to the supplied path.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "path" }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createConnection(port[, host][, connectListener])", "type": "method", "name": "createConnection", "desc": "

A factory function, which returns a new [net.Socket][] and automatically\nconnects to the supplied port and host.\n\n

\n

If host is omitted, 'localhost' will be assumed.\n\n

\n

The connectListener parameter will be added as a listener for the\n['connect'][] event once.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "connectListener", "optional": true } ] } ] }, { "textRaw": "net.createServer([options][, connectionListener])", "type": "method", "name": "createServer", "desc": "

Creates a new server. The connectionListener argument is\nautomatically set as a listener for the ['connection'][] event.\n\n

\n

options is an object with the following defaults:\n\n

\n
{\n  allowHalfOpen: false,\n  pauseOnConnect: false\n}
\n

If allowHalfOpen is true, then the socket won't automatically send a FIN\npacket when the other end of the socket sends a FIN packet. The socket becomes\nnon-readable, but still writable. You should call the [end()][] method explicitly.\nSee ['end'][] event for more information.\n\n

\n

If pauseOnConnect is true, then the socket associated with each incoming\nconnection will be paused, and no data will be read from its handle. This allows\nconnections to be passed between processes without any data being read by the\noriginal process. To begin reading data from a paused socket, call [resume()][].\n\n

\n

Here is an example of an echo server which listens for connections\non port 8124:\n\n

\n
const net = require('net');\nconst server = net.createServer((c) => { //'connection' listener\n  console.log('client connected');\n  c.on('end', () => {\n    console.log('client disconnected');\n  });\n  c.write('hello\\r\\n');\n  c.pipe(c);\n});\nserver.listen(8124, () => { //'listening' listener\n  console.log('server bound');\n});
\n

Test this by using telnet:\n\n

\n
telnet localhost 8124
\n

To listen on the socket /tmp/echo.sock the third line from the last would\njust be changed to\n\n

\n
server.listen('/tmp/echo.sock', () => { //'listening' listener
\n

Use nc to connect to a UNIX domain socket server:\n\n

\n
nc -U /tmp/echo.sock
\n", "signatures": [ { "params": [ { "name": "options", "optional": true }, { "name": "connectionListener", "optional": true } ] } ] }, { "textRaw": "net.isIP(input)", "type": "method", "name": "isIP", "desc": "

Tests if input is an IP address. Returns 0 for invalid strings,\nreturns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses.\n\n\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] }, { "textRaw": "net.isIPv4(input)", "type": "method", "name": "isIPv4", "desc": "

Returns true if input is a version 4 IP address, otherwise returns false.\n\n\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] }, { "textRaw": "net.isIPv6(input)", "type": "method", "name": "isIPv6", "desc": "

Returns true if input is a version 6 IP address, otherwise returns false.\n\n

\n

[server.listen(port, \\[host\\], \\[backlog\\], \\[callback\\])]: #net_server_listen_port_hostname_backlog_callback\n[socket.connect(options\\[, connectListener\\])]: #net_socket_connect_options_connectlistener\n

\n", "signatures": [ { "params": [ { "name": "input" } ] } ] } ], "type": "module", "displayName": "net" } ] } node-v4.2.6/doc/api/net.markdown000644 000766 000024 00000055610 12650222326 016625 0ustar00iojsstaff000000 000000 # net Stability: 2 - Stable The `net` module provides you with an asynchronous network wrapper. It contains functions for creating both servers and clients (called streams). You can include this module with `require('net');`. ## Class: net.Server This class is used to create a TCP or local server. `net.Server` is an [`EventEmitter`][] with the following events: ### Event: 'close' Emitted when the server closes. Note that if connections exist, this event is not emitted until all connections are ended. ### Event: 'connection' * {Socket object} The connection object Emitted when a new connection is made. `socket` is an instance of `net.Socket`. ### Event: 'error' * {Error Object} Emitted when an error occurs. The [`'close'`][] event will be called directly following this event. See example in discussion of `server.listen`. ### Event: 'listening' Emitted when the server has been bound after calling `server.listen`. ### server.address() Returns the bound address, the address family name and port of the server as reported by the operating system. Useful to find which port was assigned when giving getting an OS-assigned address. Returns an object with three properties, e.g. `{ port: 12346, family: 'IPv4', address: '127.0.0.1' }` Example: var server = net.createServer((socket) => { socket.end('goodbye\n'); }); // grab a random port. server.listen(() => { address = server.address(); console.log('opened server on %j', address); }); Don't call `server.address()` until the `'listening'` event has been emitted. ### server.close([callback]) Stops the server from accepting new connections and keeps existing connections. This function is asynchronous, the server is finally closed when all connections are ended and the server emits a [`'close'`][] event. The optional `callback` will be called once the `'close'` event occurs. Unlike that event, it will be called with an Error as its only argument if the server was not open when it was closed. ### server.connections Stability: 0 - Deprecated: Use [`server.getConnections`][] instead. The number of concurrent connections on the server. This becomes `null` when sending a socket to a child with [`child_process.fork()`][]. To poll forks and get current number of active connections use asynchronous `server.getConnections` instead. ### server.getConnections(callback) Asynchronously get the number of concurrent connections on the server. Works when sockets were sent to forks. Callback should take two arguments `err` and `count`. ### server.listen(handle[, backlog][, callback]) * `handle` {Object} * `backlog` {Number} * `callback` {Function} The `handle` object can be set to either a server or socket (anything with an underlying `_handle` member), or a `{fd: }` object. This will cause the server to accept connections on the specified handle, but it is presumed that the file descriptor or handle has already been bound to a port or domain socket. Listening on a file descriptor is not supported on Windows. This function is asynchronous. When the server has been bound, [`'listening'`][] event will be emitted. The last parameter `callback` will be added as a listener for the [`'listening'`][] event. The parameter `backlog` behaves the same as in [`server.listen(port, \[host\], \[backlog\], \[callback\])`][]. ### server.listen(options[, callback]) * `options` {Object} - Required. Supports the following properties: * `port` {Number} - Optional. * `host` {String} - Optional. * `backlog` {Number} - Optional. * `path` {String} - Optional. * `exclusive` {Boolean} - Optional. * `callback` {Function} - Optional. The `port`, `host`, and `backlog` properties of `options`, as well as the optional callback function, behave as they do on a call to [`server.listen(port, \[host\], \[backlog\], \[callback\])`][]. Alternatively, the `path` option can be used to specify a UNIX socket. If `exclusive` is `false` (default), then cluster workers will use the same underlying handle, allowing connection handling duties to be shared. When `exclusive` is `true`, the handle is not shared, and attempted port sharing results in an error. An example which listens on an exclusive port is shown below. server.listen({ host: 'localhost', port: 80, exclusive: true }); ### server.listen(path[, backlog][, callback]) * `path` {String} * `backlog` {Number} * `callback` {Function} Start a local socket server listening for connections on the given `path`. This function is asynchronous. When the server has been bound, [`'listening'`][] event will be emitted. The last parameter `callback` will be added as a listener for the [`'listening'`][] event. On UNIX, the local domain is usually known as the UNIX domain. The path is a filesystem path name. It is subject to the same naming conventions and permissions checks as would be done on file creation, will be visible in the filesystem, and will *persist until unlinked*. On Windows, the local domain is implemented using a named pipe. The path *must* refer to an entry in `\\?\pipe\` or `\\.\pipe\`. Any characters are permitted, but the latter may do some processing of pipe names, such as resolving `..` sequences. Despite appearances, the pipe name space is flat. Pipes will *not persist*, they are removed when the last reference to them is closed. Do not forget JavaScript string escaping requires paths to be specified with double-backslashes, such as: net.createServer().listen( path.join('\\\\?\\pipe', process.cwd(), 'myctl')) The parameter `backlog` behaves the same as in [`server.listen(port, \[host\], \[backlog\], \[callback\])`][]. ### server.listen(port[, hostname][, backlog][, callback]) Begin accepting connections on the specified `port` and `hostname`. If the `hostname` is omitted, the server will accept connections on any IPv6 address (`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. A port value of zero will assign a random port. Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on linux. The default value of this parameter is 511 (not 512). This function is asynchronous. When the server has been bound, [`'listening'`][] event will be emitted. The last parameter `callback` will be added as a listener for the [`'listening'`][] event. One issue some users run into is getting `EADDRINUSE` errors. This means that another server is already running on the requested port. One way of handling this would be to wait a second and then try again. This can be done with server.on('error', (e) => { if (e.code == 'EADDRINUSE') { console.log('Address in use, retrying...'); setTimeout(() => { server.close(); server.listen(PORT, HOST); }, 1000); } }); (Note: All sockets in Node.js set `SO_REUSEADDR` already) ### server.maxConnections Set this property to reject connections when the server's connection count gets high. It is not recommended to use this option once a socket has been sent to a child with [`child_process.fork()`][]. ### server.ref() Opposite of `unref`, calling `ref` on a previously `unref`d server will *not* let the program exit if it's the only server left (the default behavior). If the server is `ref`d calling `ref` again will have no effect. Returns `server`. ### server.unref() Calling `unref` on a server will allow the program to exit if this is the only active server in the event system. If the server is already `unref`d calling `unref` again will have no effect. Returns `server`. ## Class: net.Socket This object is an abstraction of a TCP or local socket. `net.Socket` instances implement a duplex Stream interface. They can be created by the user and used as a client (with [`connect()`][]) or they can be created by Node.js and passed to the user through the `'connection'` event of a server. ### new net.Socket([options]) Construct a new socket object. `options` is an object with the following defaults: { fd: null, allowHalfOpen: false, readable: false, writable: false } `fd` allows you to specify the existing file descriptor of socket. Set `readable` and/or `writable` to `true` to allow reads and/or writes on this socket (NOTE: Works only when `fd` is passed). About `allowHalfOpen`, refer to `createServer()` and `'end'` event. `net.Socket` instances are [`EventEmitter`][] with the following events: ### Event: 'close' * `had_error` {Boolean} `true` if the socket had a transmission error. Emitted once the socket is fully closed. The argument `had_error` is a boolean which says if the socket was closed due to a transmission error. ### Event: 'connect' Emitted when a socket connection is successfully established. See [`connect()`][]. ### Event: 'data' * {Buffer object} Emitted when data is received. The argument `data` will be a `Buffer` or `String`. Encoding of data is set by `socket.setEncoding()`. (See the [Readable Stream][] section for more information.) Note that the __data will be lost__ if there is no listener when a `Socket` emits a `'data'` event. ### Event: 'drain' Emitted when the write buffer becomes empty. Can be used to throttle uploads. See also: the return values of `socket.write()` ### Event: 'end' Emitted when the other end of the socket sends a FIN packet. By default (`allowHalfOpen == false`) the socket will destroy its file descriptor once it has written out its pending write queue. However, by setting `allowHalfOpen == true` the socket will not automatically `end()` its side allowing the user to write arbitrary amounts of data, with the caveat that the user is required to `end()` their side now. ### Event: 'error' * {Error object} Emitted when an error occurs. The `'close'` event will be called directly following this event. ### Event: 'lookup' Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets. * `err` {Error | Null} The error object. See [`dns.lookup()`][]. * `address` {String} The IP address. * `family` {String | Null} The address type. See [`dns.lookup()`][]. ### Event: 'timeout' Emitted if the socket times out from inactivity. This is only to notify that the socket has been idle. The user must manually close the connection. See also: [`socket.setTimeout()`][] ### socket.address() Returns the bound address, the address family name and port of the socket as reported by the operating system. Returns an object with three properties, e.g. `{ port: 12346, family: 'IPv4', address: '127.0.0.1' }` ### socket.bufferSize `net.Socket` has the property that `socket.write()` always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket - the network connection simply might be too slow. Node.js will internally queue up the data written to a socket and send it out over the wire when it is possible. (Internally it is polling on the socket's file descriptor for being writable). The consequence of this internal buffering is that memory may grow. This property shows the number of characters currently buffered to be written. (Number of characters is approximately equal to the number of bytes to be written, but the buffer may contain strings, and the strings are lazily encoded, so the exact number of bytes is not known.) Users who experience large or growing `bufferSize` should attempt to "throttle" the data flows in their program with [`pause()`][] and [`resume()`][]. ### socket.bytesRead The amount of received bytes. ### socket.bytesWritten The amount of bytes sent. ### socket.connect(options[, connectListener]) Opens the connection for a given socket. For TCP sockets, `options` argument should be an object which specifies: - `port`: Port the client should connect to (Required). - `host`: Host the client should connect to. Defaults to `'localhost'`. - `localAddress`: Local interface to bind to for network connections. - `localPort`: Local port to bind to for network connections. - `family` : Version of IP stack. Defaults to `4`. - `lookup` : Custom lookup function. Defaults to `dns.lookup`. For local domain sockets, `options` argument should be an object which specifies: - `path`: Path the client should connect to (Required). Normally this method is not needed, as `net.createConnection` opens the socket. Use this only if you are implementing a custom Socket. This function is asynchronous. When the [`'connect'`][] event is emitted the socket is established. If there is a problem connecting, the `'connect'` event will not be emitted, the [`'error'`][] event will be emitted with the exception. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event. ### socket.connect(path[, connectListener]) ### socket.connect(port[, host][, connectListener]) As [`socket.connect(options\[, connectListener\])`][], with options either as either `{port: port, host: host}` or `{path: path}`. ### socket.destroy() Ensures that no more I/O activity happens on this socket. Only necessary in case of errors (parse error or so). ### socket.end([data][, encoding]) Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data. If `data` is specified, it is equivalent to calling `socket.write(data, encoding)` followed by `socket.end()`. ### socket.localAddress The string representation of the local IP address the remote client is connecting on. For example, if you are listening on `'0.0.0.0'` and the client connects on `'192.168.1.1'`, the value would be `'192.168.1.1'`. ### socket.localPort The numeric representation of the local port. For example, `80` or `21`. ### socket.pause() Pauses the reading of data. That is, [`'data'`][] events will not be emitted. Useful to throttle back an upload. ### socket.ref() Opposite of `unref`, calling `ref` on a previously `unref`d socket will *not* let the program exit if it's the only socket left (the default behavior). If the socket is `ref`d calling `ref` again will have no effect. Returns `socket`. ### socket.remoteAddress The string representation of the remote IP address. For example, `'74.125.127.100'` or `'2001:4860:a005::68'`. Value may be `undefined` if the socket is destroyed (for example, if the client disconnected). ### socket.remoteFamily The string representation of the remote IP family. `'IPv4'` or `'IPv6'`. ### socket.remotePort The numeric representation of the remote port. For example, `80` or `21`. ### socket.resume() Resumes reading after a call to [`pause()`][]. ### socket.setEncoding([encoding]) Set the encoding for the socket as a [Readable Stream][]. See [`stream.setEncoding()`][] for more information. ### socket.setKeepAlive([enable][, initialDelay]) Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket. `enable` defaults to `false`. Set `initialDelay` (in milliseconds) to set the delay between the last data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting. Defaults to `0`. Returns `socket`. ### socket.setNoDelay([noDelay]) Disables the Nagle algorithm. By default TCP connections use the Nagle algorithm, they buffer data before sending it off. Setting `true` for `noDelay` will immediately fire off data each time `socket.write()` is called. `noDelay` defaults to `true`. Returns `socket`. ### socket.setTimeout(timeout[, callback]) Sets the socket to timeout after `timeout` milliseconds of inactivity on the socket. By default `net.Socket` do not have a timeout. When an idle timeout is triggered the socket will receive a [`'timeout'`][] event but the connection will not be severed. The user must manually [`end()`][] or [`destroy()`][] the socket. If `timeout` is 0, then the existing idle timeout is disabled. The optional `callback` parameter will be added as a one time listener for the [`'timeout'`][] event. Returns `socket`. ### socket.unref() Calling `unref` on a socket will allow the program to exit if this is the only active socket in the event system. If the socket is already `unref`d calling `unref` again will have no effect. Returns `socket`. ### socket.write(data[, encoding][, callback]) Sends data on the socket. The second parameter specifies the encoding in the case of a string--it defaults to UTF8 encoding. Returns `true` if the entire data was flushed successfully to the kernel buffer. Returns `false` if all or part of the data was queued in user memory. [`'drain'`][] will be emitted when the buffer is again free. The optional `callback` parameter will be executed when the data is finally written out - this may not be immediately. ## net.connect(options[, connectListener]) A factory function, which returns a new [`net.Socket`][] and automatically connects with the supplied `options`. The options are passed to both the [`net.Socket`][] constructor and the [`socket.connect`][] method. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. Here is an example of a client of the previously described echo server: const net = require('net'); const client = net.connect({port: 8124}, () => { //'connect' listener console.log('connected to server!'); client.write('world!\r\n'); }); client.on('data', (data) => { console.log(data.toString()); client.end(); }); client.on('end', () => { console.log('disconnected from server'); }); To connect on the socket `/tmp/echo.sock` the second line would just be changed to const client = net.connect({path: '/tmp/echo.sock'}); ## net.connect(path[, connectListener]) A factory function, which returns a new unix [`net.Socket`][] and automatically connects to the supplied `path`. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. ## net.connect(port[, host][, connectListener]) A factory function, which returns a new [`net.Socket`][] and automatically connects to the supplied `port` and `host`. If `host` is omitted, `'localhost'` will be assumed. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. ## net.createConnection(options[, connectListener]) A factory function, which returns a new [`net.Socket`][] and automatically connects with the supplied `options`. The options are passed to both the [`net.Socket`][] constructor and the [`socket.connect`][] method. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. Here is an example of a client of the previously described echo server: const net = require('net'); const client = net.connect({port: 8124}, () => { //'connect' listener console.log('connected to server!'); client.write('world!\r\n'); }); client.on('data', (data) => { console.log(data.toString()); client.end(); }); client.on('end', () => { console.log('disconnected from server'); }); To connect on the socket `/tmp/echo.sock` the second line would just be changed to const client = net.connect({path: '/tmp/echo.sock'}); ## net.createConnection(path[, connectListener]) A factory function, which returns a new unix [`net.Socket`][] and automatically connects to the supplied `path`. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. ## net.createConnection(port[, host][, connectListener]) A factory function, which returns a new [`net.Socket`][] and automatically connects to the supplied `port` and `host`. If `host` is omitted, `'localhost'` will be assumed. The `connectListener` parameter will be added as a listener for the [`'connect'`][] event once. ## net.createServer([options][, connectionListener]) Creates a new server. The `connectionListener` argument is automatically set as a listener for the [`'connection'`][] event. `options` is an object with the following defaults: { allowHalfOpen: false, pauseOnConnect: false } If `allowHalfOpen` is `true`, then the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. The socket becomes non-readable, but still writable. You should call the [`end()`][] method explicitly. See [`'end'`][] event for more information. If `pauseOnConnect` is `true`, then the socket associated with each incoming connection will be paused, and no data will be read from its handle. This allows connections to be passed between processes without any data being read by the original process. To begin reading data from a paused socket, call [`resume()`][]. Here is an example of an echo server which listens for connections on port 8124: const net = require('net'); const server = net.createServer((c) => { //'connection' listener console.log('client connected'); c.on('end', () => { console.log('client disconnected'); }); c.write('hello\r\n'); c.pipe(c); }); server.listen(8124, () => { //'listening' listener console.log('server bound'); }); Test this by using `telnet`: telnet localhost 8124 To listen on the socket `/tmp/echo.sock` the third line from the last would just be changed to server.listen('/tmp/echo.sock', () => { //'listening' listener Use `nc` to connect to a UNIX domain socket server: nc -U /tmp/echo.sock ## net.isIP(input) Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses. ## net.isIPv4(input) Returns true if input is a version 4 IP address, otherwise returns false. ## net.isIPv6(input) Returns true if input is a version 6 IP address, otherwise returns false. [`'close'`]: #net_event_close [`'connect'`]: #net_event_connect [`'connection'`]: #net_event_connection [`'data'`]: #net_event_data [`'drain'`]: #net_event_drain [`'end'`]: #net_event_end [`'error'`]: #net_event_error_1 [`'listening'`]: #net_event_listening [`'timeout'`]: #net_event_timeout [`child_process.fork()`]: child_process.html#child_process_child_process_fork_modulepath_args_options [`connect()`]: #net_socket_connect_options_connectlistener [`destroy()`]: #net_socket_destroy [`dns.lookup()`]: dns.html#dns_dns_lookup_hostname_options_callback [`end()`]: #net_socket_end_data_encoding [`EventEmitter`]: events.html#events_class_events_eventemitter [`net.Socket`]: #net_class_net_socket [`pause()`]: #net_socket_pause [`resume()`]: #net_socket_resume [`server.getConnections`]: #net_server_getconnections_callback [`server.listen(port, \[host\], \[backlog\], \[callback\])`]: #net_server_listen_port_hostname_backlog_callback [`socket.connect(options\[, connectListener\])`]: #net_socket_connect_options_connectlistener [`socket.connect`]: #net_socket_connect_options_connectlistener [`socket.setTimeout()`]: #net_socket_settimeout_timeout_callback [`stream.setEncoding()`]: stream.html#stream_readable_setencoding_encoding [Readable Stream]: stream.html#stream_class_stream_readable node-v4.2.6/doc/api/os.html000644 000766 000024 00000025536 12650222331 015602 0ustar00iojsstaff000000 000000 OS Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


OS#

Stability: 2 - Stable

Provides a few basic operating-system related utility functions.

Use require('os') to access this module.

os.EOL#

A constant defining the appropriate End-of-line marker for the operating system.

os.arch()#

Returns the operating system CPU architecture. Possible values are 'x64', 'arm' and 'ia32'. Returns the value of process.arch.

os.cpus()#

Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of milliseconds the CPU/core spent in: user, nice, sys, idle, and irq).

Example inspection of os.cpus:

[ { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 252020,
       nice: 0,
       sys: 30340,
       idle: 1070356870,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 306960,
       nice: 0,
       sys: 26980,
       idle: 1071569080,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 248450,
       nice: 0,
       sys: 21750,
       idle: 1070919370,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 256880,
       nice: 0,
       sys: 19430,
       idle: 1070905480,
       irq: 20 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 511580,
       nice: 20,
       sys: 40900,
       idle: 1070842510,
       irq: 0 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 291660,
       nice: 0,
       sys: 34360,
       idle: 1070888000,
       irq: 10 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 308260,
       nice: 0,
       sys: 55410,
       idle: 1071129970,
       irq: 880 } },
  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',
    speed: 2926,
    times:
     { user: 266450,
       nice: 1480,
       sys: 34920,
       idle: 1072572010,
       irq: 30 } } ]

Note that since nice values are UNIX centric in Windows the nice values of all processors are always 0.

os.endianness()#

Returns the endianness of the CPU. Possible values are 'BE' for big endian or 'LE' for little endian.

os.freemem()#

Returns the amount of free system memory in bytes.

os.homedir()#

Returns the home directory of the current user.

os.hostname()#

Returns the hostname of the operating system.

os.loadavg()#

Returns an array containing the 1, 5, and 15 minute load averages.

The load average is a measure of system activity, calculated by the operating system and expressed as a fractional number. As a rule of thumb, the load average should ideally be less than the number of logical CPUs in the system.

The load average is a very UNIX-y concept; there is no real equivalent on Windows platforms. That is why this function always returns [0, 0, 0] on Windows.

os.networkInterfaces()#

Get a list of network interfaces:

{ lo:
   [ { address: '127.0.0.1',
       netmask: '255.0.0.0',
       family: 'IPv4',
       mac: '00:00:00:00:00:00',
       internal: true },
     { address: '::1',
       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
       family: 'IPv6',
       mac: '00:00:00:00:00:00',
       internal: true } ],
  eth0:
   [ { address: '192.168.1.108',
       netmask: '255.255.255.0',
       family: 'IPv4',
       mac: '01:02:03:0a:0b:0c',
       internal: false },
     { address: 'fe80::a00:27ff:fe4e:66a1',
       netmask: 'ffff:ffff:ffff:ffff::',
       family: 'IPv6',
       mac: '01:02:03:0a:0b:0c',
       internal: false } ] }

Note that due to the underlying implementation this will only return network interfaces that have been assigned an address.

os.platform()#

Returns the operating system platform. Possible values are 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'. Returns the value of process.platform.

os.release()#

Returns the operating system release.

os.tmpdir()#

Returns the operating system's default directory for temporary files.

os.totalmem()#

Returns the total amount of system memory in bytes.

os.type()#

Returns the operating system name. For example 'Linux' on Linux, 'Darwin' on OS X and 'Windows_NT' on Windows.

os.uptime()#

Returns the system uptime in seconds.

node-v4.2.6/doc/api/os.json000644 000766 000024 00000021042 12650222331 015573 0ustar00iojsstaff000000 000000 { "source": "doc/api/os.markdown", "modules": [ { "textRaw": "OS", "name": "os", "stability": 2, "stabilityText": "Stable", "desc": "

Provides a few basic operating-system related utility functions.\n\n

\n

Use require('os') to access this module.\n\n

\n", "properties": [ { "textRaw": "os.EOL", "name": "EOL", "desc": "

A constant defining the appropriate End-of-line marker for the operating\nsystem.\n\n

\n" } ], "methods": [ { "textRaw": "os.arch()", "type": "method", "name": "arch", "desc": "

Returns the operating system CPU architecture. Possible values are 'x64',\n'arm' and 'ia32'. Returns the value of process.arch.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.cpus()", "type": "method", "name": "cpus", "desc": "

Returns an array of objects containing information about each CPU/core\ninstalled: model, speed (in MHz), and times (an object containing the number of\nmilliseconds the CPU/core spent in: user, nice, sys, idle, and irq).\n\n

\n

Example inspection of os.cpus:\n\n

\n
[ { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 252020,\n       nice: 0,\n       sys: 30340,\n       idle: 1070356870,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 306960,\n       nice: 0,\n       sys: 26980,\n       idle: 1071569080,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 248450,\n       nice: 0,\n       sys: 21750,\n       idle: 1070919370,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 256880,\n       nice: 0,\n       sys: 19430,\n       idle: 1070905480,\n       irq: 20 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 511580,\n       nice: 20,\n       sys: 40900,\n       idle: 1070842510,\n       irq: 0 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 291660,\n       nice: 0,\n       sys: 34360,\n       idle: 1070888000,\n       irq: 10 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 308260,\n       nice: 0,\n       sys: 55410,\n       idle: 1071129970,\n       irq: 880 } },\n  { model: 'Intel(R) Core(TM) i7 CPU         860  @ 2.80GHz',\n    speed: 2926,\n    times:\n     { user: 266450,\n       nice: 1480,\n       sys: 34920,\n       idle: 1072572010,\n       irq: 30 } } ]
\n

Note that since nice values are UNIX centric in Windows the nice values of\nall processors are always 0.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.endianness()", "type": "method", "name": "endianness", "desc": "

Returns the endianness of the CPU. Possible values are 'BE' for big endian\nor 'LE' for little endian.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.freemem()", "type": "method", "name": "freemem", "desc": "

Returns the amount of free system memory in bytes.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.homedir()", "type": "method", "name": "homedir", "desc": "

Returns the home directory of the current user.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.hostname()", "type": "method", "name": "hostname", "desc": "

Returns the hostname of the operating system.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.loadavg()", "type": "method", "name": "loadavg", "desc": "

Returns an array containing the 1, 5, and 15 minute load averages.\n\n

\n

The load average is a measure of system activity, calculated by the operating\nsystem and expressed as a fractional number. As a rule of thumb, the load\naverage should ideally be less than the number of logical CPUs in the system.\n\n

\n

The load average is a very UNIX-y concept; there is no real equivalent on\nWindows platforms. That is why this function always returns [0, 0, 0] on\nWindows.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.networkInterfaces()", "type": "method", "name": "networkInterfaces", "desc": "

Get a list of network interfaces:\n\n

\n
{ lo:\n   [ { address: '127.0.0.1',\n       netmask: '255.0.0.0',\n       family: 'IPv4',\n       mac: '00:00:00:00:00:00',\n       internal: true },\n     { address: '::1',\n       netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',\n       family: 'IPv6',\n       mac: '00:00:00:00:00:00',\n       internal: true } ],\n  eth0:\n   [ { address: '192.168.1.108',\n       netmask: '255.255.255.0',\n       family: 'IPv4',\n       mac: '01:02:03:0a:0b:0c',\n       internal: false },\n     { address: 'fe80::a00:27ff:fe4e:66a1',\n       netmask: 'ffff:ffff:ffff:ffff::',\n       family: 'IPv6',\n       mac: '01:02:03:0a:0b:0c',\n       internal: false } ] }
\n

Note that due to the underlying implementation this will only return network\ninterfaces that have been assigned an address.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.platform()", "type": "method", "name": "platform", "desc": "

Returns the operating system platform. Possible values are 'darwin',\n'freebsd', 'linux', 'sunos' or 'win32'. Returns the value of\nprocess.platform.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.release()", "type": "method", "name": "release", "desc": "

Returns the operating system release.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.tmpdir()", "type": "method", "name": "tmpdir", "desc": "

Returns the operating system's default directory for temporary files.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.totalmem()", "type": "method", "name": "totalmem", "desc": "

Returns the total amount of system memory in bytes.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.type()", "type": "method", "name": "type", "desc": "

Returns the operating system name. For example 'Linux' on Linux, 'Darwin'\non OS X and 'Windows_NT' on Windows.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "os.uptime()", "type": "method", "name": "uptime", "desc": "

Returns the system uptime in seconds.\n

\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "OS" } ] } node-v4.2.6/doc/api/os.markdown000644 000766 000024 00000011354 12650222326 016455 0ustar00iojsstaff000000 000000 # OS Stability: 2 - Stable Provides a few basic operating-system related utility functions. Use `require('os')` to access this module. ## os.EOL A constant defining the appropriate End-of-line marker for the operating system. ## os.arch() Returns the operating system CPU architecture. Possible values are `'x64'`, `'arm'` and `'ia32'`. Returns the value of `process.arch`. ## os.cpus() Returns an array of objects containing information about each CPU/core installed: model, speed (in MHz), and times (an object containing the number of milliseconds the CPU/core spent in: user, nice, sys, idle, and irq). Example inspection of os.cpus: [ { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 252020, nice: 0, sys: 30340, idle: 1070356870, irq: 0 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 306960, nice: 0, sys: 26980, idle: 1071569080, irq: 0 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 248450, nice: 0, sys: 21750, idle: 1070919370, irq: 0 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 256880, nice: 0, sys: 19430, idle: 1070905480, irq: 20 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 511580, nice: 20, sys: 40900, idle: 1070842510, irq: 0 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 291660, nice: 0, sys: 34360, idle: 1070888000, irq: 10 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 308260, nice: 0, sys: 55410, idle: 1071129970, irq: 880 } }, { model: 'Intel(R) Core(TM) i7 CPU 860 @ 2.80GHz', speed: 2926, times: { user: 266450, nice: 1480, sys: 34920, idle: 1072572010, irq: 30 } } ] Note that since `nice` values are UNIX centric in Windows the `nice` values of all processors are always 0. ## os.endianness() Returns the endianness of the CPU. Possible values are `'BE'` for big endian or `'LE'` for little endian. ## os.freemem() Returns the amount of free system memory in bytes. ## os.homedir() Returns the home directory of the current user. ## os.hostname() Returns the hostname of the operating system. ## os.loadavg() Returns an array containing the 1, 5, and 15 minute load averages. The load average is a measure of system activity, calculated by the operating system and expressed as a fractional number. As a rule of thumb, the load average should ideally be less than the number of logical CPUs in the system. The load average is a very UNIX-y concept; there is no real equivalent on Windows platforms. That is why this function always returns `[0, 0, 0]` on Windows. ## os.networkInterfaces() Get a list of network interfaces: { lo: [ { address: '127.0.0.1', netmask: '255.0.0.0', family: 'IPv4', mac: '00:00:00:00:00:00', internal: true }, { address: '::1', netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', family: 'IPv6', mac: '00:00:00:00:00:00', internal: true } ], eth0: [ { address: '192.168.1.108', netmask: '255.255.255.0', family: 'IPv4', mac: '01:02:03:0a:0b:0c', internal: false }, { address: 'fe80::a00:27ff:fe4e:66a1', netmask: 'ffff:ffff:ffff:ffff::', family: 'IPv6', mac: '01:02:03:0a:0b:0c', internal: false } ] } Note that due to the underlying implementation this will only return network interfaces that have been assigned an address. ## os.platform() Returns the operating system platform. Possible values are `'darwin'`, `'freebsd'`, `'linux'`, `'sunos'` or `'win32'`. Returns the value of `process.platform`. ## os.release() Returns the operating system release. ## os.tmpdir() Returns the operating system's default directory for temporary files. ## os.totalmem() Returns the total amount of system memory in bytes. ## os.type() Returns the operating system name. For example `'Linux'` on Linux, `'Darwin'` on OS X and `'Windows_NT'` on Windows. ## os.uptime() Returns the system uptime in seconds. node-v4.2.6/doc/api/path.html000644 000766 000024 00000035064 12650222331 016112 0ustar00iojsstaff000000 000000 Path Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Path#

Stability: 2 - Stable

This module contains utilities for handling and transforming file paths. Almost all these methods perform only string transformations. The file system is not consulted to check whether paths are valid.

Use require('path') to use this module. The following methods are provided:

path.basename(p[, ext])#

Return the last portion of a path. Similar to the Unix basename command.

Example:

path.basename('/foo/bar/baz/asdf/quux.html')
// returns
'quux.html'

path.basename('/foo/bar/baz/asdf/quux.html', '.html')
// returns
'quux'

path.delimiter#

The platform-specific path delimiter, ; or ':'.

An example on *nix:

console.log(process.env.PATH)
// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'

process.env.PATH.split(path.delimiter)
// returns
['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']

An example on Windows:

console.log(process.env.PATH)
// 'C:\Windows\system32;C:\Windows;C:\Program Files\node\'

process.env.PATH.split(path.delimiter)
// returns
['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\']

path.dirname(p)#

Return the directory name of a path. Similar to the Unix dirname command.

Example:

path.dirname('/foo/bar/baz/asdf/quux')
// returns
'/foo/bar/baz/asdf'

path.extname(p)#

Return the extension of the path, from the last '.' to end of string in the last portion of the path. If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string. Examples:

path.extname('index.html')
// returns
'.html'

path.extname('index.coffee.md')
// returns
'.md'

path.extname('index.')
// returns
'.'

path.extname('index')
// returns
''

path.extname('.index')
// returns
''

path.format(pathObject)#

Returns a path string from an object, the opposite of path.parse above.

path.format({
    root : "/",
    dir : "/home/user/dir",
    base : "file.txt",
    ext : ".txt",
    name : "file"
})
// returns
'/home/user/dir/file.txt'

path.isAbsolute(path)#

Determines whether path is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory.

Posix examples:

path.isAbsolute('/foo/bar') // true
path.isAbsolute('/baz/..')  // true
path.isAbsolute('qux/')     // false
path.isAbsolute('.')        // false

Windows examples:

path.isAbsolute('//server')  // true
path.isAbsolute('C:/foo/..') // true
path.isAbsolute('bar\\baz')  // false
path.isAbsolute('.')         // false

Note: If the path string passed as parameter is a zero-length string, unlike other path module functions, it will be used as-is and false will be returned.

path.join([path1][, path2][, ...])#

Join all arguments together and normalize the resulting path.

Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown.

Example:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// returns
'/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws exception
TypeError: Arguments to path.join must be strings

Note: If the arguments to join have zero-length strings, unlike other path module functions, they will be ignored. If the joined path string is a zero-length string then '.' will be returned, which represents the current working directory.

path.normalize(p)#

Normalize a string path, taking care of '..' and '.' parts.

When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used.

Example:

path.normalize('/foo/bar//baz/asdf/quux/..')
// returns
'/foo/bar/baz/asdf'

Note: If the path string passed as argument is a zero-length string then '.' will be returned, which represents the current working directory.

path.parse(pathString)#

Returns an object from a path string.

An example on *nix:

path.parse('/home/user/dir/file.txt')
// returns
{
    root : "/",
    dir : "/home/user/dir",
    base : "file.txt",
    ext : ".txt",
    name : "file"
}

An example on Windows:

path.parse('C:\\path\\dir\\index.html')
// returns
{
    root : "C:\\",
    dir : "C:\\path\\dir",
    base : "index.html",
    ext : ".html",
    name : "index"
}

path.posix#

Provide access to aforementioned path methods but always interact in a posix compatible way.

path.relative(from, to)#

Solve the relative path from from to to.

At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve, which means we see that:

path.resolve(from, path.relative(from, to)) == path.resolve(to)

Examples:

path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb')
// returns
'..\\..\\impl\\bbb'

path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')
// returns
'../../impl/bbb'

Note: If the arguments to relative have zero-length strings then the current working directory will be used instead of the zero-length strings. If both the paths are the same then a zero-length string will be returned.

path.resolve([from ...], to)#

Resolves to to an absolute path.

If to isn't already absolute from arguments are prepended in right to left order, until an absolute path is found. If after using all from paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. Non-string from arguments are ignored.

Another way to think of it is as a sequence of cd commands in a shell.

path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')

Is similar to:

cd foo/bar
cd /tmp/file/
cd ..
cd a/../subfile
pwd

The difference is that the different paths don't need to exist and may also be files.

Examples:

path.resolve('/foo/bar', './baz')
// returns
'/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/')
// returns
'/tmp/file'

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')
// if currently in /home/myself/node, it returns
'/home/myself/node/wwwroot/static_files/gif/image.gif'

Note: If the arguments to resolve have zero-length strings then the current working directory will be used instead of them.

path.sep#

The platform-specific file separator. '\\' or '/'.

An example on *nix:

'foo/bar/baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

An example on Windows:

'foo\\bar\\baz'.split(path.sep)
// returns
['foo', 'bar', 'baz']

path.win32#

Provide access to aforementioned path methods but always interact in a win32 compatible way.

node-v4.2.6/doc/api/path.json000644 000766 000024 00000031533 12650222331 016114 0ustar00iojsstaff000000 000000 { "source": "doc/api/path.markdown", "modules": [ { "textRaw": "Path", "name": "path", "stability": 2, "stabilityText": "Stable", "desc": "

This module contains utilities for handling and transforming file\npaths. Almost all these methods perform only string transformations.\nThe file system is not consulted to check whether paths are valid.\n\n

\n

Use require('path') to use this module. The following methods are provided:\n\n

\n", "methods": [ { "textRaw": "path.basename(p[, ext])", "type": "method", "name": "basename", "desc": "

Return the last portion of a path. Similar to the Unix basename command.\n\n

\n

Example:\n\n

\n
path.basename('/foo/bar/baz/asdf/quux.html')\n// returns\n'quux.html'\n\npath.basename('/foo/bar/baz/asdf/quux.html', '.html')\n// returns\n'quux'
\n", "signatures": [ { "params": [ { "name": "p" }, { "name": "ext", "optional": true } ] } ] }, { "textRaw": "path.dirname(p)", "type": "method", "name": "dirname", "desc": "

Return the directory name of a path. Similar to the Unix dirname command.\n\n

\n

Example:\n\n

\n
path.dirname('/foo/bar/baz/asdf/quux')\n// returns\n'/foo/bar/baz/asdf'
\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.extname(p)", "type": "method", "name": "extname", "desc": "

Return the extension of the path, from the last '.' to end of string\nin the last portion of the path. If there is no '.' in the last portion\nof the path or the first character of it is '.', then it returns\nan empty string. Examples:\n\n

\n
path.extname('index.html')\n// returns\n'.html'\n\npath.extname('index.coffee.md')\n// returns\n'.md'\n\npath.extname('index.')\n// returns\n'.'\n\npath.extname('index')\n// returns\n''\n\npath.extname('.index')\n// returns\n''
\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.format(pathObject)", "type": "method", "name": "format", "desc": "

Returns a path string from an object, the opposite of path.parse above.\n\n

\n
path.format({\n    root : "/",\n    dir : "/home/user/dir",\n    base : "file.txt",\n    ext : ".txt",\n    name : "file"\n})\n// returns\n'/home/user/dir/file.txt'
\n", "signatures": [ { "params": [ { "name": "pathObject" } ] } ] }, { "textRaw": "path.isAbsolute(path)", "type": "method", "name": "isAbsolute", "desc": "

Determines whether path is an absolute path. An absolute path will always\nresolve to the same location, regardless of the working directory.\n\n

\n

Posix examples:\n\n

\n
path.isAbsolute('/foo/bar') // true\npath.isAbsolute('/baz/..')  // true\npath.isAbsolute('qux/')     // false\npath.isAbsolute('.')        // false
\n

Windows examples:\n\n

\n
path.isAbsolute('//server')  // true\npath.isAbsolute('C:/foo/..') // true\npath.isAbsolute('bar\\\\baz')  // false\npath.isAbsolute('.')         // false
\n

Note: If the path string passed as parameter is a zero-length string, unlike\n other path module functions, it will be used as-is and false will be\n returned.\n\n

\n", "signatures": [ { "params": [ { "name": "path" } ] } ] }, { "textRaw": "path.join([path1][, path2][, ...])", "type": "method", "name": "join", "desc": "

Join all arguments together and normalize the resulting path.\n\n

\n

Arguments must be strings. In v0.8, non-string arguments were\nsilently ignored. In v0.10 and up, an exception is thrown.\n\n

\n

Example:\n\n

\n
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')\n// returns\n'/foo/bar/baz/asdf'\n\npath.join('foo', {}, 'bar')\n// throws exception\nTypeError: Arguments to path.join must be strings
\n

Note: If the arguments to join have zero-length strings, unlike other path\n module functions, they will be ignored. If the joined path string is a\n zero-length string then '.' will be returned, which represents the\n current working directory.\n\n

\n", "signatures": [ { "params": [ { "name": "path1", "optional": true }, { "name": "path2", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "path.normalize(p)", "type": "method", "name": "normalize", "desc": "

Normalize a string path, taking care of '..' and '.' parts.\n\n

\n

When multiple slashes are found, they're replaced by a single one;\nwhen the path contains a trailing slash, it is preserved.\nOn Windows backslashes are used.\n\n

\n

Example:\n\n

\n
path.normalize('/foo/bar//baz/asdf/quux/..')\n// returns\n'/foo/bar/baz/asdf'
\n

Note: If the path string passed as argument is a zero-length string then '.'\n will be returned, which represents the current working directory.\n\n

\n", "signatures": [ { "params": [ { "name": "p" } ] } ] }, { "textRaw": "path.parse(pathString)", "type": "method", "name": "parse", "desc": "

Returns an object from a path string.\n\n

\n

An example on *nix:\n\n

\n
path.parse('/home/user/dir/file.txt')\n// returns\n{\n    root : "/",\n    dir : "/home/user/dir",\n    base : "file.txt",\n    ext : ".txt",\n    name : "file"\n}
\n

An example on Windows:\n\n

\n
path.parse('C:\\\\path\\\\dir\\\\index.html')\n// returns\n{\n    root : "C:\\\\",\n    dir : "C:\\\\path\\\\dir",\n    base : "index.html",\n    ext : ".html",\n    name : "index"\n}
\n", "signatures": [ { "params": [ { "name": "pathString" } ] } ] }, { "textRaw": "path.relative(from, to)", "type": "method", "name": "relative", "desc": "

Solve the relative path from from to to.\n\n

\n

At times we have two absolute paths, and we need to derive the relative\npath from one to the other. This is actually the reverse transform of\npath.resolve, which means we see that:\n\n

\n
path.resolve(from, path.relative(from, to)) == path.resolve(to)
\n

Examples:\n\n

\n
path.relative('C:\\\\orandea\\\\test\\\\aaa', 'C:\\\\orandea\\\\impl\\\\bbb')\n// returns\n'..\\\\..\\\\impl\\\\bbb'\n\npath.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb')\n// returns\n'../../impl/bbb'
\n

Note: If the arguments to relative have zero-length strings then the current\n working directory will be used instead of the zero-length strings. If\n both the paths are the same then a zero-length string will be returned.\n\n

\n", "signatures": [ { "params": [ { "name": "from" }, { "name": "to" } ] } ] }, { "textRaw": "path.resolve([from ...], to)", "type": "method", "name": "resolve", "desc": "

Resolves to to an absolute path.\n\n

\n

If to isn't already absolute from arguments are prepended in right to left\norder, until an absolute path is found. If after using all from paths still\nno absolute path is found, the current working directory is used as well. The\nresulting path is normalized, and trailing slashes are removed unless the path\ngets resolved to the root directory. Non-string from arguments are ignored.\n\n

\n

Another way to think of it is as a sequence of cd commands in a shell.\n\n

\n
path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile')
\n

Is similar to:\n\n

\n
cd foo/bar\ncd /tmp/file/\ncd ..\ncd a/../subfile\npwd
\n

The difference is that the different paths don't need to exist and may also be\nfiles.\n\n

\n

Examples:\n\n

\n
path.resolve('/foo/bar', './baz')\n// returns\n'/foo/bar/baz'\n\npath.resolve('/foo/bar', '/tmp/file/')\n// returns\n'/tmp/file'\n\npath.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')\n// if currently in /home/myself/node, it returns\n'/home/myself/node/wwwroot/static_files/gif/image.gif'
\n

Note: If the arguments to resolve have zero-length strings then the current\n working directory will be used instead of them.\n\n

\n", "signatures": [ { "params": [ { "name": "from ...", "optional": true }, { "name": "to" } ] } ] } ], "properties": [ { "textRaw": "path.delimiter", "name": "delimiter", "desc": "

The platform-specific path delimiter, ; or ':'.\n\n

\n

An example on *nix:\n\n

\n
console.log(process.env.PATH)\n// '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin'\n\nprocess.env.PATH.split(path.delimiter)\n// returns\n['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
\n

An example on Windows:\n\n

\n
console.log(process.env.PATH)\n// 'C:\\Windows\\system32;C:\\Windows;C:\\Program Files\\node\\'\n\nprocess.env.PATH.split(path.delimiter)\n// returns\n['C:\\\\Windows\\\\system32', 'C:\\\\Windows', 'C:\\\\Program Files\\\\node\\\\']
\n" }, { "textRaw": "path.posix", "name": "posix", "desc": "

Provide access to aforementioned path methods but always interact in a posix\ncompatible way.\n\n

\n" }, { "textRaw": "path.sep", "name": "sep", "desc": "

The platform-specific file separator. '\\\\' or '/'.\n\n

\n

An example on *nix:\n\n

\n
'foo/bar/baz'.split(path.sep)\n// returns\n['foo', 'bar', 'baz']
\n

An example on Windows:\n\n

\n
'foo\\\\bar\\\\baz'.split(path.sep)\n// returns\n['foo', 'bar', 'baz']
\n" }, { "textRaw": "path.win32", "name": "win32", "desc": "

Provide access to aforementioned path methods but always interact in a win32\ncompatible way.\n

\n" } ], "type": "module", "displayName": "Path" } ] } node-v4.2.6/doc/api/path.markdown000644 000766 000024 00000015753 12650222326 016777 0ustar00iojsstaff000000 000000 # Path Stability: 2 - Stable This module contains utilities for handling and transforming file paths. Almost all these methods perform only string transformations. The file system is not consulted to check whether paths are valid. Use `require('path')` to use this module. The following methods are provided: ## path.basename(p[, ext]) Return the last portion of a path. Similar to the Unix `basename` command. Example: path.basename('/foo/bar/baz/asdf/quux.html') // returns 'quux.html' path.basename('/foo/bar/baz/asdf/quux.html', '.html') // returns 'quux' ## path.delimiter The platform-specific path delimiter, `;` or `':'`. An example on *nix: console.log(process.env.PATH) // '/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin' process.env.PATH.split(path.delimiter) // returns ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin'] An example on Windows: console.log(process.env.PATH) // 'C:\Windows\system32;C:\Windows;C:\Program Files\node\' process.env.PATH.split(path.delimiter) // returns ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\'] ## path.dirname(p) Return the directory name of a path. Similar to the Unix `dirname` command. Example: path.dirname('/foo/bar/baz/asdf/quux') // returns '/foo/bar/baz/asdf' ## path.extname(p) Return the extension of the path, from the last '.' to end of string in the last portion of the path. If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string. Examples: path.extname('index.html') // returns '.html' path.extname('index.coffee.md') // returns '.md' path.extname('index.') // returns '.' path.extname('index') // returns '' path.extname('.index') // returns '' ## path.format(pathObject) Returns a path string from an object, the opposite of `path.parse` above. path.format({ root : "/", dir : "/home/user/dir", base : "file.txt", ext : ".txt", name : "file" }) // returns '/home/user/dir/file.txt' ## path.isAbsolute(path) Determines whether `path` is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. Posix examples: path.isAbsolute('/foo/bar') // true path.isAbsolute('/baz/..') // true path.isAbsolute('qux/') // false path.isAbsolute('.') // false Windows examples: path.isAbsolute('//server') // true path.isAbsolute('C:/foo/..') // true path.isAbsolute('bar\\baz') // false path.isAbsolute('.') // false *Note:* If the path string passed as parameter is a zero-length string, unlike other path module functions, it will be used as-is and `false` will be returned. ## path.join([path1][, path2][, ...]) Join all arguments together and normalize the resulting path. Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. Example: path.join('/foo', 'bar', 'baz/asdf', 'quux', '..') // returns '/foo/bar/baz/asdf' path.join('foo', {}, 'bar') // throws exception TypeError: Arguments to path.join must be strings *Note:* If the arguments to `join` have zero-length strings, unlike other path module functions, they will be ignored. If the joined path string is a zero-length string then `'.'` will be returned, which represents the current working directory. ## path.normalize(p) Normalize a string path, taking care of `'..'` and `'.'` parts. When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. Example: path.normalize('/foo/bar//baz/asdf/quux/..') // returns '/foo/bar/baz/asdf' *Note:* If the path string passed as argument is a zero-length string then `'.'` will be returned, which represents the current working directory. ## path.parse(pathString) Returns an object from a path string. An example on *nix: path.parse('/home/user/dir/file.txt') // returns { root : "/", dir : "/home/user/dir", base : "file.txt", ext : ".txt", name : "file" } An example on Windows: path.parse('C:\\path\\dir\\index.html') // returns { root : "C:\\", dir : "C:\\path\\dir", base : "index.html", ext : ".html", name : "index" } ## path.posix Provide access to aforementioned `path` methods but always interact in a posix compatible way. ## path.relative(from, to) Solve the relative path from `from` to `to`. At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of `path.resolve`, which means we see that: path.resolve(from, path.relative(from, to)) == path.resolve(to) Examples: path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb') // returns '..\\..\\impl\\bbb' path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb') // returns '../../impl/bbb' *Note:* If the arguments to `relative` have zero-length strings then the current working directory will be used instead of the zero-length strings. If both the paths are the same then a zero-length string will be returned. ## path.resolve([from ...], to) Resolves `to` to an absolute path. If `to` isn't already absolute `from` arguments are prepended in right to left order, until an absolute path is found. If after using all `from` paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. Non-string `from` arguments are ignored. Another way to think of it is as a sequence of `cd` commands in a shell. path.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile') Is similar to: cd foo/bar cd /tmp/file/ cd .. cd a/../subfile pwd The difference is that the different paths don't need to exist and may also be files. Examples: path.resolve('/foo/bar', './baz') // returns '/foo/bar/baz' path.resolve('/foo/bar', '/tmp/file/') // returns '/tmp/file' path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif') // if currently in /home/myself/node, it returns '/home/myself/node/wwwroot/static_files/gif/image.gif' *Note:* If the arguments to `resolve` have zero-length strings then the current working directory will be used instead of them. ## path.sep The platform-specific file separator. `'\\'` or `'/'`. An example on *nix: 'foo/bar/baz'.split(path.sep) // returns ['foo', 'bar', 'baz'] An example on Windows: 'foo\\bar\\baz'.split(path.sep) // returns ['foo', 'bar', 'baz'] ## path.win32 Provide access to aforementioned `path` methods but always interact in a win32 compatible way. node-v4.2.6/doc/api/process.html000644 000766 000024 00000141712 12650222331 016632 0ustar00iojsstaff000000 000000 process Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


process#

The process object is a global object and can be accessed from anywhere. It is an instance of EventEmitter.

Event: 'beforeExit'#

This event is emitted when Node.js empties its event loop and has nothing else to schedule. Normally, Node.js exits when there is no work scheduled, but a listener for 'beforeExit' can make asynchronous calls, and cause Node.js to continue.

'beforeExit' is not emitted for conditions causing explicit termination, such as process.exit() or uncaught exceptions, and should not be used as an alternative to the 'exit' event unless the intention is to schedule more work.

Event: 'exit'#

Emitted when the process is about to exit. There is no way to prevent the exiting of the event loop at this point, and once all 'exit' listeners have finished running the process will exit. Therefore you must only perform synchronous operations in this handler. This is a good hook to perform checks on the module's state (like for unit tests). The callback takes one argument, the code the process is exiting with.

This event is only emitted when Node.js exits explicitly by process.exit() or implicitly by the event loop draining.

Example of listening for 'exit':

process.on('exit', (code) => {
  // do *NOT* do this
  setTimeout(() => {
    console.log('This will not run');
  }, 0);
  console.log('About to exit with code:', code);
});

Event: 'message'#

  • message Object a parsed JSON object or primitive value
  • sendHandle Handle object a net.Socket or net.Server object, or undefined.

Messages sent by ChildProcess.send() are obtained using the 'message' event on the child's process object.

Event: 'rejectionHandled'#

Emitted whenever a Promise was rejected and an error handler was attached to it (for example with .catch()) later than after an event loop turn. This event is emitted with the following arguments:

  • p the promise that was previously emitted in an 'unhandledRejection' event, but which has now gained a rejection handler.

There is no notion of a top level for a promise chain at which rejections can always be handled. Being inherently asynchronous in nature, a promise rejection can be be handled at a future point in time — possibly much later than the event loop turn it takes for the 'unhandledRejection' event to be emitted.

Another way of stating this is that, unlike in synchronous code where there is an ever-growing list of unhandled exceptions, with promises there is a growing-and-shrinking list of unhandled rejections. In synchronous code, the 'uncaughtException' event tells you when the list of unhandled exceptions grows. And in asynchronous code, the 'unhandledRejection' event tells you when the list of unhandled rejections grows, while the 'rejectionHandled' event tells you when the list of unhandled rejections shrinks.

For example using the rejection detection hooks in order to keep a map of all the rejected promise reasons at a given time:

const unhandledRejections = new Map();
process.on('unhandledRejection', (reason, p) => {
  unhandledRejections.set(p, reason);
});
process.on('rejectionHandled', (p) => {
  unhandledRejections.delete(p);
});

This map will grow and shrink over time, reflecting rejections that start unhandled and then become handled. You could record the errors in some error log, either periodically (probably best for long-running programs, allowing you to clear the map, which in the case of a very buggy program could grow indefinitely) or upon process exit (more convenient for scripts).

Event: 'uncaughtException'#

Emitted when an exception bubbles all the way back to the event loop. If a listener is added for this exception, the default action (which is to print a stack trace and exit) will not occur.

Example of listening for 'uncaughtException':

process.on('uncaughtException', (err) => {
  console.log(`Caught exception: ${err}`);
});

setTimeout(() => {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

Note that 'uncaughtException' is a very crude mechanism for exception handling.

Do not use it as the Node.js equivalent of On Error Resume Next. An unhandled exception means your application - and by extension Node.js itself - is in an undefined state. Blindly resuming means anything could happen.

Think of resuming as pulling the power cord when you are upgrading your system. Nine out of ten times nothing happens - but the 10th time, your system is bust.

'uncaughtException' should be used to perform synchronous cleanup before shutting down the process. It is not safe to resume normal operation after 'uncaughtException'. If you do use it, restart your application after every unhandled exception!

You have been warned.

Event: 'unhandledRejection'#

Emitted whenever a Promise is rejected and no error handler is attached to the promise within a turn of the event loop. When programming with promises exceptions are encapsulated as rejected promises. Such promises can be caught and handled using promise.catch(...) and rejections are propagated through a promise chain. This event is useful for detecting and keeping track of promises that were rejected whose rejections were not handled yet. This event is emitted with the following arguments:

  • reason the object with which the promise was rejected (usually an Error instance).
  • p the promise that was rejected.

Here is an example that logs every unhandled rejection to the console

process.on('unhandledRejection', (reason, p) => {
    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
    // application specific logging, throwing an error, or other logic here
});

For example, here is a rejection that will trigger the 'unhandledRejection' event:

somePromise.then((res) => {
  return reportToUser(JSON.parse(res)); // note the typo
}); // no `.catch` or `.then`

Here is an example of a coding pattern that will also trigger 'unhandledRejection':

function SomeResource() {
  // Initially set the loaded status to a rejected promise
  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));
}

var resource = new SomeResource();
// no .catch or .then on resource.loaded for at least a turn

In cases like this, you may not want to track the rejection as a developer error like you would for other 'unhandledRejection' events. To address this, you can either attach a dummy .catch(function() { }) handler to resource.loaded, preventing the 'unhandledRejection' event from being emitted, or you can use the 'rejectionHandled' event. Below is an explanation of how to do that.

Exit Codes#

Node.js will normally exit with a 0 status code when no more async operations are pending. The following status codes are used in other cases:

  • 1 Uncaught Fatal Exception - There was an uncaught exception, and it was not handled by a domain or an 'uncaughtException' event handler.
  • 2 - Unused (reserved by Bash for builtin misuse)
  • 3 Internal JavaScript Parse Error - The JavaScript source code internal in Node.js's bootstrapping process caused a parse error. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 4 Internal JavaScript Evaluation Failure - The JavaScript source code internal in Node.js's bootstrapping process failed to return a function value when evaluated. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 5 Fatal Error - There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix FATAL ERROR.
  • 6 Non-function Internal Exception Handler - There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, and could not be called.
  • 7 Internal Exception Handler Run-Time Failure - There was an uncaught exception, and the internal fatal exception handler function itself threw an error while attempting to handle it. This can happen, for example, if a process.on('uncaughtException') or domain.on('error') handler throws an error.
  • 8 - Unused. In previous versions of Node.js, exit code 8 sometimes indicated an uncaught exception.
  • 9 - Invalid Argument - Either an unknown option was specified, or an option requiring a value was provided without a value.
  • 10 Internal JavaScript Run-Time Failure - The JavaScript source code internal in Node.js's bootstrapping process threw an error when the bootstrapping function was called. This is extremely rare, and generally can only happen during development of Node.js itself.
  • 12 Invalid Debug Argument - The --debug and/or --debug-brk options were set, but an invalid port number was chosen.
  • >128 Signal Exits - If Node.js receives a fatal signal such as SIGKILL or SIGHUP, then its exit code will be 128 plus the value of the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code.

Signal Events#

Emitted when the processes receives a signal. See sigaction(2) for a list of standard POSIX signal names such as SIGINT, SIGHUP, etc.

Example of listening for SIGINT:

// Start reading from stdin so we don't exit.
process.stdin.resume();

process.on('SIGINT', () => {
  console.log('Got SIGINT.  Press Control-D to exit.');
});

An easy way to send the SIGINT signal is with Control-C in most terminal programs.

Note:

  • SIGUSR1 is reserved by Node.js to start the debugger. It's possible to install a listener but that won't stop the debugger from starting.
  • SIGTERM and SIGINT have default handlers on non-Windows platforms that resets the terminal mode before exiting with code 128 + signal number. If one of these signals has a listener installed, its default behavior will be removed (Node.js will no longer exit).
  • SIGPIPE is ignored by default. It can have a listener installed.
  • SIGHUP is generated on Windows when the console window is closed, and on other platforms under various similar conditions, see signal(7). It can have a listener installed, however Node.js will be unconditionally terminated by Windows about 10 seconds later. On non-Windows platforms, the default behavior of SIGHUP is to terminate Node.js, but once a listener has been installed its default behavior will be removed.
  • SIGTERM is not supported on Windows, it can be listened on.
  • SIGINT from the terminal is supported on all platforms, and can usually be generated with CTRL+C (though this may be configurable). It is not generated when terminal raw mode is enabled.
  • SIGBREAK is delivered on Windows when CTRL+BREAK is pressed, on non-Windows platforms it can be listened on, but there is no way to send or generate it.
  • SIGWINCH is delivered when the console has been resized. On Windows, this will only happen on write to the console when the cursor is being moved, or when a readable tty is used in raw mode.
  • SIGKILL cannot have a listener installed, it will unconditionally terminate Node.js on all platforms.
  • SIGSTOP cannot have a listener installed.

Note that Windows does not support sending Signals, but Node.js offers some emulation with process.kill(), and child_process.kill(). Sending signal 0 can be used to test for the existence of a process. Sending SIGINT, SIGTERM, and SIGKILL cause the unconditional termination of the target process.

process.abort()#

This causes Node.js to emit an abort. This will cause Node.js to exit and generate a core file.

process.arch#

What processor architecture you're running on: 'arm', 'ia32', or 'x64'.

console.log('This processor architecture is ' + process.arch);

process.argv#

An array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments.

// print process.argv
process.argv.forEach((val, index, array) => {
  console.log(`${index}: ${val}`);
});

This will generate:

$ node process-2.js one two=three four
0: node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four

process.chdir(directory)#

Changes the current working directory of the process or throws an exception if that fails.

console.log(`Starting directory: ${process.cwd()}`);
try {
  process.chdir('/tmp');
  console.log(`New directory: ${process.cwd()}`);
}
catch (err) {
  console.log(`chdir: ${err}`);
}

process.config#

An Object containing the JavaScript representation of the configure options that were used to compile the current Node.js executable. This is the same as the config.gypi file that was produced when running the ./configure script.

An example of the possible output looks like:

{ target_defaults:
   { cflags: [],
     default_configuration: 'Release',
     defines: [],
     include_dirs: [],
     libraries: [] },
  variables:
   { host_arch: 'x64',
     node_install_npm: 'true',
     node_prefix: '',
     node_shared_cares: 'false',
     node_shared_http_parser: 'false',
     node_shared_libuv: 'false',
     node_shared_zlib: 'false',
     node_use_dtrace: 'false',
     node_use_openssl: 'true',
     node_shared_openssl: 'false',
     strict_aliasing: 'true',
     target_arch: 'x64',
     v8_use_snapshot: 'true' } }

process.connected#

  • Boolean Set to false after process.disconnect() is called

If process.connected is false, it is no longer possible to send messages.

process.cwd()#

Returns the current working directory of the process.

console.log(`Current directory: ${process.cwd()}`);

process.disconnect()#

Close the IPC channel to the parent process, allowing this child to exit gracefully once there are no other connections keeping it alive.

Identical to the parent process's ChildProcess.disconnect().

If Node.js was not spawned with an IPC channel, process.disconnect() will be undefined.

process.env#

An object containing the user environment. See environ(7).

An example of this object looks like:

{ TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node' }

You can write to this object, but changes won't be reflected outside of your process. That means that the following won't work:

$ node -e 'process.env.foo = "bar"' && echo $foo

But this will:

process.env.foo = 'bar';
console.log(process.env.foo);

process.execArgv#

This is the set of Node.js-specific command line options from the executable that started the process. These options do not show up in process.argv, and do not include the Node.js executable, the name of the script, or any options following the script name. These options are useful in order to spawn child processes with the same execution environment as the parent.

Example:

$ node --harmony script.js --version

results in process.execArgv:

['--harmony']

and process.argv:

['/usr/local/bin/node', 'script.js', '--version']

process.execPath#

This is the absolute pathname of the executable that started the process.

Example:

/usr/local/bin/node

process.exit([code])#

Ends the process with the specified code. If omitted, exit uses the 'success' code 0.

To exit with a 'failure' code:

process.exit(1);

The shell that executed Node.js should see the exit code as 1.

process.exitCode#

A number which will be the process exit code, when the process either exits gracefully, or is exited via process.exit() without specifying a code.

Specifying a code to process.exit(code) will override any previous setting of process.exitCode.

process.getegid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the effective group identity of the process. (See getegid(2).) This is the numerical group id, not the group name.

if (process.getegid) {
  console.log(`Current gid: ${process.getegid()}`);
}

process.geteuid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the effective user identity of the process. (See geteuid(2).) This is the numerical userid, not the username.

if (process.geteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
}

process.getgid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the group identity of the process. (See getgid(2).) This is the numerical group id, not the group name.

if (process.getgid) {
  console.log(`Current gid: ${process.getgid()}`);
}

process.getgroups()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Returns an array with the supplementary group IDs. POSIX leaves it unspecified if the effective group ID is included but Node.js ensures it always is.

process.getuid()#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Gets the user identity of the process. (See getuid(2).) This is the numerical userid, not the username.

if (process.getuid) {
  console.log(`Current uid: ${process.getuid()}`);
}

process.hrtime()#

Returns the current high-resolution real time in a [seconds, nanoseconds] tuple Array. It is relative to an arbitrary time in the past. It is not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals.

You may pass in the result of a previous call to process.hrtime() to get a diff reading, useful for benchmarks and measuring intervals:

var time = process.hrtime();
// [ 1800216, 25 ]

setTimeout(() => {
  var diff = process.hrtime(time);
  // [ 1, 552 ]

  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);
  // benchmark took 1000000527 nanoseconds
}, 1000);

process.initgroups(user, extra_group)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Reads /etc/group and initializes the group access list, using all groups of which the user is a member. This is a privileged operation, meaning you need to be root or have the CAP_SETGID capability.

user is a user name or user ID. extra_group is a group name or group ID.

Some care needs to be taken when dropping privileges. Example:

console.log(process.getgroups());         // [ 0 ]
process.initgroups('bnoordhuis', 1000);   // switch user
console.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]
process.setgid(1000);                     // drop root gid
console.log(process.getgroups());         // [ 27, 30, 46, 1000 ]

process.kill(pid[, signal])#

Send a signal to a process. pid is the process id and signal is the string describing the signal to send. Signal names are strings like SIGINT or SIGHUP. If omitted, the signal will be SIGTERM. See Signal Events and kill(2) for more information.

Will throw an error if target does not exist, and as a special case, a signal of 0 can be used to test for the existence of a process. Windows platforms will throw an error if the pid is used to kill a process group.

Note that even though the name of this function is process.kill, it is really just a signal sender, like the kill system call. The signal sent may do something other than kill the target process.

Example of sending a signal to yourself:

process.on('SIGHUP', () => {
  console.log('Got SIGHUP signal.');
});

setTimeout(() => {
  console.log('Exiting.');
  process.exit(0);
}, 100);

process.kill(process.pid, 'SIGHUP');

Note: When SIGUSR1 is received by Node.js it starts the debugger, see Signal Events.

process.mainModule#

Alternate way to retrieve require.main. The difference is that if the main module changes at runtime, require.main might still refer to the original main module in modules that were required before the change occurred. Generally it's safe to assume that the two refer to the same module.

As with require.main, it will be undefined if there was no entry script.

process.memoryUsage()#

Returns an object describing the memory usage of the Node.js process measured in bytes.

const util = require('util');

console.log(util.inspect(process.memoryUsage()));

This will generate:

{ rss: 4935680,
  heapTotal: 1826816,
  heapUsed: 650472 }

heapTotal and heapUsed refer to V8's memory usage.

process.nextTick(callback[, arg][, ...])#

  • callback Function

Once the current event loop turn runs to completion, call the callback function.

This is not a simple alias to setTimeout(fn, 0), it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop.

console.log('start');
process.nextTick(() => {
  console.log('nextTick callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// nextTick callback

This is important in developing APIs where you want to give the user the chance to assign event handlers after an object has been constructed, but before any I/O has occurred.

function MyThing(options) {
  this.setupOptions(options);

  process.nextTick(() => {
    this.startDoingStuff();
  }.bind(this));
}

var thing = new MyThing();
thing.getReadyForStuff();

// thing.startDoingStuff() gets called now, not before.

It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example:

// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!
function maybeSync(arg, cb) {
  if (arg) {
    cb();
    return;
  }

  fs.stat('file', cb);
}

This API is hazardous. If you do this:

maybeSync(true, function() {
  foo();
});
bar();

then it's not clear whether foo() or bar() will be called first.

This approach is much better:

function definitelyAsync(arg, cb) {
  if (arg) {
    process.nextTick(cb);
    return;
  }

  fs.stat('file', cb);
}

Note: the nextTick queue is completely drained on each pass of the event loop before additional I/O is processed. As a result, recursively setting nextTick callbacks will block any I/O from happening, just like a while(true); loop.

process.pid#

The PID of the process.

console.log(`This process is pid ${process.pid}`);

process.platform#

What platform you're running on: 'darwin', 'freebsd', 'linux', 'sunos' or 'win32'

console.log(`This platform is ${process.platform}`);

process.release#

An Object containing metadata related to the current release, including URLs for the source tarball and headers-only tarball.

process.release contains the following properties:

  • name: a string with a value that will always be 'node' for Node.js. For legacy io.js releases, this will be 'io.js'.
  • sourceUrl: a complete URL pointing to a .tar.gz file containing the source of the current release.
  • headersUrl: a complete URL pointing to a .tar.gz file containing only the header files for the current release. This file is significantly smaller than the full source file and can be used for compiling add-ons against Node.js.
  • libUrl: a complete URL pointing to an node.lib file matching the architecture and version of the current release. This file is used for compiling add-ons against Node.js. This property is only present on Windows builds of Node.js and will be missing on all other platforms.

e.g.

{ name: 'node',
  sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz',
  headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz',
  libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' }

In custom builds from non-release versions of the source tree, only the name property may be present. The additional properties should not be relied upon to exist.

process.send(message[, sendHandle][, callback])#

  • message Object
  • sendHandle Handle object

When Node.js is spawned with an IPC channel attached, it can send messages to its parent process using process.send(). Each will be received as a 'message' event on the parent's ChildProcess object.

If Node.js was not spawned with an IPC channel, process.send() will be undefined.

process.setegid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the effective group identity of the process. (See setegid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID.

if (process.getegid && process.setegid) {
  console.log(`Current gid: ${process.getegid()}`);
  try {
    process.setegid(501);
    console.log(`New gid: ${process.getegid()}`);
  }
  catch (err) {
    console.log(`Failed to set gid: ${err}`);
  }
}

process.seteuid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the effective user identity of the process. (See seteuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID.

if (process.geteuid && process.seteuid) {
  console.log(`Current uid: ${process.geteuid()}`);
  try {
    process.seteuid(501);
    console.log(`New uid: ${process.geteuid()}`);
  }
  catch (err) {
    console.log(`Failed to set uid: ${err}`);
  }
}

process.setgid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the group identity of the process. (See setgid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID.

if (process.getgid && process.setgid) {
  console.log(`Current gid: ${process.getgid()}`);
  try {
    process.setgid(501);
    console.log(`New gid: ${process.getgid()}`);
  }
  catch (err) {
    console.log(`Failed to set gid: ${err}`);
  }
}

process.setgroups(groups)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the supplementary group IDs. This is a privileged operation, meaning you need to be root or have the CAP_SETGID capability.

The list can contain group IDs, group names or both.

process.setuid(id)#

Note: this function is only available on POSIX platforms (i.e. not Windows, Android)

Sets the user identity of the process. (See setuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID.

if (process.getuid && process.setuid) {
  console.log(`Current uid: ${process.getuid()}`);
  try {
    process.setuid(501);
    console.log(`New uid: ${process.getuid()}`);
  }
  catch (err) {
    console.log(`Failed to set uid: ${err}`);
  }
}

process.stderr#

A writable stream to stderr (on fd 2).

process.stderr and process.stdout are unlike other streams in Node.js in that they cannot be closed (end() will throw), they never emit the finish event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.)

process.stdin#

A Readable Stream for stdin (on fd 0).

Example of opening standard input and listening for both events:

process.stdin.setEncoding('utf8');

process.stdin.on('readable', () => {
  var chunk = process.stdin.read();
  if (chunk !== null) {
    process.stdout.write(`data: ${chunk}`);
  }
});

process.stdin.on('end', () => {
  process.stdout.write('end');
});

As a Stream, process.stdin can also be used in "old" mode that is compatible with scripts written for node.js prior to v0.10. For more information see Stream compatibility.

In "old" Streams mode the stdin stream is paused by default, so one must call process.stdin.resume() to read from it. Note also that calling process.stdin.resume() itself would switch stream to "old" mode.

If you are starting a new project you should prefer a more recent "new" Streams mode over "old" one.

process.stdout#

A Writable Stream to stdout (on fd 1).

For example, a console.log equivalent could look like this:

console.log = function(msg) {
  process.stdout.write(`${msg}\n`);
};

process.stderr and process.stdout are unlike other streams in Node.js in that they cannot be closed (end() will throw), they never emit the 'finish' event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.)

To check if Node.js is being run in a TTY context, read the isTTY property on process.stderr, process.stdout, or process.stdin:

$ node -p "Boolean(process.stdin.isTTY)"
true
$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"
false

$ node -p "Boolean(process.stdout.isTTY)"
true
$ node -p "Boolean(process.stdout.isTTY)" | cat
false

See the tty docs for more information.

process.title#

Getter/setter to set what is displayed in ps.

When used as a setter, the maximum length is platform-specific and probably short.

On Linux and OS X, it's limited to the size of the binary name plus the length of the command line arguments because it overwrites the argv memory.

v0.8 allowed for longer process title strings by also overwriting the environ memory but that was potentially insecure/confusing in some (rather obscure) cases.

process.umask([mask])#

Sets or reads the process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the old mask if mask argument is given, otherwise returns the current mask.

const newmask = 0o022;
const oldmask = process.umask(newmask);
console.log(
  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`
);

process.uptime()#

Number of seconds Node.js has been running.

process.version#

A compiled-in property that exposes NODE_VERSION.

console.log(`Version: ${process.version}`);

process.versions#

A property exposing version strings of Node.js and its dependencies.

console.log(process.versions);

Will print something like:

{ http_parser: '2.3.0',
  node: '1.1.1',
  v8: '4.1.0.14',
  uv: '1.3.0',
  zlib: '1.2.8',
  ares: '1.10.0-DEV',
  modules: '43',
  icu: '55.1',
  openssl: '1.0.1k' }
node-v4.2.6/doc/api/process.json000644 000766 000024 00000135205 12650222331 016637 0ustar00iojsstaff000000 000000 { "source": "doc/api/process.markdown", "globals": [ { "textRaw": "process", "name": "process", "type": "global", "desc": "

The process object is a global object and can be accessed from anywhere.\nIt is an instance of [EventEmitter][].\n\n

\n", "events": [ { "textRaw": "Event: 'beforeExit'", "type": "event", "name": "beforeExit", "desc": "

This event is emitted when Node.js empties its event loop and has nothing else to\nschedule. Normally, Node.js exits when there is no work scheduled, but a listener\nfor 'beforeExit' can make asynchronous calls, and cause Node.js to continue.\n\n

\n

'beforeExit' is not emitted for conditions causing explicit termination, such as\n[process.exit()][] or uncaught exceptions, and should not be used as an\nalternative to the 'exit' event unless the intention is to schedule more work.\n\n

\n", "params": [] }, { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "desc": "

Emitted when the process is about to exit. There is no way to prevent the\nexiting of the event loop at this point, and once all 'exit' listeners have\nfinished running the process will exit. Therefore you must only perform\nsynchronous operations in this handler. This is a good hook to perform\nchecks on the module's state (like for unit tests). The callback takes one\nargument, the code the process is exiting with.\n\n

\n

This event is only emitted when Node.js exits explicitly by process.exit() or\nimplicitly by the event loop draining.\n\n

\n

Example of listening for 'exit':\n\n

\n
process.on('exit', (code) => {\n  // do *NOT* do this\n  setTimeout(() => {\n    console.log('This will not run');\n  }, 0);\n  console.log('About to exit with code:', code);\n});
\n", "params": [] }, { "textRaw": "Event: 'message'", "type": "event", "name": "message", "params": [], "desc": "

Messages sent by [ChildProcess.send()][] are obtained using the 'message'\nevent on the child's process object.\n\n

\n" }, { "textRaw": "Event: 'rejectionHandled'", "type": "event", "name": "rejectionHandled", "desc": "

Emitted whenever a Promise was rejected and an error handler was attached to it\n(for example with .catch()) later than after an event loop turn. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • p the promise that was previously emitted in an 'unhandledRejection'\nevent, but which has now gained a rejection handler.
  • \n
\n

There is no notion of a top level for a promise chain at which rejections can\nalways be handled. Being inherently asynchronous in nature, a promise rejection\ncan be be handled at a future point in time — possibly much later than the\nevent loop turn it takes for the 'unhandledRejection' event to be emitted.\n\n

\n

Another way of stating this is that, unlike in synchronous code where there is\nan ever-growing list of unhandled exceptions, with promises there is a\ngrowing-and-shrinking list of unhandled rejections. In synchronous code, the\n'uncaughtException' event tells you when the list of unhandled exceptions\ngrows. And in asynchronous code, the 'unhandledRejection' event tells you\nwhen the list of unhandled rejections grows, while the 'rejectionHandled'\nevent tells you when the list of unhandled rejections shrinks.\n\n

\n

For example using the rejection detection hooks in order to keep a map of all\nthe rejected promise reasons at a given time:\n\n

\n
const unhandledRejections = new Map();\nprocess.on('unhandledRejection', (reason, p) => {\n  unhandledRejections.set(p, reason);\n});\nprocess.on('rejectionHandled', (p) => {\n  unhandledRejections.delete(p);\n});
\n

This map will grow and shrink over time, reflecting rejections that start\nunhandled and then become handled. You could record the errors in some error\nlog, either periodically (probably best for long-running programs, allowing\nyou to clear the map, which in the case of a very buggy program could grow\nindefinitely) or upon process exit (more convenient for scripts).\n\n

\n", "params": [] }, { "textRaw": "Event: 'uncaughtException'", "type": "event", "name": "uncaughtException", "desc": "

Emitted when an exception bubbles all the way back to the event loop. If a\nlistener is added for this exception, the default action (which is to print\na stack trace and exit) will not occur.\n\n

\n

Example of listening for 'uncaughtException':\n\n

\n
process.on('uncaughtException', (err) => {\n  console.log(`Caught exception: ${err}`);\n});\n\nsetTimeout(() => {\n  console.log('This will still run.');\n}, 500);\n\n// Intentionally cause an exception, but don't catch it.\nnonexistentFunc();\nconsole.log('This will not run.');
\n

Note that 'uncaughtException' is a very crude mechanism for exception\nhandling.\n\n

\n

Do not use it as the Node.js equivalent of On Error Resume Next. An\nunhandled exception means your application - and by extension Node.js itself -\nis in an undefined state. Blindly resuming means anything could happen.\n\n

\n

Think of resuming as pulling the power cord when you are upgrading your system.\nNine out of ten times nothing happens - but the 10th time, your system is bust.\n\n

\n

'uncaughtException' should be used to perform synchronous cleanup before\nshutting down the process. It is not safe to resume normal operation after\n'uncaughtException'. If you do use it, restart your application after every\nunhandled exception!\n\n

\n

You have been warned.\n\n

\n", "params": [] }, { "textRaw": "Event: 'unhandledRejection'", "type": "event", "name": "unhandledRejection", "desc": "

Emitted whenever a Promise is rejected and no error handler is attached to\nthe promise within a turn of the event loop. When programming with promises\nexceptions are encapsulated as rejected promises. Such promises can be caught\nand handled using [promise.catch(...)][] and rejections are propagated through\na promise chain. This event is useful for detecting and keeping track of\npromises that were rejected whose rejections were not handled yet. This event\nis emitted with the following arguments:\n\n

\n
    \n
  • reason the object with which the promise was rejected (usually an [Error][]\ninstance).
  • \n
  • p the promise that was rejected.
  • \n
\n

Here is an example that logs every unhandled rejection to the console\n\n

\n
process.on('unhandledRejection', (reason, p) => {\n    console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);\n    // application specific logging, throwing an error, or other logic here\n});
\n

For example, here is a rejection that will trigger the 'unhandledRejection'\nevent:\n\n

\n
somePromise.then((res) => {\n  return reportToUser(JSON.parse(res)); // note the typo\n}); // no `.catch` or `.then`
\n

Here is an example of a coding pattern that will also trigger\n'unhandledRejection':\n\n

\n
function SomeResource() {\n  // Initially set the loaded status to a rejected promise\n  this.loaded = Promise.reject(new Error('Resource not yet loaded!'));\n}\n\nvar resource = new SomeResource();\n// no .catch or .then on resource.loaded for at least a turn
\n

In cases like this, you may not want to track the rejection as a developer\nerror like you would for other 'unhandledRejection' events. To address\nthis, you can either attach a dummy .catch(function() { }) handler to\nresource.loaded, preventing the 'unhandledRejection' event from being\nemitted, or you can use the 'rejectionHandled' event. Below is an\nexplanation of how to do that.\n\n

\n", "params": [] }, { "textRaw": "Signal Events", "name": "SIGINT, SIGHUP, etc.", "type": "event", "desc": "

Emitted when the processes receives a signal. See sigaction(2) for a list of\nstandard POSIX signal names such as SIGINT, SIGHUP, etc.\n\n

\n

Example of listening for SIGINT:\n\n

\n
// Start reading from stdin so we don't exit.\nprocess.stdin.resume();\n\nprocess.on('SIGINT', () => {\n  console.log('Got SIGINT.  Press Control-D to exit.');\n});
\n

An easy way to send the SIGINT signal is with Control-C in most terminal\nprograms.\n\n

\n

Note:\n\n

\n
    \n
  • SIGUSR1 is reserved by Node.js to start the debugger. It's possible to\ninstall a listener but that won't stop the debugger from starting.
  • \n
  • SIGTERM and SIGINT have default handlers on non-Windows platforms that resets\nthe terminal mode before exiting with code 128 + signal number. If one of\nthese signals has a listener installed, its default behavior will be removed\n(Node.js will no longer exit).
  • \n
  • SIGPIPE is ignored by default. It can have a listener installed.
  • \n
  • SIGHUP is generated on Windows when the console window is closed, and on other\nplatforms under various similar conditions, see signal(7). It can have a\nlistener installed, however Node.js will be unconditionally terminated by\nWindows about 10 seconds later. On non-Windows platforms, the default\nbehavior of SIGHUP is to terminate Node.js, but once a listener has been\ninstalled its default behavior will be removed.
  • \n
  • SIGTERM is not supported on Windows, it can be listened on.
  • \n
  • SIGINT from the terminal is supported on all platforms, and can usually be\ngenerated with CTRL+C (though this may be configurable). It is not generated\nwhen terminal raw mode is enabled.
  • \n
  • SIGBREAK is delivered on Windows when CTRL+BREAK is pressed, on non-Windows\nplatforms it can be listened on, but there is no way to send or generate it.
  • \n
  • SIGWINCH is delivered when the console has been resized. On Windows, this will\nonly happen on write to the console when the cursor is being moved, or when a\nreadable tty is used in raw mode.
  • \n
  • SIGKILL cannot have a listener installed, it will unconditionally terminate\nNode.js on all platforms.
  • \n
  • SIGSTOP cannot have a listener installed.
  • \n
\n

Note that Windows does not support sending Signals, but Node.js offers some\nemulation with process.kill(), and child_process.kill(). Sending signal 0\ncan be used to test for the existence of a process. Sending SIGINT,\nSIGTERM, and SIGKILL cause the unconditional termination of the target\nprocess.\n\n

\n", "params": [] } ], "modules": [ { "textRaw": "Exit Codes", "name": "exit_codes", "desc": "

Node.js will normally exit with a 0 status code when no more async\noperations are pending. The following status codes are used in other\ncases:\n\n

\n
    \n
  • 1 Uncaught Fatal Exception - There was an uncaught exception,\nand it was not handled by a domain or an 'uncaughtException' event\nhandler.
  • \n
  • 2 - Unused (reserved by Bash for builtin misuse)
  • \n
  • 3 Internal JavaScript Parse Error - The JavaScript source code\ninternal in Node.js's bootstrapping process caused a parse error. This\nis extremely rare, and generally can only happen during development\nof Node.js itself.
  • \n
  • 4 Internal JavaScript Evaluation Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process failed to\nreturn a function value when evaluated. This is extremely rare, and\ngenerally can only happen during development of Node.js itself.
  • \n
  • 5 Fatal Error - There was a fatal unrecoverable error in V8.\nTypically a message will be printed to stderr with the prefix FATAL\nERROR.
  • \n
  • 6 Non-function Internal Exception Handler - There was an\nuncaught exception, but the internal fatal exception handler\nfunction was somehow set to a non-function, and could not be called.
  • \n
  • 7 Internal Exception Handler Run-Time Failure - There was an\nuncaught exception, and the internal fatal exception handler\nfunction itself threw an error while attempting to handle it. This\ncan happen, for example, if a process.on('uncaughtException') or\ndomain.on('error') handler throws an error.
  • \n
  • 8 - Unused. In previous versions of Node.js, exit code 8 sometimes\nindicated an uncaught exception.
  • \n
  • 9 - Invalid Argument - Either an unknown option was specified,\nor an option requiring a value was provided without a value.
  • \n
  • 10 Internal JavaScript Run-Time Failure - The JavaScript\nsource code internal in Node.js's bootstrapping process threw an error\nwhen the bootstrapping function was called. This is extremely rare,\nand generally can only happen during development of Node.js itself.
  • \n
  • 12 Invalid Debug Argument - The --debug and/or --debug-brk\noptions were set, but an invalid port number was chosen.
  • \n
  • >128 Signal Exits - If Node.js receives a fatal signal such as\nSIGKILL or SIGHUP, then its exit code will be 128 plus the\nvalue of the signal code. This is a standard Unix practice, since\nexit codes are defined to be 7-bit integers, and signal exits set\nthe high-order bit, and then contain the value of the signal code.
  • \n
\n", "type": "module", "displayName": "Exit Codes" } ], "methods": [ { "textRaw": "process.abort()", "type": "method", "name": "abort", "desc": "

This causes Node.js to emit an abort. This will cause Node.js to exit and\ngenerate a core file.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.chdir(directory)", "type": "method", "name": "chdir", "desc": "

Changes the current working directory of the process or throws an exception if that fails.\n\n

\n
console.log(`Starting directory: ${process.cwd()}`);\ntry {\n  process.chdir('/tmp');\n  console.log(`New directory: ${process.cwd()}`);\n}\ncatch (err) {\n  console.log(`chdir: ${err}`);\n}
\n", "signatures": [ { "params": [ { "name": "directory" } ] } ] }, { "textRaw": "process.cwd()", "type": "method", "name": "cwd", "desc": "

Returns the current working directory of the process.\n\n

\n
console.log(`Current directory: ${process.cwd()}`);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.disconnect()", "type": "method", "name": "disconnect", "desc": "

Close the IPC channel to the parent process, allowing this child to exit\ngracefully once there are no other connections keeping it alive.\n\n

\n

Identical to the parent process's [ChildProcess.disconnect()][].\n\n

\n

If Node.js was not spawned with an IPC channel, process.disconnect() will be\nundefined.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.exit([code])", "type": "method", "name": "exit", "desc": "

Ends the process with the specified code. If omitted, exit uses the\n'success' code 0.\n\n

\n

To exit with a 'failure' code:\n\n

\n
process.exit(1);
\n

The shell that executed Node.js should see the exit code as 1.\n\n\n

\n", "signatures": [ { "params": [ { "name": "code", "optional": true } ] } ] }, { "textRaw": "process.getegid()", "type": "method", "name": "getegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective group identity of the process. (See getegid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.geteuid()", "type": "method", "name": "geteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the effective user identity of the process. (See geteuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.geteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgid()", "type": "method", "name": "getgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the group identity of the process. (See getgid(2).)\nThis is the numerical group id, not the group name.\n\n

\n
if (process.getgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getgroups()", "type": "method", "name": "getgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Returns an array with the supplementary group IDs. POSIX leaves it unspecified\nif the effective group ID is included but Node.js ensures it always is.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.getuid()", "type": "method", "name": "getuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Gets the user identity of the process. (See getuid(2).)\nThis is the numerical userid, not the username.\n\n

\n
if (process.getuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.hrtime()", "type": "method", "name": "hrtime", "desc": "

Returns the current high-resolution real time in a [seconds, nanoseconds]\ntuple Array. It is relative to an arbitrary time in the past. It is not\nrelated to the time of day and therefore not subject to clock drift. The\nprimary use is for measuring performance between intervals.\n\n

\n

You may pass in the result of a previous call to process.hrtime() to get\na diff reading, useful for benchmarks and measuring intervals:\n\n

\n
var time = process.hrtime();\n// [ 1800216, 25 ]\n\nsetTimeout(() => {\n  var diff = process.hrtime(time);\n  // [ 1, 552 ]\n\n  console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]);\n  // benchmark took 1000000527 nanoseconds\n}, 1000);
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.initgroups(user, extra_group)", "type": "method", "name": "initgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Reads /etc/group and initializes the group access list, using all groups of\nwhich the user is a member. This is a privileged operation, meaning you need\nto be root or have the CAP_SETGID capability.\n\n

\n

user is a user name or user ID. extra_group is a group name or group ID.\n\n

\n

Some care needs to be taken when dropping privileges. Example:\n\n

\n
console.log(process.getgroups());         // [ 0 ]\nprocess.initgroups('bnoordhuis', 1000);   // switch user\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000, 0 ]\nprocess.setgid(1000);                     // drop root gid\nconsole.log(process.getgroups());         // [ 27, 30, 46, 1000 ]
\n", "signatures": [ { "params": [ { "name": "user" }, { "name": "extra_group" } ] } ] }, { "textRaw": "process.kill(pid[, signal])", "type": "method", "name": "kill", "desc": "

Send a signal to a process. pid is the process id and signal is the\nstring describing the signal to send. Signal names are strings like\nSIGINT or SIGHUP. If omitted, the signal will be SIGTERM.\nSee [Signal Events][] and kill(2) for more information.\n\n

\n

Will throw an error if target does not exist, and as a special case, a signal\nof 0 can be used to test for the existence of a process. Windows platforms\nwill throw an error if the pid is used to kill a process group.\n\n

\n

Note that even though the name of this function is process.kill, it is really\njust a signal sender, like the kill system call. The signal sent may do\nsomething other than kill the target process.\n\n

\n

Example of sending a signal to yourself:\n\n

\n
process.on('SIGHUP', () => {\n  console.log('Got SIGHUP signal.');\n});\n\nsetTimeout(() => {\n  console.log('Exiting.');\n  process.exit(0);\n}, 100);\n\nprocess.kill(process.pid, 'SIGHUP');
\n

Note: When SIGUSR1 is received by Node.js it starts the debugger, see\n[Signal Events][].\n\n

\n", "signatures": [ { "params": [ { "name": "pid" }, { "name": "signal", "optional": true } ] } ] }, { "textRaw": "process.memoryUsage()", "type": "method", "name": "memoryUsage", "desc": "

Returns an object describing the memory usage of the Node.js process\nmeasured in bytes.\n\n

\n
const util = require('util');\n\nconsole.log(util.inspect(process.memoryUsage()));
\n

This will generate:\n\n

\n
{ rss: 4935680,\n  heapTotal: 1826816,\n  heapUsed: 650472 }
\n

heapTotal and heapUsed refer to V8's memory usage.\n\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "process.nextTick(callback[, arg][, ...])", "type": "method", "name": "nextTick", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} ", "name": "callback", "type": "Function" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] }, { "params": [ { "name": "callback" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ], "desc": "

Once the current event loop turn runs to completion, call the callback\nfunction.\n\n

\n

This is not a simple alias to [setTimeout(fn, 0)][], it's much more\nefficient. It runs before any additional I/O events (including\ntimers) fire in subsequent ticks of the event loop.\n\n

\n
console.log('start');\nprocess.nextTick(() => {\n  console.log('nextTick callback');\n});\nconsole.log('scheduled');\n// Output:\n// start\n// scheduled\n// nextTick callback
\n

This is important in developing APIs where you want to give the user the\nchance to assign event handlers after an object has been constructed,\nbut before any I/O has occurred.\n\n

\n
function MyThing(options) {\n  this.setupOptions(options);\n\n  process.nextTick(() => {\n    this.startDoingStuff();\n  }.bind(this));\n}\n\nvar thing = new MyThing();\nthing.getReadyForStuff();\n\n// thing.startDoingStuff() gets called now, not before.
\n

It is very important for APIs to be either 100% synchronous or 100%\nasynchronous. Consider this example:\n\n

\n
// WARNING!  DO NOT USE!  BAD UNSAFE HAZARD!\nfunction maybeSync(arg, cb) {\n  if (arg) {\n    cb();\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

This API is hazardous. If you do this:\n\n

\n
maybeSync(true, function() {\n  foo();\n});\nbar();
\n

then it's not clear whether foo() or bar() will be called first.\n\n

\n

This approach is much better:\n\n

\n
function definitelyAsync(arg, cb) {\n  if (arg) {\n    process.nextTick(cb);\n    return;\n  }\n\n  fs.stat('file', cb);\n}
\n

Note: the nextTick queue is completely drained on each pass of the\nevent loop before additional I/O is processed. As a result,\nrecursively setting nextTick callbacks will block any I/O from\nhappening, just like a while(true); loop.\n\n

\n" }, { "textRaw": "process.send(message[, sendHandle][, callback])", "type": "method", "name": "send", "signatures": [ { "params": [ { "textRaw": "`message` {Object} ", "name": "message", "type": "Object" }, { "textRaw": "`sendHandle` {Handle object} ", "name": "sendHandle", "type": "Handle object", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "message" }, { "name": "sendHandle", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

When Node.js is spawned with an IPC channel attached, it can send messages to its\nparent process using process.send(). Each will be received as a\n['message'][] event on the parent's ChildProcess object.\n\n

\n

If Node.js was not spawned with an IPC channel, process.send() will be undefined.\n\n

\n" }, { "textRaw": "process.setegid(id)", "type": "method", "name": "setegid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective group identity of the process. (See setegid(2).)\nThis accepts either a numerical ID or a groupname string. If a groupname\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.getegid && process.setegid) {\n  console.log(`Current gid: ${process.getegid()}`);\n  try {\n    process.setegid(501);\n    console.log(`New gid: ${process.getegid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.seteuid(id)", "type": "method", "name": "seteuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the effective user identity of the process. (See seteuid(2).)\nThis accepts either a numerical ID or a username string. If a username\nis specified, this method blocks while resolving it to a numerical ID.\n\n

\n
if (process.geteuid && process.seteuid) {\n  console.log(`Current uid: ${process.geteuid()}`);\n  try {\n    process.seteuid(501);\n    console.log(`New uid: ${process.geteuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgid(id)", "type": "method", "name": "setgid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the group identity of the process. (See setgid(2).) This accepts either\na numerical ID or a groupname string. If a groupname is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getgid && process.setgid) {\n  console.log(`Current gid: ${process.getgid()}`);\n  try {\n    process.setgid(501);\n    console.log(`New gid: ${process.getgid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set gid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.setgroups(groups)", "type": "method", "name": "setgroups", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the supplementary group IDs. This is a privileged operation, meaning you\nneed to be root or have the CAP_SETGID capability.\n\n

\n

The list can contain group IDs, group names or both.\n\n

\n", "signatures": [ { "params": [ { "name": "groups" } ] } ] }, { "textRaw": "process.setuid(id)", "type": "method", "name": "setuid", "desc": "

Note: this function is only available on POSIX platforms (i.e. not Windows,\nAndroid)\n\n

\n

Sets the user identity of the process. (See setuid(2).) This accepts either\na numerical ID or a username string. If a username is specified, this method\nblocks while resolving it to a numerical ID.\n\n

\n
if (process.getuid && process.setuid) {\n  console.log(`Current uid: ${process.getuid()}`);\n  try {\n    process.setuid(501);\n    console.log(`New uid: ${process.getuid()}`);\n  }\n  catch (err) {\n    console.log(`Failed to set uid: ${err}`);\n  }\n}
\n", "signatures": [ { "params": [ { "name": "id" } ] } ] }, { "textRaw": "process.umask([mask])", "type": "method", "name": "umask", "desc": "

Sets or reads the process's file mode creation mask. Child processes inherit\nthe mask from the parent process. Returns the old mask if mask argument is\ngiven, otherwise returns the current mask.\n\n

\n
const newmask = 0o022;\nconst oldmask = process.umask(newmask);\nconsole.log(\n  `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}`\n);
\n", "signatures": [ { "params": [ { "name": "mask", "optional": true } ] } ] }, { "textRaw": "process.uptime()", "type": "method", "name": "uptime", "desc": "

Number of seconds Node.js has been running.\n\n

\n", "signatures": [ { "params": [] } ] } ], "properties": [ { "textRaw": "process.arch", "name": "arch", "desc": "

What processor architecture you're running on: 'arm', 'ia32', or 'x64'.\n\n

\n
console.log('This processor architecture is ' + process.arch);
\n" }, { "textRaw": "process.argv", "name": "argv", "desc": "

An array containing the command line arguments. The first element will be\n'node', the second element will be the name of the JavaScript file. The\nnext elements will be any additional command line arguments.\n\n

\n
// print process.argv\nprocess.argv.forEach((val, index, array) => {\n  console.log(`${index}: ${val}`);\n});
\n

This will generate:\n\n

\n
$ node process-2.js one two=three four\n0: node\n1: /Users/mjr/work/node/process-2.js\n2: one\n3: two=three\n4: four
\n" }, { "textRaw": "process.config", "name": "config", "desc": "

An Object containing the JavaScript representation of the configure options\nthat were used to compile the current Node.js executable. This is the same as\nthe config.gypi file that was produced when running the ./configure script.\n\n

\n

An example of the possible output looks like:\n\n

\n
{ target_defaults:\n   { cflags: [],\n     default_configuration: 'Release',\n     defines: [],\n     include_dirs: [],\n     libraries: [] },\n  variables:\n   { host_arch: 'x64',\n     node_install_npm: 'true',\n     node_prefix: '',\n     node_shared_cares: 'false',\n     node_shared_http_parser: 'false',\n     node_shared_libuv: 'false',\n     node_shared_zlib: 'false',\n     node_use_dtrace: 'false',\n     node_use_openssl: 'true',\n     node_shared_openssl: 'false',\n     strict_aliasing: 'true',\n     target_arch: 'x64',\n     v8_use_snapshot: 'true' } }
\n", "properties": [ { "textRaw": "`connected` {Boolean} Set to false after `process.disconnect()` is called ", "name": "connected", "desc": "

If process.connected is false, it is no longer possible to send messages.\n\n

\n", "shortDesc": "Set to false after `process.disconnect()` is called" } ] }, { "textRaw": "process.env", "name": "env", "desc": "

An object containing the user environment. See environ(7).\n\n

\n

An example of this object looks like:\n\n

\n
{ TERM: 'xterm-256color',\n  SHELL: '/usr/local/bin/bash',\n  USER: 'maciej',\n  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',\n  PWD: '/Users/maciej',\n  EDITOR: 'vim',\n  SHLVL: '1',\n  HOME: '/Users/maciej',\n  LOGNAME: 'maciej',\n  _: '/usr/local/bin/node' }
\n

You can write to this object, but changes won't be reflected outside of your\nprocess. That means that the following won't work:\n\n

\n
$ node -e 'process.env.foo = "bar"' && echo $foo
\n

But this will:\n\n

\n
process.env.foo = 'bar';\nconsole.log(process.env.foo);
\n" }, { "textRaw": "process.execArgv", "name": "execArgv", "desc": "

This is the set of Node.js-specific command line options from the\nexecutable that started the process. These options do not show up in\nprocess.argv, and do not include the Node.js executable, the name of\nthe script, or any options following the script name. These options\nare useful in order to spawn child processes with the same execution\nenvironment as the parent.\n\n

\n

Example:\n\n

\n
$ node --harmony script.js --version
\n

results in process.execArgv:\n\n

\n
['--harmony']
\n

and process.argv:\n\n

\n
['/usr/local/bin/node', 'script.js', '--version']
\n" }, { "textRaw": "process.execPath", "name": "execPath", "desc": "

This is the absolute pathname of the executable that started the process.\n\n

\n

Example:\n\n

\n
/usr/local/bin/node
\n" }, { "textRaw": "process.exitCode", "name": "exitCode", "desc": "

A number which will be the process exit code, when the process either\nexits gracefully, or is exited via [process.exit()][] without specifying\na code.\n\n

\n

Specifying a code to process.exit(code) will override any previous\nsetting of process.exitCode.\n\n\n

\n" }, { "textRaw": "process.mainModule", "name": "mainModule", "desc": "

Alternate way to retrieve [require.main][]. The difference is that if the main\nmodule changes at runtime, require.main might still refer to the original main\nmodule in modules that were required before the change occurred. Generally it's\nsafe to assume that the two refer to the same module.\n\n

\n

As with require.main, it will be undefined if there was no entry script.\n\n

\n" }, { "textRaw": "process.pid", "name": "pid", "desc": "

The PID of the process.\n\n

\n
console.log(`This process is pid ${process.pid}`);
\n" }, { "textRaw": "process.platform", "name": "platform", "desc": "

What platform you're running on:\n'darwin', 'freebsd', 'linux', 'sunos' or 'win32'\n\n

\n
console.log(`This platform is ${process.platform}`);
\n" }, { "textRaw": "process.release", "name": "release", "desc": "

An Object containing metadata related to the current release, including URLs\nfor the source tarball and headers-only tarball.\n\n

\n

process.release contains the following properties:\n\n

\n
    \n
  • name: a string with a value that will always be 'node' for Node.js. For\nlegacy io.js releases, this will be 'io.js'.
  • \n
  • sourceUrl: a complete URL pointing to a .tar.gz file containing the\nsource of the current release.
  • \n
  • headersUrl: a complete URL pointing to a .tar.gz file containing only\nthe header files for the current release. This file is significantly smaller\nthan the full source file and can be used for compiling add-ons against\nNode.js.
  • \n
  • libUrl: a complete URL pointing to an node.lib file matching the\narchitecture and version of the current release. This file is used for\ncompiling add-ons against Node.js. This property is only present on Windows\nbuilds of Node.js and will be missing on all other platforms.
  • \n
\n

e.g.\n\n

\n
{ name: 'node',\n  sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz',\n  headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz',\n  libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' }
\n

In custom builds from non-release versions of the source tree, only the\nname property may be present. The additional properties should not be\nrelied upon to exist.\n\n

\n" }, { "textRaw": "process.stderr", "name": "stderr", "desc": "

A writable stream to stderr (on fd 2).\n\n

\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the finish\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n" }, { "textRaw": "process.stdin", "name": "stdin", "desc": "

A Readable Stream for stdin (on fd 0).\n\n

\n

Example of opening standard input and listening for both events:\n\n

\n
process.stdin.setEncoding('utf8');\n\nprocess.stdin.on('readable', () => {\n  var chunk = process.stdin.read();\n  if (chunk !== null) {\n    process.stdout.write(`data: ${chunk}`);\n  }\n});\n\nprocess.stdin.on('end', () => {\n  process.stdout.write('end');\n});
\n

As a Stream, process.stdin can also be used in "old" mode that is compatible\nwith scripts written for node.js prior to v0.10.\nFor more information see [Stream compatibility][].\n\n

\n

In "old" Streams mode the stdin stream is paused by default, so one\nmust call process.stdin.resume() to read from it. Note also that calling\nprocess.stdin.resume() itself would switch stream to "old" mode.\n\n

\n

If you are starting a new project you should prefer a more recent "new" Streams\nmode over "old" one.\n\n

\n" }, { "textRaw": "process.stdout", "name": "stdout", "desc": "

A Writable Stream to stdout (on fd 1).\n\n

\n

For example, a console.log equivalent could look like this:\n\n

\n
console.log = function(msg) {\n  process.stdout.write(`${msg}\\n`);\n};
\n

process.stderr and process.stdout are unlike other streams in Node.js in\nthat they cannot be closed (end() will throw), they never emit the 'finish'\nevent and that writes can block when output is redirected to a file (although\ndisks are fast and operating systems normally employ write-back caching so it\nshould be a very rare occurrence indeed.)\n\n

\n

To check if Node.js is being run in a TTY context, read the isTTY property\non process.stderr, process.stdout, or process.stdin:\n\n

\n
$ node -p "Boolean(process.stdin.isTTY)"\ntrue\n$ echo "foo" | node -p "Boolean(process.stdin.isTTY)"\nfalse\n\n$ node -p "Boolean(process.stdout.isTTY)"\ntrue\n$ node -p "Boolean(process.stdout.isTTY)" | cat\nfalse
\n

See [the tty docs][] for more information.\n\n

\n" }, { "textRaw": "process.title", "name": "title", "desc": "

Getter/setter to set what is displayed in ps.\n\n

\n

When used as a setter, the maximum length is platform-specific and probably\nshort.\n\n

\n

On Linux and OS X, it's limited to the size of the binary name plus the\nlength of the command line arguments because it overwrites the argv memory.\n\n

\n

v0.8 allowed for longer process title strings by also overwriting the environ\nmemory but that was potentially insecure/confusing in some (rather obscure)\ncases.\n\n

\n" }, { "textRaw": "process.version", "name": "version", "desc": "

A compiled-in property that exposes NODE_VERSION.\n\n

\n
console.log(`Version: ${process.version}`);
\n" }, { "textRaw": "process.versions", "name": "versions", "desc": "

A property exposing version strings of Node.js and its dependencies.\n\n

\n
console.log(process.versions);
\n

Will print something like:\n\n

\n
{ http_parser: '2.3.0',\n  node: '1.1.1',\n  v8: '4.1.0.14',\n  uv: '1.3.0',\n  zlib: '1.2.8',\n  ares: '1.10.0-DEV',\n  modules: '43',\n  icu: '55.1',\n  openssl: '1.0.1k' }
\n" } ] } ] } node-v4.2.6/doc/api/process.markdown000644 000766 000024 00000077720 12650222326 017523 0ustar00iojsstaff000000 000000 # process The `process` object is a global object and can be accessed from anywhere. It is an instance of [`EventEmitter`][]. ## Event: 'beforeExit' This event is emitted when Node.js empties its event loop and has nothing else to schedule. Normally, Node.js exits when there is no work scheduled, but a listener for `'beforeExit'` can make asynchronous calls, and cause Node.js to continue. `'beforeExit'` is not emitted for conditions causing explicit termination, such as [`process.exit()`][] or uncaught exceptions, and should not be used as an alternative to the `'exit'` event unless the intention is to schedule more work. ## Event: 'exit' Emitted when the process is about to exit. There is no way to prevent the exiting of the event loop at this point, and once all `'exit'` listeners have finished running the process will exit. Therefore you **must** only perform **synchronous** operations in this handler. This is a good hook to perform checks on the module's state (like for unit tests). The callback takes one argument, the code the process is exiting with. This event is only emitted when Node.js exits explicitly by process.exit() or implicitly by the event loop draining. Example of listening for `'exit'`: process.on('exit', (code) => { // do *NOT* do this setTimeout(() => { console.log('This will not run'); }, 0); console.log('About to exit with code:', code); }); ## Event: 'message' * `message` {Object} a parsed JSON object or primitive value * `sendHandle` {Handle object} a [`net.Socket`][] or [`net.Server`][] object, or undefined. Messages sent by [`ChildProcess.send()`][] are obtained using the `'message'` event on the child's process object. ## Event: 'rejectionHandled' Emitted whenever a Promise was rejected and an error handler was attached to it (for example with `.catch()`) later than after an event loop turn. This event is emitted with the following arguments: - `p` the promise that was previously emitted in an `'unhandledRejection'` event, but which has now gained a rejection handler. There is no notion of a top level for a promise chain at which rejections can always be handled. Being inherently asynchronous in nature, a promise rejection can be be handled at a future point in time — possibly much later than the event loop turn it takes for the `'unhandledRejection'` event to be emitted. Another way of stating this is that, unlike in synchronous code where there is an ever-growing list of unhandled exceptions, with promises there is a growing-and-shrinking list of unhandled rejections. In synchronous code, the `'uncaughtException'` event tells you when the list of unhandled exceptions grows. And in asynchronous code, the `'unhandledRejection'` event tells you when the list of unhandled rejections grows, while the `'rejectionHandled'` event tells you when the list of unhandled rejections shrinks. For example using the rejection detection hooks in order to keep a map of all the rejected promise reasons at a given time: const unhandledRejections = new Map(); process.on('unhandledRejection', (reason, p) => { unhandledRejections.set(p, reason); }); process.on('rejectionHandled', (p) => { unhandledRejections.delete(p); }); This map will grow and shrink over time, reflecting rejections that start unhandled and then become handled. You could record the errors in some error log, either periodically (probably best for long-running programs, allowing you to clear the map, which in the case of a very buggy program could grow indefinitely) or upon process exit (more convenient for scripts). ## Event: 'uncaughtException' Emitted when an exception bubbles all the way back to the event loop. If a listener is added for this exception, the default action (which is to print a stack trace and exit) will not occur. Example of listening for `'uncaughtException'`: process.on('uncaughtException', (err) => { console.log(`Caught exception: ${err}`); }); setTimeout(() => { console.log('This will still run.'); }, 500); // Intentionally cause an exception, but don't catch it. nonexistentFunc(); console.log('This will not run.'); Note that `'uncaughtException'` is a very crude mechanism for exception handling. Do *not* use it as the Node.js equivalent of `On Error Resume Next`. An unhandled exception means your application - and by extension Node.js itself - is in an undefined state. Blindly resuming means *anything* could happen. Think of resuming as pulling the power cord when you are upgrading your system. Nine out of ten times nothing happens - but the 10th time, your system is bust. `'uncaughtException'` should be used to perform synchronous cleanup before shutting down the process. It is not safe to resume normal operation after `'uncaughtException'`. If you do use it, restart your application after every unhandled exception! You have been warned. ## Event: 'unhandledRejection' Emitted whenever a `Promise` is rejected and no error handler is attached to the promise within a turn of the event loop. When programming with promises exceptions are encapsulated as rejected promises. Such promises can be caught and handled using [`promise.catch(...)`][] and rejections are propagated through a promise chain. This event is useful for detecting and keeping track of promises that were rejected whose rejections were not handled yet. This event is emitted with the following arguments: - `reason` the object with which the promise was rejected (usually an [`Error`][] instance). - `p` the promise that was rejected. Here is an example that logs every unhandled rejection to the console process.on('unhandledRejection', (reason, p) => { console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); // application specific logging, throwing an error, or other logic here }); For example, here is a rejection that will trigger the `'unhandledRejection'` event: somePromise.then((res) => { return reportToUser(JSON.parse(res)); // note the typo }); // no `.catch` or `.then` Here is an example of a coding pattern that will also trigger `'unhandledRejection'`: function SomeResource() { // Initially set the loaded status to a rejected promise this.loaded = Promise.reject(new Error('Resource not yet loaded!')); } var resource = new SomeResource(); // no .catch or .then on resource.loaded for at least a turn In cases like this, you may not want to track the rejection as a developer error like you would for other `'unhandledRejection'` events. To address this, you can either attach a dummy `.catch(function() { })` handler to `resource.loaded`, preventing the `'unhandledRejection'` event from being emitted, or you can use the `'rejectionHandled'` event. Below is an explanation of how to do that. ## Exit Codes Node.js will normally exit with a `0` status code when no more async operations are pending. The following status codes are used in other cases: * `1` **Uncaught Fatal Exception** - There was an uncaught exception, and it was not handled by a domain or an `'uncaughtException'` event handler. * `2` - Unused (reserved by Bash for builtin misuse) * `3` **Internal JavaScript Parse Error** - The JavaScript source code internal in Node.js's bootstrapping process caused a parse error. This is extremely rare, and generally can only happen during development of Node.js itself. * `4` **Internal JavaScript Evaluation Failure** - The JavaScript source code internal in Node.js's bootstrapping process failed to return a function value when evaluated. This is extremely rare, and generally can only happen during development of Node.js itself. * `5` **Fatal Error** - There was a fatal unrecoverable error in V8. Typically a message will be printed to stderr with the prefix `FATAL ERROR`. * `6` **Non-function Internal Exception Handler** - There was an uncaught exception, but the internal fatal exception handler function was somehow set to a non-function, and could not be called. * `7` **Internal Exception Handler Run-Time Failure** - There was an uncaught exception, and the internal fatal exception handler function itself threw an error while attempting to handle it. This can happen, for example, if a `process.on('uncaughtException')` or `domain.on('error')` handler throws an error. * `8` - Unused. In previous versions of Node.js, exit code 8 sometimes indicated an uncaught exception. * `9` - **Invalid Argument** - Either an unknown option was specified, or an option requiring a value was provided without a value. * `10` **Internal JavaScript Run-Time Failure** - The JavaScript source code internal in Node.js's bootstrapping process threw an error when the bootstrapping function was called. This is extremely rare, and generally can only happen during development of Node.js itself. * `12` **Invalid Debug Argument** - The `--debug` and/or `--debug-brk` options were set, but an invalid port number was chosen. * `>128` **Signal Exits** - If Node.js receives a fatal signal such as `SIGKILL` or `SIGHUP`, then its exit code will be `128` plus the value of the signal code. This is a standard Unix practice, since exit codes are defined to be 7-bit integers, and signal exits set the high-order bit, and then contain the value of the signal code. ## Signal Events Emitted when the processes receives a signal. See sigaction(2) for a list of standard POSIX signal names such as `SIGINT`, `SIGHUP`, etc. Example of listening for `SIGINT`: // Start reading from stdin so we don't exit. process.stdin.resume(); process.on('SIGINT', () => { console.log('Got SIGINT. Press Control-D to exit.'); }); An easy way to send the `SIGINT` signal is with `Control-C` in most terminal programs. Note: - `SIGUSR1` is reserved by Node.js to start the debugger. It's possible to install a listener but that won't stop the debugger from starting. - `SIGTERM` and `SIGINT` have default handlers on non-Windows platforms that resets the terminal mode before exiting with code `128 + signal number`. If one of these signals has a listener installed, its default behavior will be removed (Node.js will no longer exit). - `SIGPIPE` is ignored by default. It can have a listener installed. - `SIGHUP` is generated on Windows when the console window is closed, and on other platforms under various similar conditions, see signal(7). It can have a listener installed, however Node.js will be unconditionally terminated by Windows about 10 seconds later. On non-Windows platforms, the default behavior of `SIGHUP` is to terminate Node.js, but once a listener has been installed its default behavior will be removed. - `SIGTERM` is not supported on Windows, it can be listened on. - `SIGINT` from the terminal is supported on all platforms, and can usually be generated with `CTRL+C` (though this may be configurable). It is not generated when terminal raw mode is enabled. - `SIGBREAK` is delivered on Windows when `CTRL+BREAK` is pressed, on non-Windows platforms it can be listened on, but there is no way to send or generate it. - `SIGWINCH` is delivered when the console has been resized. On Windows, this will only happen on write to the console when the cursor is being moved, or when a readable tty is used in raw mode. - `SIGKILL` cannot have a listener installed, it will unconditionally terminate Node.js on all platforms. - `SIGSTOP` cannot have a listener installed. Note that Windows does not support sending Signals, but Node.js offers some emulation with `process.kill()`, and `child_process.kill()`. Sending signal `0` can be used to test for the existence of a process. Sending `SIGINT`, `SIGTERM`, and `SIGKILL` cause the unconditional termination of the target process. ## process.abort() This causes Node.js to emit an abort. This will cause Node.js to exit and generate a core file. ## process.arch What processor architecture you're running on: `'arm'`, `'ia32'`, or `'x64'`. console.log('This processor architecture is ' + process.arch); ## process.argv An array containing the command line arguments. The first element will be 'node', the second element will be the name of the JavaScript file. The next elements will be any additional command line arguments. // print process.argv process.argv.forEach((val, index, array) => { console.log(`${index}: ${val}`); }); This will generate: $ node process-2.js one two=three four 0: node 1: /Users/mjr/work/node/process-2.js 2: one 3: two=three 4: four ## process.chdir(directory) Changes the current working directory of the process or throws an exception if that fails. console.log(`Starting directory: ${process.cwd()}`); try { process.chdir('/tmp'); console.log(`New directory: ${process.cwd()}`); } catch (err) { console.log(`chdir: ${err}`); } ## process.config An Object containing the JavaScript representation of the configure options that were used to compile the current Node.js executable. This is the same as the `config.gypi` file that was produced when running the `./configure` script. An example of the possible output looks like: { target_defaults: { cflags: [], default_configuration: 'Release', defines: [], include_dirs: [], libraries: [] }, variables: { host_arch: 'x64', node_install_npm: 'true', node_prefix: '', node_shared_cares: 'false', node_shared_http_parser: 'false', node_shared_libuv: 'false', node_shared_zlib: 'false', node_use_dtrace: 'false', node_use_openssl: 'true', node_shared_openssl: 'false', strict_aliasing: 'true', target_arch: 'x64', v8_use_snapshot: 'true' } } ### process.connected * {Boolean} Set to false after `process.disconnect()` is called If `process.connected` is false, it is no longer possible to send messages. ## process.cwd() Returns the current working directory of the process. console.log(`Current directory: ${process.cwd()}`); ## process.disconnect() Close the IPC channel to the parent process, allowing this child to exit gracefully once there are no other connections keeping it alive. Identical to the parent process's [`ChildProcess.disconnect()`][]. If Node.js was not spawned with an IPC channel, `process.disconnect()` will be undefined. ## process.env An object containing the user environment. See environ(7). An example of this object looks like: { TERM: 'xterm-256color', SHELL: '/usr/local/bin/bash', USER: 'maciej', PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin', PWD: '/Users/maciej', EDITOR: 'vim', SHLVL: '1', HOME: '/Users/maciej', LOGNAME: 'maciej', _: '/usr/local/bin/node' } You can write to this object, but changes won't be reflected outside of your process. That means that the following won't work: $ node -e 'process.env.foo = "bar"' && echo $foo But this will: process.env.foo = 'bar'; console.log(process.env.foo); ## process.execArgv This is the set of Node.js-specific command line options from the executable that started the process. These options do not show up in `process.argv`, and do not include the Node.js executable, the name of the script, or any options following the script name. These options are useful in order to spawn child processes with the same execution environment as the parent. Example: $ node --harmony script.js --version results in process.execArgv: ['--harmony'] and process.argv: ['/usr/local/bin/node', 'script.js', '--version'] ## process.execPath This is the absolute pathname of the executable that started the process. Example: /usr/local/bin/node ## process.exit([code]) Ends the process with the specified `code`. If omitted, exit uses the 'success' code `0`. To exit with a 'failure' code: process.exit(1); The shell that executed Node.js should see the exit code as 1. ## process.exitCode A number which will be the process exit code, when the process either exits gracefully, or is exited via [`process.exit()`][] without specifying a code. Specifying a code to `process.exit(code)` will override any previous setting of `process.exitCode`. ## process.getegid() Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Gets the effective group identity of the process. (See getegid(2).) This is the numerical group id, not the group name. if (process.getegid) { console.log(`Current gid: ${process.getegid()}`); } ## process.geteuid() Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Gets the effective user identity of the process. (See geteuid(2).) This is the numerical userid, not the username. if (process.geteuid) { console.log(`Current uid: ${process.geteuid()}`); } ## process.getgid() Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Gets the group identity of the process. (See getgid(2).) This is the numerical group id, not the group name. if (process.getgid) { console.log(`Current gid: ${process.getgid()}`); } ## process.getgroups() Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Returns an array with the supplementary group IDs. POSIX leaves it unspecified if the effective group ID is included but Node.js ensures it always is. ## process.getuid() Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Gets the user identity of the process. (See getuid(2).) This is the numerical userid, not the username. if (process.getuid) { console.log(`Current uid: ${process.getuid()}`); } ## process.hrtime() Returns the current high-resolution real time in a `[seconds, nanoseconds]` tuple Array. It is relative to an arbitrary time in the past. It is not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals. You may pass in the result of a previous call to `process.hrtime()` to get a diff reading, useful for benchmarks and measuring intervals: var time = process.hrtime(); // [ 1800216, 25 ] setTimeout(() => { var diff = process.hrtime(time); // [ 1, 552 ] console.log('benchmark took %d nanoseconds', diff[0] * 1e9 + diff[1]); // benchmark took 1000000527 nanoseconds }, 1000); ## process.initgroups(user, extra_group) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Reads /etc/group and initializes the group access list, using all groups of which the user is a member. This is a privileged operation, meaning you need to be root or have the `CAP_SETGID` capability. `user` is a user name or user ID. `extra_group` is a group name or group ID. Some care needs to be taken when dropping privileges. Example: console.log(process.getgroups()); // [ 0 ] process.initgroups('bnoordhuis', 1000); // switch user console.log(process.getgroups()); // [ 27, 30, 46, 1000, 0 ] process.setgid(1000); // drop root gid console.log(process.getgroups()); // [ 27, 30, 46, 1000 ] ## process.kill(pid[, signal]) Send a signal to a process. `pid` is the process id and `signal` is the string describing the signal to send. Signal names are strings like `SIGINT` or `SIGHUP`. If omitted, the signal will be `SIGTERM`. See [Signal Events][] and kill(2) for more information. Will throw an error if target does not exist, and as a special case, a signal of `0` can be used to test for the existence of a process. Windows platforms will throw an error if the `pid` is used to kill a process group. Note that even though the name of this function is `process.kill`, it is really just a signal sender, like the `kill` system call. The signal sent may do something other than kill the target process. Example of sending a signal to yourself: process.on('SIGHUP', () => { console.log('Got SIGHUP signal.'); }); setTimeout(() => { console.log('Exiting.'); process.exit(0); }, 100); process.kill(process.pid, 'SIGHUP'); Note: When SIGUSR1 is received by Node.js it starts the debugger, see [Signal Events][]. ## process.mainModule Alternate way to retrieve [`require.main`][]. The difference is that if the main module changes at runtime, `require.main` might still refer to the original main module in modules that were required before the change occurred. Generally it's safe to assume that the two refer to the same module. As with `require.main`, it will be `undefined` if there was no entry script. ## process.memoryUsage() Returns an object describing the memory usage of the Node.js process measured in bytes. const util = require('util'); console.log(util.inspect(process.memoryUsage())); This will generate: { rss: 4935680, heapTotal: 1826816, heapUsed: 650472 } `heapTotal` and `heapUsed` refer to V8's memory usage. ## process.nextTick(callback[, arg][, ...]) * `callback` {Function} Once the current event loop turn runs to completion, call the callback function. This is *not* a simple alias to [`setTimeout(fn, 0)`][], it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop. console.log('start'); process.nextTick(() => { console.log('nextTick callback'); }); console.log('scheduled'); // Output: // start // scheduled // nextTick callback This is important in developing APIs where you want to give the user the chance to assign event handlers after an object has been constructed, but before any I/O has occurred. function MyThing(options) { this.setupOptions(options); process.nextTick(() => { this.startDoingStuff(); }.bind(this)); } var thing = new MyThing(); thing.getReadyForStuff(); // thing.startDoingStuff() gets called now, not before. It is very important for APIs to be either 100% synchronous or 100% asynchronous. Consider this example: // WARNING! DO NOT USE! BAD UNSAFE HAZARD! function maybeSync(arg, cb) { if (arg) { cb(); return; } fs.stat('file', cb); } This API is hazardous. If you do this: maybeSync(true, function() { foo(); }); bar(); then it's not clear whether `foo()` or `bar()` will be called first. This approach is much better: function definitelyAsync(arg, cb) { if (arg) { process.nextTick(cb); return; } fs.stat('file', cb); } Note: the nextTick queue is completely drained on each pass of the event loop **before** additional I/O is processed. As a result, recursively setting nextTick callbacks will block any I/O from happening, just like a `while(true);` loop. ## process.pid The PID of the process. console.log(`This process is pid ${process.pid}`); ## process.platform What platform you're running on: `'darwin'`, `'freebsd'`, `'linux'`, `'sunos'` or `'win32'` console.log(`This platform is ${process.platform}`); ## process.release An Object containing metadata related to the current release, including URLs for the source tarball and headers-only tarball. `process.release` contains the following properties: * `name`: a string with a value that will always be `'node'` for Node.js. For legacy io.js releases, this will be `'io.js'`. * `sourceUrl`: a complete URL pointing to a _.tar.gz_ file containing the source of the current release. * `headersUrl`: a complete URL pointing to a _.tar.gz_ file containing only the header files for the current release. This file is significantly smaller than the full source file and can be used for compiling add-ons against Node.js. * `libUrl`: a complete URL pointing to an _node.lib_ file matching the architecture and version of the current release. This file is used for compiling add-ons against Node.js. _This property is only present on Windows builds of Node.js and will be missing on all other platforms._ e.g. { name: 'node', sourceUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0.tar.gz', headersUrl: 'https://nodejs.org/download/release/v4.0.0/node-v4.0.0-headers.tar.gz', libUrl: 'https://nodejs.org/download/release/v4.0.0/win-x64/node.lib' } In custom builds from non-release versions of the source tree, only the `name` property may be present. The additional properties should not be relied upon to exist. ## process.send(message[, sendHandle][, callback]) * `message` {Object} * `sendHandle` {Handle object} When Node.js is spawned with an IPC channel attached, it can send messages to its parent process using `process.send()`. Each will be received as a [`'message'`][] event on the parent's `ChildProcess` object. If Node.js was not spawned with an IPC channel, `process.send()` will be undefined. ## process.setegid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Sets the effective group identity of the process. (See setegid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. if (process.getegid && process.setegid) { console.log(`Current gid: ${process.getegid()}`); try { process.setegid(501); console.log(`New gid: ${process.getegid()}`); } catch (err) { console.log(`Failed to set gid: ${err}`); } } ## process.seteuid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Sets the effective user identity of the process. (See seteuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. if (process.geteuid && process.seteuid) { console.log(`Current uid: ${process.geteuid()}`); try { process.seteuid(501); console.log(`New uid: ${process.geteuid()}`); } catch (err) { console.log(`Failed to set uid: ${err}`); } } ## process.setgid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Sets the group identity of the process. (See setgid(2).) This accepts either a numerical ID or a groupname string. If a groupname is specified, this method blocks while resolving it to a numerical ID. if (process.getgid && process.setgid) { console.log(`Current gid: ${process.getgid()}`); try { process.setgid(501); console.log(`New gid: ${process.getgid()}`); } catch (err) { console.log(`Failed to set gid: ${err}`); } } ## process.setgroups(groups) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Sets the supplementary group IDs. This is a privileged operation, meaning you need to be root or have the `CAP_SETGID` capability. The list can contain group IDs, group names or both. ## process.setuid(id) Note: this function is only available on POSIX platforms (i.e. not Windows, Android) Sets the user identity of the process. (See setuid(2).) This accepts either a numerical ID or a username string. If a username is specified, this method blocks while resolving it to a numerical ID. if (process.getuid && process.setuid) { console.log(`Current uid: ${process.getuid()}`); try { process.setuid(501); console.log(`New uid: ${process.getuid()}`); } catch (err) { console.log(`Failed to set uid: ${err}`); } } ## process.stderr A writable stream to stderr (on fd `2`). `process.stderr` and `process.stdout` are unlike other streams in Node.js in that they cannot be closed (`end()` will throw), they never emit the `finish` event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.) ## process.stdin A `Readable Stream` for stdin (on fd `0`). Example of opening standard input and listening for both events: process.stdin.setEncoding('utf8'); process.stdin.on('readable', () => { var chunk = process.stdin.read(); if (chunk !== null) { process.stdout.write(`data: ${chunk}`); } }); process.stdin.on('end', () => { process.stdout.write('end'); }); As a Stream, `process.stdin` can also be used in "old" mode that is compatible with scripts written for node.js prior to v0.10. For more information see [Stream compatibility][]. In "old" Streams mode the stdin stream is paused by default, so one must call `process.stdin.resume()` to read from it. Note also that calling `process.stdin.resume()` itself would switch stream to "old" mode. If you are starting a new project you should prefer a more recent "new" Streams mode over "old" one. ## process.stdout A `Writable Stream` to `stdout` (on fd `1`). For example, a `console.log` equivalent could look like this: console.log = function(msg) { process.stdout.write(`${msg}\n`); }; `process.stderr` and `process.stdout` are unlike other streams in Node.js in that they cannot be closed (`end()` will throw), they never emit the `'finish'` event and that writes can block when output is redirected to a file (although disks are fast and operating systems normally employ write-back caching so it should be a very rare occurrence indeed.) To check if Node.js is being run in a TTY context, read the `isTTY` property on `process.stderr`, `process.stdout`, or `process.stdin`: $ node -p "Boolean(process.stdin.isTTY)" true $ echo "foo" | node -p "Boolean(process.stdin.isTTY)" false $ node -p "Boolean(process.stdout.isTTY)" true $ node -p "Boolean(process.stdout.isTTY)" | cat false See [the tty docs][] for more information. ## process.title Getter/setter to set what is displayed in `ps`. When used as a setter, the maximum length is platform-specific and probably short. On Linux and OS X, it's limited to the size of the binary name plus the length of the command line arguments because it overwrites the argv memory. v0.8 allowed for longer process title strings by also overwriting the environ memory but that was potentially insecure/confusing in some (rather obscure) cases. ## process.umask([mask]) Sets or reads the process's file mode creation mask. Child processes inherit the mask from the parent process. Returns the old mask if `mask` argument is given, otherwise returns the current mask. const newmask = 0o022; const oldmask = process.umask(newmask); console.log( `Changed umask from ${oldmask.toString(8)} to ${newmask.toString(8)}` ); ## process.uptime() Number of seconds Node.js has been running. ## process.version A compiled-in property that exposes `NODE_VERSION`. console.log(`Version: ${process.version}`); ## process.versions A property exposing version strings of Node.js and its dependencies. console.log(process.versions); Will print something like: { http_parser: '2.3.0', node: '1.1.1', v8: '4.1.0.14', uv: '1.3.0', zlib: '1.2.8', ares: '1.10.0-DEV', modules: '43', icu: '55.1', openssl: '1.0.1k' } [`'message'`]: child_process.html#child_process_event_message [`ChildProcess.disconnect()`]: child_process.html#child_process_child_disconnect [`ChildProcess.send()`]: child_process.html#child_process_child_send_message_sendhandle_callback [`Error`]: errors.html#errors_class_error [`EventEmitter`]: events.html#events_class_events_eventemitter [`net.Server`]: net.html#net_class_net_server [`net.Socket`]: net.html#net_class_net_socket [`process.exit()`]: #process_process_exit_code [`promise.catch(...)`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch [`require.main`]: modules.html#modules_accessing_the_main_module [`setTimeout(fn, 0)`]: timers.html#timers_settimeout_callback_delay_arg [Signal Events]: #process_signal_events [Stream compatibility]: stream.html#stream_compatibility_with_older_node_js_versions [the tty docs]: tty.html#tty_tty node-v4.2.6/doc/api/punycode.html000644 000766 000024 00000020123 12650222331 016772 0ustar00iojsstaff000000 000000 punycode Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


punycode#

Stability: 2 - Stable

Punycode.js is bundled with Node.js v0.6.2+. Use require('punycode') to access it. (To use it with other Node.js versions, use npm to install the punycode module first.)

punycode.decode(string)#

Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols.

// decode domain name parts
punycode.decode('maana-pta'); // 'mañana'
punycode.decode('--dqo34k'); // '☃-⌘'

punycode.encode(string)#

Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols.

// encode domain name parts
punycode.encode('mañana'); // 'maana-pta'
punycode.encode('☃-⌘'); // '--dqo34k'

punycode.toASCII(domain)#

Converts a Unicode string representing a domain name to Punycode. Only the non-ASCII parts of the domain name will be converted, i.e. it doesn't matter if you call it with a domain that's already in ASCII.

// encode domain names
punycode.toASCII('mañana.com'); // 'xn--maana-pta.com'
punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'

punycode.toUnicode(domain)#

Converts a Punycode string representing a domain name to Unicode. Only the Punycoded parts of the domain name will be converted, i.e. it doesn't matter if you call it on a string that has already been converted to Unicode.

// decode domain names
punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'
punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'

punycode.ucs2#

punycode.ucs2.decode(string)#

Creates an array containing the numeric code point values of each Unicode symbol in the string. While JavaScript uses UCS-2 internally, this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16.

punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]
// surrogate pair for U+1D306 tetragram for centre:
punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306]

punycode.ucs2.encode(codePoints)#

Creates a string based on an array of numeric code point values.

punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'
punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06'

punycode.version#

A string representing the current Punycode.js version number.

node-v4.2.6/doc/api/punycode.json000644 000766 000024 00000011300 12650222331 016774 0ustar00iojsstaff000000 000000 { "source": "doc/api/punycode.markdown", "modules": [ { "textRaw": "punycode", "name": "punycode", "stability": 2, "stabilityText": "Stable", "desc": "

[Punycode.js][] is bundled with Node.js v0.6.2+. Use require('punycode') to\naccess it. (To use it with other Node.js versions, use npm to install the\npunycode module first.)\n\n

\n", "methods": [ { "textRaw": "punycode.decode(string)", "type": "method", "name": "decode", "desc": "

Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols.\n\n

\n
// decode domain name parts\npunycode.decode('maana-pta'); // 'mañana'\npunycode.decode('--dqo34k'); // '☃-⌘'
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "punycode.encode(string)", "type": "method", "name": "encode", "desc": "

Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols.\n\n

\n
// encode domain name parts\npunycode.encode('mañana'); // 'maana-pta'\npunycode.encode('☃-⌘'); // '--dqo34k'
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "punycode.toASCII(domain)", "type": "method", "name": "toASCII", "desc": "

Converts a Unicode string representing a domain name to Punycode. Only the\nnon-ASCII parts of the domain name will be converted, i.e. it doesn't matter if\nyou call it with a domain that's already in ASCII.\n\n

\n
// encode domain names\npunycode.toASCII('mañana.com'); // 'xn--maana-pta.com'\npunycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com'
\n", "signatures": [ { "params": [ { "name": "domain" } ] } ] }, { "textRaw": "punycode.toUnicode(domain)", "type": "method", "name": "toUnicode", "desc": "

Converts a Punycode string representing a domain name to Unicode. Only the\nPunycoded parts of the domain name will be converted, i.e. it doesn't matter if\nyou call it on a string that has already been converted to Unicode.\n\n

\n
// decode domain names\npunycode.toUnicode('xn--maana-pta.com'); // 'mañana.com'\npunycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com'
\n", "signatures": [ { "params": [ { "name": "domain" } ] } ] } ], "properties": [ { "textRaw": "punycode.ucs2", "name": "ucs2", "modules": [ { "textRaw": "punycode.ucs2.decode(string)", "name": "punycode.ucs2.decode(string)", "desc": "

Creates an array containing the numeric code point values of each Unicode\nsymbol in the string. While [JavaScript uses UCS-2 internally][], this function\nwill convert a pair of surrogate halves (each of which UCS-2 exposes as\nseparate characters) into a single code point, matching UTF-16.\n\n

\n
punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63]\n// surrogate pair for U+1D306 tetragram for centre:\npunycode.ucs2.decode('\\uD834\\uDF06'); // [0x1D306]
\n", "type": "module", "displayName": "punycode.ucs2.decode(string)" }, { "textRaw": "punycode.ucs2.encode(codePoints)", "name": "punycode.ucs2.encode(codepoints)", "desc": "

Creates a string based on an array of numeric code point values.\n\n

\n
punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc'\npunycode.ucs2.encode([0x1D306]); // '\\uD834\\uDF06'
\n", "type": "module", "displayName": "punycode.ucs2.encode(codePoints)" } ] }, { "textRaw": "punycode.version", "name": "version", "desc": "

A string representing the current Punycode.js version number.\n\n

\n" } ], "type": "module", "displayName": "punycode" } ] } node-v4.2.6/doc/api/punycode.markdown000644 000766 000024 00000004557 12650222326 017671 0ustar00iojsstaff000000 000000 # punycode Stability: 2 - Stable [Punycode.js][] is bundled with Node.js v0.6.2+. Use `require('punycode')` to access it. (To use it with other Node.js versions, use npm to install the `punycode` module first.) ## punycode.decode(string) Converts a Punycode string of ASCII-only symbols to a string of Unicode symbols. // decode domain name parts punycode.decode('maana-pta'); // 'mañana' punycode.decode('--dqo34k'); // '☃-⌘' ## punycode.encode(string) Converts a string of Unicode symbols to a Punycode string of ASCII-only symbols. // encode domain name parts punycode.encode('mañana'); // 'maana-pta' punycode.encode('☃-⌘'); // '--dqo34k' ## punycode.toASCII(domain) Converts a Unicode string representing a domain name to Punycode. Only the non-ASCII parts of the domain name will be converted, i.e. it doesn't matter if you call it with a domain that's already in ASCII. // encode domain names punycode.toASCII('mañana.com'); // 'xn--maana-pta.com' punycode.toASCII('☃-⌘.com'); // 'xn----dqo34k.com' ## punycode.toUnicode(domain) Converts a Punycode string representing a domain name to Unicode. Only the Punycoded parts of the domain name will be converted, i.e. it doesn't matter if you call it on a string that has already been converted to Unicode. // decode domain names punycode.toUnicode('xn--maana-pta.com'); // 'mañana.com' punycode.toUnicode('xn----dqo34k.com'); // '☃-⌘.com' ## punycode.ucs2 ### punycode.ucs2.decode(string) Creates an array containing the numeric code point values of each Unicode symbol in the string. While [JavaScript uses UCS-2 internally][], this function will convert a pair of surrogate halves (each of which UCS-2 exposes as separate characters) into a single code point, matching UTF-16. punycode.ucs2.decode('abc'); // [0x61, 0x62, 0x63] // surrogate pair for U+1D306 tetragram for centre: punycode.ucs2.decode('\uD834\uDF06'); // [0x1D306] ### punycode.ucs2.encode(codePoints) Creates a string based on an array of numeric code point values. punycode.ucs2.encode([0x61, 0x62, 0x63]); // 'abc' punycode.ucs2.encode([0x1D306]); // '\uD834\uDF06' ## punycode.version A string representing the current Punycode.js version number. [Punycode.js]: https://mths.be/punycode [JavaScript uses UCS-2 internally]: https://mathiasbynens.be/notes/javascript-encoding node-v4.2.6/doc/api/querystring.html000644 000766 000024 00000017073 12650222331 017552 0ustar00iojsstaff000000 000000 Query String Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Query String#

Stability: 2 - Stable

This module provides utilities for dealing with query strings. It provides the following methods:

querystring.escape#

The escape function used by querystring.stringify, provided so that it could be overridden if necessary.

querystring.parse(str[, sep][, eq][, options])#

Deserialize a query string to an object. Optionally override the default separator ('&') and assignment ('=') characters.

Options object may contain maxKeys property (equal to 1000 by default), it'll be used to limit processed keys. Set it to 0 to remove key count limitation.

Options object may contain decodeURIComponent property (querystring.unescape by default), it can be used to decode a non-utf8 encoding string if necessary.

Example:

querystring.parse('foo=bar&baz=qux&baz=quux&corge')
// returns
{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }

// Suppose gbkDecodeURIComponent function already exists,
// it can decode `gbk` encoding string
querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null,
  { decodeURIComponent: gbkDecodeURIComponent })
// returns
{ w: '中文', foo: 'bar' }

querystring.stringify(obj[, sep][, eq][, options])#

Serialize an object to a query string. Optionally override the default separator ('&') and assignment ('=') characters.

Options object may contain encodeURIComponent property (querystring.escape by default), it can be used to encode string with non-utf8 encoding if necessary.

Example:

querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
// returns
'foo=bar&baz=qux&baz=quux&corge='

querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
// returns
'foo:bar;baz:qux'

// Suppose gbkEncodeURIComponent function already exists,
// it can encode string with `gbk` encoding
querystring.stringify({ w: '中文', foo: 'bar' }, null, null,
  { encodeURIComponent: gbkEncodeURIComponent })
// returns
'w=%D6%D0%CE%C4&foo=bar'

querystring.unescape#

The unescape function used by querystring.parse, provided so that it could be overridden if necessary.

It will try to use decodeURIComponent in the first place, but if that fails it falls back to a safer equivalent that doesn't throw on malformed URLs.

node-v4.2.6/doc/api/querystring.json000644 000766 000024 00000010662 12650222331 017554 0ustar00iojsstaff000000 000000 { "source": "doc/api/querystring.markdown", "modules": [ { "textRaw": "Query String", "name": "querystring", "stability": 2, "stabilityText": "Stable", "desc": "

This module provides utilities for dealing with query strings.\nIt provides the following methods:\n\n

\n", "properties": [ { "textRaw": "querystring.escape", "name": "escape", "desc": "

The escape function used by querystring.stringify,\nprovided so that it could be overridden if necessary.\n\n

\n" }, { "textRaw": "querystring.unescape", "name": "unescape", "desc": "

The unescape function used by querystring.parse,\nprovided so that it could be overridden if necessary.\n\n

\n

It will try to use decodeURIComponent in the first place,\nbut if that fails it falls back to a safer equivalent that\ndoesn't throw on malformed URLs.\n

\n" } ], "methods": [ { "textRaw": "querystring.parse(str[, sep][, eq][, options])", "type": "method", "name": "parse", "desc": "

Deserialize a query string to an object.\nOptionally override the default separator ('&') and assignment ('=')\ncharacters.\n\n

\n

Options object may contain maxKeys property (equal to 1000 by default), it'll\nbe used to limit processed keys. Set it to 0 to remove key count limitation.\n\n

\n

Options object may contain decodeURIComponent property (querystring.unescape by default),\nit can be used to decode a non-utf8 encoding string if necessary.\n\n

\n

Example:\n\n

\n
querystring.parse('foo=bar&baz=qux&baz=quux&corge')\n// returns\n{ foo: 'bar', baz: ['qux', 'quux'], corge: '' }\n\n// Suppose gbkDecodeURIComponent function already exists,\n// it can decode `gbk` encoding string\nquerystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null,\n  { decodeURIComponent: gbkDecodeURIComponent })\n// returns\n{ w: '中文', foo: 'bar' }
\n", "signatures": [ { "params": [ { "name": "str" }, { "name": "sep", "optional": true }, { "name": "eq", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "querystring.stringify(obj[, sep][, eq][, options])", "type": "method", "name": "stringify", "desc": "

Serialize an object to a query string.\nOptionally override the default separator ('&') and assignment ('=')\ncharacters.\n\n

\n

Options object may contain encodeURIComponent property (querystring.escape by default),\nit can be used to encode string with non-utf8 encoding if necessary.\n\n

\n

Example:\n\n

\n
querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })\n// returns\n'foo=bar&baz=qux&baz=quux&corge='\n\nquerystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')\n// returns\n'foo:bar;baz:qux'\n\n// Suppose gbkEncodeURIComponent function already exists,\n// it can encode string with `gbk` encoding\nquerystring.stringify({ w: '中文', foo: 'bar' }, null, null,\n  { encodeURIComponent: gbkEncodeURIComponent })\n// returns\n'w=%D6%D0%CE%C4&foo=bar'
\n", "signatures": [ { "params": [ { "name": "obj" }, { "name": "sep", "optional": true }, { "name": "eq", "optional": true }, { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "querystring" } ] } node-v4.2.6/doc/api/querystring.markdown000644 000766 000024 00000004442 12650222326 020430 0ustar00iojsstaff000000 000000 # Query String Stability: 2 - Stable This module provides utilities for dealing with query strings. It provides the following methods: ## querystring.escape The escape function used by `querystring.stringify`, provided so that it could be overridden if necessary. ## querystring.parse(str[, sep][, eq][, options]) Deserialize a query string to an object. Optionally override the default separator (`'&'`) and assignment (`'='`) characters. Options object may contain `maxKeys` property (equal to 1000 by default), it'll be used to limit processed keys. Set it to 0 to remove key count limitation. Options object may contain `decodeURIComponent` property (`querystring.unescape` by default), it can be used to decode a `non-utf8` encoding string if necessary. Example: querystring.parse('foo=bar&baz=qux&baz=quux&corge') // returns { foo: 'bar', baz: ['qux', 'quux'], corge: '' } // Suppose gbkDecodeURIComponent function already exists, // it can decode `gbk` encoding string querystring.parse('w=%D6%D0%CE%C4&foo=bar', null, null, { decodeURIComponent: gbkDecodeURIComponent }) // returns { w: '中文', foo: 'bar' } ## querystring.stringify(obj[, sep][, eq][, options]) Serialize an object to a query string. Optionally override the default separator (`'&'`) and assignment (`'='`) characters. Options object may contain `encodeURIComponent` property (`querystring.escape` by default), it can be used to encode string with `non-utf8` encoding if necessary. Example: querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' }) // returns 'foo=bar&baz=qux&baz=quux&corge=' querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':') // returns 'foo:bar;baz:qux' // Suppose gbkEncodeURIComponent function already exists, // it can encode string with `gbk` encoding querystring.stringify({ w: '中文', foo: 'bar' }, null, null, { encodeURIComponent: gbkEncodeURIComponent }) // returns 'w=%D6%D0%CE%C4&foo=bar' ## querystring.unescape The unescape function used by `querystring.parse`, provided so that it could be overridden if necessary. It will try to use `decodeURIComponent` in the first place, but if that fails it falls back to a safer equivalent that doesn't throw on malformed URLs. node-v4.2.6/doc/api/readline.html000644 000766 000024 00000050032 12650222331 016731 0ustar00iojsstaff000000 000000 Readline Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Readline#

Stability: 2 - Stable

To use this module, do require('readline'). Readline allows reading of a stream (such as process.stdin) on a line-by-line basis.

Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. Here's how to allow your program to gracefully exit:

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log('Thank you for your valuable feedback:', answer);

  rl.close();
});

Class: Interface#

The class that represents a readline interface with an input and output stream.

rl.close()#

Closes the Interface instance, relinquishing control on the input and output streams. The 'close' event will also be emitted.

rl.pause()#

Pauses the readline input stream, allowing it to be resumed later if needed.

Note that this doesn't immediately pause the stream of events. Several events may be emitted after calling pause, including line.

rl.prompt([preserveCursor])#

Readies readline for input from the user, putting the current setPrompt options on a new line, giving the user a new spot to write. Set preserveCursor to true to prevent the cursor placement being reset to 0.

This will also resume the input stream used with createInterface if it has been paused.

If output is set to null or undefined when calling createInterface, the prompt is not written.

rl.question(query, callback)#

Prepends the prompt with query and invokes callback with the user's response. Displays the query to the user, and then invokes callback with the user's response after it has been typed.

This will also resume the input stream used with createInterface if it has been paused.

If output is set to null or undefined when calling createInterface, nothing is displayed.

Example usage:

interface.question('What is your favorite food?', (answer) => {
  console.log(`Oh, so your favorite food is ${answer}`);
});

rl.resume()#

Resumes the readline input stream.

rl.setPrompt(prompt)#

Sets the prompt, for example when you run node on the command line, you see > , which is Node.js's prompt.

rl.write(data[, key])#

Writes data to output stream, unless output is set to null or undefined when calling createInterface. key is an object literal to represent a key sequence; available if the terminal is a TTY.

This will also resume the input stream if it has been paused.

Example:

rl.write('Delete me!');
// Simulate ctrl+u to delete the line written previously
rl.write(null, {ctrl: true, name: 'u'});

Events#

Event: 'close'#

function () {}

Emitted when close() is called.

Also emitted when the input stream receives its 'end' event. The Interface instance should be considered "finished" once this is emitted. For example, when the input stream receives ^D, respectively known as EOT.

This event is also called if there is no SIGINT event listener present when the input stream receives a ^C, respectively known as SIGINT.

Event: 'line'#

function (line) {}

Emitted whenever the input stream receives a \n, usually received when the user hits enter, or return. This is a good hook to listen for user input.

Example of listening for 'line':

rl.on('line', (cmd) => {
  console.log(`You just typed: ${cmd}`);
});

Event: 'pause'#

function () {}

Emitted whenever the input stream is paused.

Also emitted whenever the input stream is not paused and receives the SIGCONT event. (See events SIGTSTP and SIGCONT)

Example of listening for 'pause':

rl.on('pause', () => {
  console.log('Readline paused.');
});

Event: 'resume'#

function () {}

Emitted whenever the input stream is resumed.

Example of listening for 'resume':

rl.on('resume', () => {
  console.log('Readline resumed.');
});

Event: 'SIGCONT'#

function () {}

This does not work on Windows.

Emitted whenever the input stream is sent to the background with ^Z, respectively known as SIGTSTP, and then continued with fg(1). This event only emits if the stream was not paused before sending the program to the background.

Example of listening for SIGCONT:

rl.on('SIGCONT', () => {
  // `prompt` will automatically resume the stream
  rl.prompt();
});

Event: 'SIGINT'#

function () {}

Emitted whenever the input stream receives a ^C, respectively known as SIGINT. If there is no SIGINT event listener present when the input stream receives a SIGINT, pause will be triggered.

Example of listening for SIGINT:

rl.on('SIGINT', () => {
  rl.question('Are you sure you want to exit?', (answer) => {
    if (answer.match(/^y(es)?$/i)) rl.pause();
  });
});

Event: 'SIGTSTP'#

function () {}

This does not work on Windows.

Emitted whenever the input stream receives a ^Z, respectively known as SIGTSTP. If there is no SIGTSTP event listener present when the input stream receives a SIGTSTP, the program will be sent to the background.

When the program is resumed with fg, the 'pause' and SIGCONT events will be emitted. You can use either to resume the stream.

The 'pause' and SIGCONT events will not be triggered if the stream was paused before the program was sent to the background.

Example of listening for SIGTSTP:

rl.on('SIGTSTP', () => {
  // This will override SIGTSTP and prevent the program from going to the
  // background.
  console.log('Caught SIGTSTP.');
});

Example: Tiny CLI#

Here's an example of how to use all these together to craft a tiny command line interface:

const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

rl.setPrompt('OHAI> ');
rl.prompt();

rl.on('line', (line) => {
  switch(line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log('Say what? I might have heard `' + line.trim() + '`');
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  process.exit(0);
});

Example: Read File Stream Line-by-Line#

A common case for readline's input option is to pass a filesystem readable stream to it. This is how one could craft line-by-line parsing of a file:

const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('sample.txt')
});

rl.on('line', function (line) {
  console.log('Line from file:', line);
});

readline.clearLine(stream, dir)#

Clears current line of given TTY stream in a specified direction. dir should have one of following values:

  • -1 - to the left from cursor
  • 1 - to the right from cursor
  • 0 - the entire line

readline.clearScreenDown(stream)#

Clears the screen from the current position of the cursor down.

readline.createInterface(options)#

Creates a readline Interface instance. Accepts an options Object that takes the following values:

  • input - the readable stream to listen to (Required).

  • output - the writable stream to write readline data to (Optional).

  • completer - an optional function that is used for Tab autocompletion. See below for an example of using this.

  • terminal - pass true if the input and output streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking isTTY on the output stream upon instantiation.

  • historySize - maximum number of history lines retained. Defaults to 30.

The completer function is given the current line entered by the user, and is supposed to return an Array with 2 entries:

  1. An Array with matching entries for the completion.

  2. The substring that was used for the matching.

Which ends up looking something like: [[substr1, substr2, ...], originalsubstring].

Example:

function completer(line) {
  var completions = '.help .error .exit .quit .q'.split(' ')
  var hits = completions.filter((c) => { return c.indexOf(line) == 0 })
  // show all completions if none found
  return [hits.length ? hits : completions, line]
}

Also completer can be run in async mode if it accepts two arguments:

function completer(linePartial, callback) {
  callback(null, [['123'], linePartial]);
}

createInterface is commonly used with process.stdin and process.stdout in order to accept user input:

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

Once you have a readline instance, you most commonly listen for the 'line' event.

If terminal is true for this instance then the output stream will get the best compatibility if it defines an output.columns property, and fires a 'resize' event on the output if/when the columns ever change (process.stdout does this automatically when it is a TTY).

readline.cursorTo(stream, x, y)#

Move cursor to the specified position in a given TTY stream.

readline.moveCursor(stream, dx, dy)#

Move cursor relative to it's current position in a given TTY stream.

node-v4.2.6/doc/api/readline.json000644 000766 000024 00000044075 12650222331 016750 0ustar00iojsstaff000000 000000 { "source": "doc/api/readline.markdown", "modules": [ { "textRaw": "Readline", "name": "readline", "stability": 2, "stabilityText": "Stable", "desc": "

To use this module, do require('readline'). Readline allows reading of a\nstream (such as [process.stdin][]) on a line-by-line basis.\n\n

\n

Note that once you've invoked this module, your Node.js program will not\nterminate until you've closed the interface. Here's how to allow your\nprogram to gracefully exit:\n\n

\n
const readline = require('readline');\n\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});\n\nrl.question('What do you think of Node.js? ', (answer) => {\n  // TODO: Log the answer in a database\n  console.log('Thank you for your valuable feedback:', answer);\n\n  rl.close();\n});
\n", "classes": [ { "textRaw": "Class: Interface", "type": "class", "name": "Interface", "desc": "

The class that represents a readline interface with an input and output\nstream.\n\n

\n", "methods": [ { "textRaw": "rl.close()", "type": "method", "name": "close", "desc": "

Closes the Interface instance, relinquishing control on the input and\noutput streams. The 'close' event will also be emitted.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.pause()", "type": "method", "name": "pause", "desc": "

Pauses the readline input stream, allowing it to be resumed later if needed.\n\n

\n

Note that this doesn't immediately pause the stream of events. Several events may\nbe emitted after calling pause, including line.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.prompt([preserveCursor])", "type": "method", "name": "prompt", "desc": "

Readies readline for input from the user, putting the current setPrompt\noptions on a new line, giving the user a new spot to write. Set preserveCursor\nto true to prevent the cursor placement being reset to 0.\n\n

\n

This will also resume the input stream used with createInterface if it has\nbeen paused.\n\n

\n

If output is set to null or undefined when calling createInterface, the\nprompt is not written.\n\n

\n", "signatures": [ { "params": [ { "name": "preserveCursor", "optional": true } ] } ] }, { "textRaw": "rl.question(query, callback)", "type": "method", "name": "question", "desc": "

Prepends the prompt with query and invokes callback with the user's\nresponse. Displays the query to the user, and then invokes callback\nwith the user's response after it has been typed.\n\n

\n

This will also resume the input stream used with createInterface if\nit has been paused.\n\n

\n

If output is set to null or undefined when calling createInterface,\nnothing is displayed.\n\n

\n

Example usage:\n\n

\n
interface.question('What is your favorite food?', (answer) => {\n  console.log(`Oh, so your favorite food is ${answer}`);\n});
\n", "signatures": [ { "params": [ { "name": "query" }, { "name": "callback" } ] } ] }, { "textRaw": "rl.resume()", "type": "method", "name": "resume", "desc": "

Resumes the readline input stream.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "rl.setPrompt(prompt)", "type": "method", "name": "setPrompt", "desc": "

Sets the prompt, for example when you run node on the command line, you see\n> , which is Node.js's prompt.\n\n

\n", "signatures": [ { "params": [ { "name": "prompt" } ] } ] }, { "textRaw": "rl.write(data[, key])", "type": "method", "name": "write", "desc": "

Writes data to output stream, unless output is set to null or\nundefined when calling createInterface. key is an object literal to\nrepresent a key sequence; available if the terminal is a TTY.\n\n

\n

This will also resume the input stream if it has been paused.\n\n

\n

Example:\n\n

\n
rl.write('Delete me!');\n// Simulate ctrl+u to delete the line written previously\nrl.write(null, {ctrl: true, name: 'u'});
\n", "signatures": [ { "params": [ { "name": "data" }, { "name": "key", "optional": true } ] } ] } ] } ], "modules": [ { "textRaw": "Events", "name": "events", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

function () {}\n\n

\n

Emitted when close() is called.\n\n

\n

Also emitted when the input stream receives its 'end' event. The Interface\ninstance should be considered "finished" once this is emitted. For example, when\nthe input stream receives ^D, respectively known as EOT.\n\n

\n

This event is also called if there is no SIGINT event listener present when\nthe input stream receives a ^C, respectively known as SIGINT.\n\n

\n", "params": [] }, { "textRaw": "Event: 'line'", "type": "event", "name": "line", "desc": "

function (line) {}\n\n

\n

Emitted whenever the input stream receives a \\n, usually received when the\nuser hits enter, or return. This is a good hook to listen for user input.\n\n

\n

Example of listening for 'line':\n\n

\n
rl.on('line', (cmd) => {\n  console.log(`You just typed: ${cmd}`);\n});
\n", "params": [] }, { "textRaw": "Event: 'pause'", "type": "event", "name": "pause", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream is paused.\n\n

\n

Also emitted whenever the input stream is not paused and receives the\nSIGCONT event. (See events SIGTSTP and SIGCONT)\n\n

\n

Example of listening for 'pause':\n\n

\n
rl.on('pause', () => {\n  console.log('Readline paused.');\n});
\n", "params": [] }, { "textRaw": "Event: 'resume'", "type": "event", "name": "resume", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream is resumed.\n\n

\n

Example of listening for 'resume':\n\n

\n
rl.on('resume', () => {\n  console.log('Readline resumed.');\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGCONT'", "type": "event", "name": "SIGCONT", "desc": "

function () {}\n\n

\n

This does not work on Windows.\n\n

\n

Emitted whenever the input stream is sent to the background with ^Z,\nrespectively known as SIGTSTP, and then continued with fg(1). This event\nonly emits if the stream was not paused before sending the program to the\nbackground.\n\n

\n

Example of listening for SIGCONT:\n\n

\n
rl.on('SIGCONT', () => {\n  // `prompt` will automatically resume the stream\n  rl.prompt();\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGINT'", "type": "event", "name": "SIGINT", "desc": "

function () {}\n\n

\n

Emitted whenever the input stream receives a ^C, respectively known as\nSIGINT. If there is no SIGINT event listener present when the input\nstream receives a SIGINT, pause will be triggered.\n\n

\n

Example of listening for SIGINT:\n\n

\n
rl.on('SIGINT', () => {\n  rl.question('Are you sure you want to exit?', (answer) => {\n    if (answer.match(/^y(es)?$/i)) rl.pause();\n  });\n});
\n", "params": [] }, { "textRaw": "Event: 'SIGTSTP'", "type": "event", "name": "SIGTSTP", "desc": "

function () {}\n\n

\n

This does not work on Windows.\n\n

\n

Emitted whenever the input stream receives a ^Z, respectively known as\nSIGTSTP. If there is no SIGTSTP event listener present when the input\nstream receives a SIGTSTP, the program will be sent to the background.\n\n

\n

When the program is resumed with fg, the 'pause' and SIGCONT events will be\nemitted. You can use either to resume the stream.\n\n

\n

The 'pause' and SIGCONT events will not be triggered if the stream was paused\nbefore the program was sent to the background.\n\n

\n

Example of listening for SIGTSTP:\n\n

\n
rl.on('SIGTSTP', () => {\n  // This will override SIGTSTP and prevent the program from going to the\n  // background.\n  console.log('Caught SIGTSTP.');\n});
\n

Example: Tiny CLI

\n

Here's an example of how to use all these together to craft a tiny command\nline interface:\n\n

\n
const readline = require('readline');\nconst rl = readline.createInterface(process.stdin, process.stdout);\n\nrl.setPrompt('OHAI> ');\nrl.prompt();\n\nrl.on('line', (line) => {\n  switch(line.trim()) {\n    case 'hello':\n      console.log('world!');\n      break;\n    default:\n      console.log('Say what? I might have heard `' + line.trim() + '`');\n      break;\n  }\n  rl.prompt();\n}).on('close', () => {\n  console.log('Have a great day!');\n  process.exit(0);\n});
\n

Example: Read File Stream Line-by-Line

\n

A common case for readline's input option is to pass a filesystem readable\nstream to it. This is how one could craft line-by-line parsing of a file:\n\n

\n
const readline = require('readline');\nconst fs = require('fs');\n\nconst rl = readline.createInterface({\n  input: fs.createReadStream('sample.txt')\n});\n\nrl.on('line', function (line) {\n  console.log('Line from file:', line);\n});
\n", "params": [] } ], "type": "module", "displayName": "Events" } ], "methods": [ { "textRaw": "readline.clearLine(stream, dir)", "type": "method", "name": "clearLine", "desc": "

Clears current line of given TTY stream in a specified direction.\ndir should have one of following values:\n\n

\n
    \n
  • -1 - to the left from cursor
  • \n
  • 1 - to the right from cursor
  • \n
  • 0 - the entire line
  • \n
\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "dir" } ] } ] }, { "textRaw": "readline.clearScreenDown(stream)", "type": "method", "name": "clearScreenDown", "desc": "

Clears the screen from the current position of the cursor down.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" } ] } ] }, { "textRaw": "readline.createInterface(options)", "type": "method", "name": "createInterface", "desc": "

Creates a readline Interface instance. Accepts an options Object that takes\nthe following values:\n\n

\n
    \n
  • input - the readable stream to listen to (Required).

    \n
  • \n
  • output - the writable stream to write readline data to (Optional).

    \n
  • \n
  • completer - an optional function that is used for Tab autocompletion. See\nbelow for an example of using this.

    \n
  • \n
  • terminal - pass true if the input and output streams should be\ntreated like a TTY, and have ANSI/VT100 escape codes written to it.\nDefaults to checking isTTY on the output stream upon instantiation.

    \n
  • \n
  • historySize - maximum number of history lines retained. Defaults to 30.

    \n
  • \n
\n

The completer function is given the current line entered by the user, and\nis supposed to return an Array with 2 entries:\n\n

\n
    \n
  1. An Array with matching entries for the completion.

    \n
  2. \n
  3. The substring that was used for the matching.

    \n
  4. \n
\n

Which ends up looking something like:\n[[substr1, substr2, ...], originalsubstring].\n\n

\n

Example:\n\n

\n
function completer(line) {\n  var completions = '.help .error .exit .quit .q'.split(' ')\n  var hits = completions.filter((c) => { return c.indexOf(line) == 0 })\n  // show all completions if none found\n  return [hits.length ? hits : completions, line]\n}
\n

Also completer can be run in async mode if it accepts two arguments:\n\n

\n
function completer(linePartial, callback) {\n  callback(null, [['123'], linePartial]);\n}
\n

createInterface is commonly used with [process.stdin][] and\n[process.stdout][] in order to accept user input:\n\n

\n
const readline = require('readline');\nconst rl = readline.createInterface({\n  input: process.stdin,\n  output: process.stdout\n});
\n

Once you have a readline instance, you most commonly listen for the\n'line' event.\n\n

\n

If terminal is true for this instance then the output stream will get\nthe best compatibility if it defines an output.columns property, and fires\na 'resize' event on the output if/when the columns ever change\n([process.stdout][] does this automatically when it is a TTY).\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] }, { "textRaw": "readline.cursorTo(stream, x, y)", "type": "method", "name": "cursorTo", "desc": "

Move cursor to the specified position in a given TTY stream.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "x" }, { "name": "y" } ] } ] }, { "textRaw": "readline.moveCursor(stream, dx, dy)", "type": "method", "name": "moveCursor", "desc": "

Move cursor relative to it's current position in a given TTY stream.\n\n

\n", "signatures": [ { "params": [ { "name": "stream" }, { "name": "dx" }, { "name": "dy" } ] } ] } ], "type": "module", "displayName": "Readline" } ] } node-v4.2.6/doc/api/readline.markdown000644 000766 000024 00000022734 12650222326 017623 0ustar00iojsstaff000000 000000 # Readline Stability: 2 - Stable To use this module, do `require('readline')`. Readline allows reading of a stream (such as [`process.stdin`][]) on a line-by-line basis. Note that once you've invoked this module, your Node.js program will not terminate until you've closed the interface. Here's how to allow your program to gracefully exit: const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('What do you think of Node.js? ', (answer) => { // TODO: Log the answer in a database console.log('Thank you for your valuable feedback:', answer); rl.close(); }); ## Class: Interface The class that represents a readline interface with an input and output stream. ### rl.close() Closes the `Interface` instance, relinquishing control on the `input` and `output` streams. The `'close'` event will also be emitted. ### rl.pause() Pauses the readline `input` stream, allowing it to be resumed later if needed. Note that this doesn't immediately pause the stream of events. Several events may be emitted after calling `pause`, including `line`. ### rl.prompt([preserveCursor]) Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write. Set `preserveCursor` to `true` to prevent the cursor placement being reset to `0`. This will also resume the `input` stream used with `createInterface` if it has been paused. If `output` is set to `null` or `undefined` when calling `createInterface`, the prompt is not written. ### rl.question(query, callback) Prepends the prompt with `query` and invokes `callback` with the user's response. Displays the query to the user, and then invokes `callback` with the user's response after it has been typed. This will also resume the `input` stream used with `createInterface` if it has been paused. If `output` is set to `null` or `undefined` when calling `createInterface`, nothing is displayed. Example usage: interface.question('What is your favorite food?', (answer) => { console.log(`Oh, so your favorite food is ${answer}`); }); ### rl.resume() Resumes the readline `input` stream. ### rl.setPrompt(prompt) Sets the prompt, for example when you run `node` on the command line, you see `> `, which is Node.js's prompt. ### rl.write(data[, key]) Writes `data` to `output` stream, unless `output` is set to `null` or `undefined` when calling `createInterface`. `key` is an object literal to represent a key sequence; available if the terminal is a TTY. This will also resume the `input` stream if it has been paused. Example: rl.write('Delete me!'); // Simulate ctrl+u to delete the line written previously rl.write(null, {ctrl: true, name: 'u'}); ## Events ### Event: 'close' `function () {}` Emitted when `close()` is called. Also emitted when the `input` stream receives its `'end'` event. The `Interface` instance should be considered "finished" once this is emitted. For example, when the `input` stream receives `^D`, respectively known as `EOT`. This event is also called if there is no `SIGINT` event listener present when the `input` stream receives a `^C`, respectively known as `SIGINT`. ### Event: 'line' `function (line) {}` Emitted whenever the `input` stream receives a `\n`, usually received when the user hits enter, or return. This is a good hook to listen for user input. Example of listening for `'line'`: rl.on('line', (cmd) => { console.log(`You just typed: ${cmd}`); }); ### Event: 'pause' `function () {}` Emitted whenever the `input` stream is paused. Also emitted whenever the `input` stream is not paused and receives the `SIGCONT` event. (See events `SIGTSTP` and `SIGCONT`) Example of listening for `'pause'`: rl.on('pause', () => { console.log('Readline paused.'); }); ### Event: 'resume' `function () {}` Emitted whenever the `input` stream is resumed. Example of listening for `'resume'`: rl.on('resume', () => { console.log('Readline resumed.'); }); ### Event: 'SIGCONT' `function () {}` **This does not work on Windows.** Emitted whenever the `input` stream is sent to the background with `^Z`, respectively known as `SIGTSTP`, and then continued with `fg(1)`. This event only emits if the stream was not paused before sending the program to the background. Example of listening for `SIGCONT`: rl.on('SIGCONT', () => { // `prompt` will automatically resume the stream rl.prompt(); }); ### Event: 'SIGINT' `function () {}` Emitted whenever the `input` stream receives a `^C`, respectively known as `SIGINT`. If there is no `SIGINT` event listener present when the `input` stream receives a `SIGINT`, `pause` will be triggered. Example of listening for `SIGINT`: rl.on('SIGINT', () => { rl.question('Are you sure you want to exit?', (answer) => { if (answer.match(/^y(es)?$/i)) rl.pause(); }); }); ### Event: 'SIGTSTP' `function () {}` **This does not work on Windows.** Emitted whenever the `input` stream receives a `^Z`, respectively known as `SIGTSTP`. If there is no `SIGTSTP` event listener present when the `input` stream receives a `SIGTSTP`, the program will be sent to the background. When the program is resumed with `fg`, the `'pause'` and `SIGCONT` events will be emitted. You can use either to resume the stream. The `'pause'` and `SIGCONT` events will not be triggered if the stream was paused before the program was sent to the background. Example of listening for `SIGTSTP`: rl.on('SIGTSTP', () => { // This will override SIGTSTP and prevent the program from going to the // background. console.log('Caught SIGTSTP.'); }); ## Example: Tiny CLI Here's an example of how to use all these together to craft a tiny command line interface: const readline = require('readline'); const rl = readline.createInterface(process.stdin, process.stdout); rl.setPrompt('OHAI> '); rl.prompt(); rl.on('line', (line) => { switch(line.trim()) { case 'hello': console.log('world!'); break; default: console.log('Say what? I might have heard `' + line.trim() + '`'); break; } rl.prompt(); }).on('close', () => { console.log('Have a great day!'); process.exit(0); }); ## Example: Read File Stream Line-by-Line A common case for `readline`'s `input` option is to pass a filesystem readable stream to it. This is how one could craft line-by-line parsing of a file: const readline = require('readline'); const fs = require('fs'); const rl = readline.createInterface({ input: fs.createReadStream('sample.txt') }); rl.on('line', function (line) { console.log('Line from file:', line); }); ## readline.clearLine(stream, dir) Clears current line of given TTY stream in a specified direction. `dir` should have one of following values: * `-1` - to the left from cursor * `1` - to the right from cursor * `0` - the entire line ## readline.clearScreenDown(stream) Clears the screen from the current position of the cursor down. ## readline.createInterface(options) Creates a readline `Interface` instance. Accepts an `options` Object that takes the following values: - `input` - the readable stream to listen to (Required). - `output` - the writable stream to write readline data to (Optional). - `completer` - an optional function that is used for Tab autocompletion. See below for an example of using this. - `terminal` - pass `true` if the `input` and `output` streams should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking `isTTY` on the `output` stream upon instantiation. - `historySize` - maximum number of history lines retained. Defaults to `30`. The `completer` function is given the current line entered by the user, and is supposed to return an Array with 2 entries: 1. An Array with matching entries for the completion. 2. The substring that was used for the matching. Which ends up looking something like: `[[substr1, substr2, ...], originalsubstring]`. Example: function completer(line) { var completions = '.help .error .exit .quit .q'.split(' ') var hits = completions.filter((c) => { return c.indexOf(line) == 0 }) // show all completions if none found return [hits.length ? hits : completions, line] } Also `completer` can be run in async mode if it accepts two arguments: function completer(linePartial, callback) { callback(null, [['123'], linePartial]); } `createInterface` is commonly used with [`process.stdin`][] and [`process.stdout`][] in order to accept user input: const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); Once you have a readline instance, you most commonly listen for the `'line'` event. If `terminal` is `true` for this instance then the `output` stream will get the best compatibility if it defines an `output.columns` property, and fires a `'resize'` event on the `output` if/when the columns ever change ([`process.stdout`][] does this automatically when it is a TTY). ## readline.cursorTo(stream, x, y) Move cursor to the specified position in a given TTY stream. ## readline.moveCursor(stream, dx, dy) Move cursor relative to it's current position in a given TTY stream. [`process.stdin`]: process.html#process_process_stdin [`process.stdout`]: process.html#process_process_stdout node-v4.2.6/doc/api/repl.html000644 000766 000024 00000047011 12650222331 016113 0ustar00iojsstaff000000 000000 REPL Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


REPL#

Stability: 2 - Stable

A Read-Eval-Print-Loop (REPL) is available both as a standalone program and easily includable in other programs. The REPL provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out.

By executing node without any arguments from the command-line you will be dropped into the REPL. It has simplistic emacs line-editing.

mjr:~$ node
Type '.help' for options.
> a = [ 1, 2, 3];
[ 1, 2, 3 ]
> a.forEach(function (v) {
...   console.log(v);
...   });
1
2
3

For advanced line-editors, start Node.js with the environmental variable NODE_NO_READLINE=1. This will start the main and debugger REPL in canonical terminal settings which will allow you to use with rlwrap.

For example, you could add this to your bashrc file:

alias node="env NODE_NO_READLINE=1 rlwrap node"

Environment Variable Options#

The built-in repl (invoked by running node or node -i) may be controlled via the following environment variables:

  • NODE_REPL_HISTORY - When a valid path is given, persistent REPL history will be saved to the specified file rather than .node_repl_history in the user's home directory. Setting this value to "" will disable persistent REPL history.
  • NODE_REPL_HISTORY_SIZE - defaults to 1000. Controls how many lines of history will be persisted if history is available. Must be a positive number.
  • NODE_REPL_MODE - may be any of sloppy, strict, or magic. Defaults to magic, which will automatically run "strict mode only" statements in strict mode.

Persistent History#

By default, the REPL will persist history between node REPL sessions by saving to a .node_repl_history file in the user's home directory. This can be disabled by setting the environment variable NODE_REPL_HISTORY="".

NODE_REPL_HISTORY_FILE#

Stability: 0 - Deprecated: Use NODE_REPL_HISTORY instead.

Previously in Node.js/io.js v2.x, REPL history was controlled by using a NODE_REPL_HISTORY_FILE environment variable, and the history was saved in JSON format. This variable has now been deprecated, and your REPL history will automatically be converted to using plain text. The new file will be saved to either your home directory, or a directory defined by the NODE_REPL_HISTORY variable, as documented below.

REPL Features#

Inside the REPL, Control+D will exit. Multi-line expressions can be input. Tab completion is supported for both global and local variables.

Core modules will be loaded on-demand into the environment. For example, accessing fs will require() the fs module as global.fs.

The special variable _ (underscore) contains the result of the last expression.

> [ 'a', 'b', 'c' ]
[ 'a', 'b', 'c' ]
> _.length
3
> _ += 1
4

The REPL provides access to any variables in the global scope. You can expose a variable to the REPL explicitly by assigning it to the context object associated with each REPLServer. For example:

// repl_test.js
const repl = require('repl');
var msg = 'message';

repl.start('> ').context.m = msg;

Things in the context object appear as local within the REPL:

mjr:~$ node repl_test.js
> m
'message'

There are a few special REPL commands:

  • .break - While inputting a multi-line expression, sometimes you get lost or just don't care about completing it. .break will start over.
  • .clear - Resets the context object to an empty object and clears any multi-line expression.
  • .exit - Close the I/O stream, which will cause the REPL to exit.
  • .help - Show this list of special commands.
  • .save - Save the current REPL session to a file

    .save ./file/to/save.js

  • .load - Load a file into the current REPL session.

    .load ./file/to/load.js

The following key combinations in the REPL have these special effects:

  • <ctrl>C - Similar to the .break keyword. Terminates the current command. Press twice on a blank line to forcibly exit.
  • <ctrl>D - Similar to the .exit keyword.
  • <tab> - Show both global and local(scope) variables

Customizing Object displays in the REPL#

The REPL module internally uses util.inspect(), when printing values. However, util.inspect delegates the call to the object's inspect() function, if it has one. You can read more about this delegation here.

For example, if you have defined an inspect() function on an object, like this:

> var obj = { foo: 'this will not show up in the inspect() output' };
undefined
> obj.inspect = function() {
...   return { bar: 'baz' };
... };
[Function]

and try to print obj in REPL, it will invoke the custom inspect() function:

> obj
{ bar: 'baz' }

Class: REPLServer#

This inherits from Readline Interface with the following events:

Event: 'exit'#

function () {}

Emitted when the user exits the REPL in any of the defined ways. Namely, typing .exit at the repl, pressing Ctrl+C twice to signal SIGINT, or pressing Ctrl+D to signal 'end' on the input stream.

Example of listening for exit:

replServer.on('exit', () => {
  console.log('Got "exit" event from repl!');
  process.exit();
});

Event: 'reset'#

function (context) {}

Emitted when the REPL's context is reset. This happens when you type .clear. If you start the repl with { useGlobal: true } then this event will never be emitted.

Example of listening for reset:

// Extend the initial repl context.
var replServer = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
replServer.on('reset', (context) => {
  console.log('repl has a new context');
  someExtension.extend(context);
});

replServer.defineCommand(keyword, cmd)#

  • keyword String
  • cmd Object|Function

Makes a command available in the REPL. The command is invoked by typing a . followed by the keyword. The cmd is an object with the following values:

  • help - help text to be displayed when .help is entered (Optional).
  • action - a function to execute, potentially taking in a string argument, when the command is invoked, bound to the REPLServer instance (Required).

If a function is provided instead of an object for cmd, it is treated as the action.

Example of defining a command:

// repl_test.js
const repl = require('repl');

var replServer = repl.start();
replServer.defineCommand('sayhello', {
  help: 'Say hello',
  action: function(name) {
    this.write(`Hello, ${name}!\n');
    this.displayPrompt();
  }
});

Example of invoking that command from the REPL:

> .sayhello Node.js User
Hello, Node.js User!

replServer.displayPrompt([preserveCursor])#

  • preserveCursor Boolean

Like readline.prompt except also adding indents with ellipses when inside blocks. The preserveCursor argument is passed to readline.prompt. This is used primarily with defineCommand. It's also used internally to render each prompt line.

repl.start(options)#

Returns and starts a REPLServer instance, that inherits from Readline Interface. Accepts an "options" Object that takes the following values:

  • prompt - the prompt and stream for all I/O. Defaults to > .

  • input - the readable stream to listen to. Defaults to process.stdin.

  • output - the writable stream to write readline data to. Defaults to process.stdout.

  • terminal - pass true if the stream should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking isTTY on the output stream upon instantiation.

  • eval - function that will be used to eval each given line. Defaults to an async wrapper for eval(). See below for an example of a custom eval.

  • useColors - a boolean which specifies whether or not the writer function should output colors. If a different writer function is set then this does nothing. Defaults to the repl's terminal value.

  • useGlobal - if set to true, then the repl will use the global object, instead of running scripts in a separate context. Defaults to false.

  • ignoreUndefined - if set to true, then the repl will not output the return value of command if it's undefined. Defaults to false.

  • writer - the function to invoke for each command that gets evaluated which returns the formatting (including coloring) to display. Defaults to util.inspect.

  • replMode - controls whether the repl runs all commands in strict mode, default mode, or a hybrid mode ("magic" mode.) Acceptable values are:

    • repl.REPL_MODE_SLOPPY - run commands in sloppy mode.
    • repl.REPL_MODE_STRICT - run commands in strict mode. This is equivalent to prefacing every repl statement with 'use strict'.
    • repl.REPL_MODE_MAGIC - attempt to run commands in default mode. If they fail to parse, re-try in strict mode.

You can use your own eval function if it has following signature:

function eval(cmd, context, filename, callback) {
  callback(null, result);
}

On tab completion - eval will be called with .scope as an input string. It is expected to return an array of scope names to be used for the auto-completion.

Multiple REPLs may be started against the same running instance of Node.js. Each will share the same global object but will have unique I/O.

Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:

const net = require('net');
const repl = require('repl');
var connections = 0;

repl.start({
  prompt: 'Node.js via stdin> ',
  input: process.stdin,
  output: process.stdout
});

net.createServer((socket) => {
  connections += 1;
  repl.start({
    prompt: 'Node.js via Unix socket> ',
    input: socket,
    output: socket
  }).on('exit', () => {
    socket.end();
  })
}).listen('/tmp/node-repl-sock');

net.createServer((socket) => {
  connections += 1;
  repl.start({
    prompt: 'Node.js via TCP socket> ',
    input: socket,
    output: socket
  }).on('exit', () => {
    socket.end();
  });
}).listen(5001);

Running this program from the command line will start a REPL on stdin. Other REPL clients may connect through the Unix socket or TCP socket. telnet is useful for connecting to TCP sockets, and socat can be used to connect to both Unix and TCP sockets.

By starting a REPL from a Unix socket-based server instead of stdin, you can connect to a long-running Node.js process without restarting it.

For an example of running a "full-featured" (terminal) REPL over a net.Server and net.Socket instance, see: https://gist.github.com/2209310

For an example of running a REPL instance over curl(1), see: https://gist.github.com/2053342

node-v4.2.6/doc/api/repl.json000644 000766 000024 00000042041 12650222331 016116 0ustar00iojsstaff000000 000000 { "source": "doc/api/repl.markdown", "modules": [ { "textRaw": "REPL", "name": "repl", "stability": 2, "stabilityText": "Stable", "desc": "

A Read-Eval-Print-Loop (REPL) is available both as a standalone program and\neasily includable in other programs. The REPL provides a way to interactively\nrun JavaScript and see the results. It can be used for debugging, testing, or\njust trying things out.\n\n

\n

By executing node without any arguments from the command-line you will be\ndropped into the REPL. It has simplistic emacs line-editing.\n\n

\n
mjr:~$ node\nType '.help' for options.\n> a = [ 1, 2, 3];\n[ 1, 2, 3 ]\n> a.forEach(function (v) {\n...   console.log(v);\n...   });\n1\n2\n3
\n

For advanced line-editors, start Node.js with the environmental variable\nNODE_NO_READLINE=1. This will start the main and debugger REPL in canonical\nterminal settings which will allow you to use with rlwrap.\n\n

\n

For example, you could add this to your bashrc file:\n\n

\n
alias node="env NODE_NO_READLINE=1 rlwrap node"
\n", "modules": [ { "textRaw": "Environment Variable Options", "name": "environment_variable_options", "desc": "

The built-in repl (invoked by running node or node -i) may be controlled\nvia the following environment variables:\n\n

\n
    \n
  • NODE_REPL_HISTORY - When a valid path is given, persistent REPL history\nwill be saved to the specified file rather than .node_repl_history in the\nuser's home directory. Setting this value to "" will disable persistent\nREPL history.
  • \n
  • NODE_REPL_HISTORY_SIZE - defaults to 1000. Controls how many lines of\nhistory will be persisted if history is available. Must be a positive number.
  • \n
  • NODE_REPL_MODE - may be any of sloppy, strict, or magic. Defaults\nto magic, which will automatically run "strict mode only" statements in\nstrict mode.
  • \n
\n", "type": "module", "displayName": "Environment Variable Options" }, { "textRaw": "Persistent History", "name": "persistent_history", "desc": "

By default, the REPL will persist history between node REPL sessions by saving\nto a .node_repl_history file in the user's home directory. This can be\ndisabled by setting the environment variable NODE_REPL_HISTORY="".\n\n

\n", "modules": [ { "textRaw": "NODE_REPL_HISTORY_FILE", "name": "node_repl_history_file", "stability": 0, "stabilityText": "Deprecated: Use `NODE_REPL_HISTORY` instead.", "desc": "

Previously in Node.js/io.js v2.x, REPL history was controlled by using a\nNODE_REPL_HISTORY_FILE environment variable, and the history was saved in JSON\nformat. This variable has now been deprecated, and your REPL history will\nautomatically be converted to using plain text. The new file will be saved to\neither your home directory, or a directory defined by the NODE_REPL_HISTORY\nvariable, as documented below.\n\n

\n", "type": "module", "displayName": "NODE_REPL_HISTORY_FILE" } ], "type": "module", "displayName": "Persistent History" } ], "miscs": [ { "textRaw": "REPL Features", "name": "REPL Features", "type": "misc", "desc": "

Inside the REPL, Control+D will exit. Multi-line expressions can be input.\nTab completion is supported for both global and local variables.\n\n

\n

Core modules will be loaded on-demand into the environment. For example,\naccessing fs will require() the fs module as global.fs.\n\n

\n

The special variable _ (underscore) contains the result of the last expression.\n\n

\n
> [ 'a', 'b', 'c' ]\n[ 'a', 'b', 'c' ]\n> _.length\n3\n> _ += 1\n4
\n

The REPL provides access to any variables in the global scope. You can expose\na variable to the REPL explicitly by assigning it to the context object\nassociated with each REPLServer. For example:\n\n

\n
// repl_test.js\nconst repl = require('repl');\nvar msg = 'message';\n\nrepl.start('> ').context.m = msg;
\n

Things in the context object appear as local within the REPL:\n\n

\n
mjr:~$ node repl_test.js\n> m\n'message'
\n

There are a few special REPL commands:\n\n

\n
    \n
  • .break - While inputting a multi-line expression, sometimes you get lost\nor just don't care about completing it. .break will start over.
  • \n
  • .clear - Resets the context object to an empty object and clears any\nmulti-line expression.
  • \n
  • .exit - Close the I/O stream, which will cause the REPL to exit.
  • \n
  • .help - Show this list of special commands.
  • \n
  • .save - Save the current REPL session to a file
    \n

    .save ./file/to/save.js

    \n
    \n
  • \n
  • .load - Load a file into the current REPL session.
    \n

    .load ./file/to/load.js

    \n
    \n
  • \n
\n

The following key combinations in the REPL have these special effects:\n\n

\n
    \n
  • <ctrl>C - Similar to the .break keyword. Terminates the current\ncommand. Press twice on a blank line to forcibly exit.
  • \n
  • <ctrl>D - Similar to the .exit keyword.
  • \n
  • <tab> - Show both global and local(scope) variables
  • \n
\n", "miscs": [ { "textRaw": "Customizing Object displays in the REPL", "name": "customizing_object_displays_in_the_repl", "desc": "

The REPL module internally uses\n[util.inspect()][], when printing values. However, util.inspect delegates the\n call to the object's inspect() function, if it has one. You can read more\n about this delegation [here][].\n\n

\n

For example, if you have defined an inspect() function on an object, like this:\n\n

\n
> var obj = { foo: 'this will not show up in the inspect() output' };\nundefined\n> obj.inspect = function() {\n...   return { bar: 'baz' };\n... };\n[Function]
\n

and try to print obj in REPL, it will invoke the custom inspect() function:\n\n

\n
> obj\n{ bar: 'baz' }
\n", "type": "misc", "displayName": "Customizing Object displays in the REPL" } ] } ], "classes": [ { "textRaw": "Class: REPLServer", "type": "class", "name": "REPLServer", "desc": "

This inherits from [Readline Interface][] with the following events:\n\n

\n", "events": [ { "textRaw": "Event: 'exit'", "type": "event", "name": "exit", "desc": "

function () {}\n\n

\n

Emitted when the user exits the REPL in any of the defined ways. Namely, typing\n.exit at the repl, pressing Ctrl+C twice to signal SIGINT, or pressing Ctrl+D\nto signal 'end' on the input stream.\n\n

\n

Example of listening for exit:\n\n

\n
replServer.on('exit', () => {\n  console.log('Got "exit" event from repl!');\n  process.exit();\n});
\n", "params": [] }, { "textRaw": "Event: 'reset'", "type": "event", "name": "reset", "desc": "

function (context) {}\n\n

\n

Emitted when the REPL's context is reset. This happens when you type .clear.\nIf you start the repl with { useGlobal: true } then this event will never\nbe emitted.\n\n

\n

Example of listening for reset:\n\n

\n
// Extend the initial repl context.\nvar replServer = repl.start({ options ... });\nsomeExtension.extend(r.context);\n\n// When a new context is created extend it as well.\nreplServer.on('reset', (context) => {\n  console.log('repl has a new context');\n  someExtension.extend(context);\n});
\n", "params": [] } ], "methods": [ { "textRaw": "replServer.defineCommand(keyword, cmd)", "type": "method", "name": "defineCommand", "signatures": [ { "params": [ { "textRaw": "`keyword` {String} ", "name": "keyword", "type": "String" }, { "textRaw": "`cmd` {Object|Function} ", "name": "cmd", "type": "Object|Function" } ] }, { "params": [ { "name": "keyword" }, { "name": "cmd" } ] } ], "desc": "

Makes a command available in the REPL. The command is invoked by typing a .\nfollowed by the keyword. The cmd is an object with the following values:\n\n

\n
    \n
  • help - help text to be displayed when .help is entered (Optional).
  • \n
  • action - a function to execute, potentially taking in a string argument,\nwhen the command is invoked, bound to the REPLServer instance (Required).
  • \n
\n

If a function is provided instead of an object for cmd, it is treated as the\naction.\n\n

\n

Example of defining a command:\n\n

\n
// repl_test.js\nconst repl = require('repl');\n\nvar replServer = repl.start();\nreplServer.defineCommand('sayhello', {\n  help: 'Say hello',\n  action: function(name) {\n    this.write(`Hello, ${name}!\\n');\n    this.displayPrompt();\n  }\n});
\n

Example of invoking that command from the REPL:\n\n

\n
> .sayhello Node.js User\nHello, Node.js User!
\n" }, { "textRaw": "replServer.displayPrompt([preserveCursor])", "type": "method", "name": "displayPrompt", "signatures": [ { "params": [ { "textRaw": "`preserveCursor` {Boolean} ", "name": "preserveCursor", "type": "Boolean", "optional": true } ] }, { "params": [ { "name": "preserveCursor", "optional": true } ] } ], "desc": "

Like [readline.prompt][] except also adding indents with ellipses when inside\nblocks. The preserveCursor argument is passed to [readline.prompt][]. This is\nused primarily with defineCommand. It's also used internally to render each\nprompt line.\n\n

\n" } ] } ], "methods": [ { "textRaw": "repl.start(options)", "type": "method", "name": "start", "desc": "

Returns and starts a REPLServer instance, that inherits from\n[Readline Interface][]. Accepts an "options" Object that takes\nthe following values:\n\n

\n
    \n
  • prompt - the prompt and stream for all I/O. Defaults to > .

    \n
  • \n
  • input - the readable stream to listen to. Defaults to process.stdin.

    \n
  • \n
  • output - the writable stream to write readline data to. Defaults to\nprocess.stdout.

    \n
  • \n
  • terminal - pass true if the stream should be treated like a TTY, and\nhave ANSI/VT100 escape codes written to it. Defaults to checking isTTY\non the output stream upon instantiation.

    \n
  • \n
  • eval - function that will be used to eval each given line. Defaults to\nan async wrapper for eval(). See below for an example of a custom eval.

    \n
  • \n
  • useColors - a boolean which specifies whether or not the writer function\nshould output colors. If a different writer function is set then this does\nnothing. Defaults to the repl's terminal value.

    \n
  • \n
  • useGlobal - if set to true, then the repl will use the global object,\ninstead of running scripts in a separate context. Defaults to false.

    \n
  • \n
  • ignoreUndefined - if set to true, then the repl will not output the\nreturn value of command if it's undefined. Defaults to false.

    \n
  • \n
  • writer - the function to invoke for each command that gets evaluated which\nreturns the formatting (including coloring) to display. Defaults to\nutil.inspect.

    \n
  • \n
  • replMode - controls whether the repl runs all commands in strict mode,\ndefault mode, or a hybrid mode ("magic" mode.) Acceptable values are:

    \n
      \n
    • repl.REPL_MODE_SLOPPY - run commands in sloppy mode.
    • \n
    • repl.REPL_MODE_STRICT - run commands in strict mode. This is equivalent to\nprefacing every repl statement with 'use strict'.
    • \n
    • repl.REPL_MODE_MAGIC - attempt to run commands in default mode. If they\nfail to parse, re-try in strict mode.
    • \n
    \n
  • \n
\n

You can use your own eval function if it has following signature:\n\n

\n
function eval(cmd, context, filename, callback) {\n  callback(null, result);\n}
\n

On tab completion - eval will be called with .scope as an input string. It\nis expected to return an array of scope names to be used for the auto-completion.\n\n

\n

Multiple REPLs may be started against the same running instance of Node.js. Each\nwill share the same global object but will have unique I/O.\n\n

\n

Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket:\n\n

\n
const net = require('net');\nconst repl = require('repl');\nvar connections = 0;\n\nrepl.start({\n  prompt: 'Node.js via stdin> ',\n  input: process.stdin,\n  output: process.stdout\n});\n\nnet.createServer((socket) => {\n  connections += 1;\n  repl.start({\n    prompt: 'Node.js via Unix socket> ',\n    input: socket,\n    output: socket\n  }).on('exit', () => {\n    socket.end();\n  })\n}).listen('/tmp/node-repl-sock');\n\nnet.createServer((socket) => {\n  connections += 1;\n  repl.start({\n    prompt: 'Node.js via TCP socket> ',\n    input: socket,\n    output: socket\n  }).on('exit', () => {\n    socket.end();\n  });\n}).listen(5001);
\n

Running this program from the command line will start a REPL on stdin. Other\nREPL clients may connect through the Unix socket or TCP socket. telnet is useful\nfor connecting to TCP sockets, and socat can be used to connect to both Unix and\nTCP sockets.\n\n

\n

By starting a REPL from a Unix socket-based server instead of stdin, you can\nconnect to a long-running Node.js process without restarting it.\n\n

\n

For an example of running a "full-featured" (terminal) REPL over\na net.Server and net.Socket instance, see: https://gist.github.com/2209310\n\n

\n

For an example of running a REPL instance over curl(1),\nsee: https://gist.github.com/2053342\n\n

\n", "signatures": [ { "params": [ { "name": "options" } ] } ] } ], "type": "module", "displayName": "REPL" } ] } node-v4.2.6/doc/api/repl.markdown000644 000766 000024 00000026100 12650222326 016771 0ustar00iojsstaff000000 000000 # REPL Stability: 2 - Stable A Read-Eval-Print-Loop (REPL) is available both as a standalone program and easily includable in other programs. The REPL provides a way to interactively run JavaScript and see the results. It can be used for debugging, testing, or just trying things out. By executing `node` without any arguments from the command-line you will be dropped into the REPL. It has simplistic emacs line-editing. mjr:~$ node Type '.help' for options. > a = [ 1, 2, 3]; [ 1, 2, 3 ] > a.forEach(function (v) { ... console.log(v); ... }); 1 2 3 For advanced line-editors, start Node.js with the environmental variable `NODE_NO_READLINE=1`. This will start the main and debugger REPL in canonical terminal settings which will allow you to use with `rlwrap`. For example, you could add this to your bashrc file: alias node="env NODE_NO_READLINE=1 rlwrap node" ## Environment Variable Options The built-in repl (invoked by running `node` or `node -i`) may be controlled via the following environment variables: - `NODE_REPL_HISTORY` - When a valid path is given, persistent REPL history will be saved to the specified file rather than `.node_repl_history` in the user's home directory. Setting this value to `""` will disable persistent REPL history. - `NODE_REPL_HISTORY_SIZE` - defaults to `1000`. Controls how many lines of history will be persisted if history is available. Must be a positive number. - `NODE_REPL_MODE` - may be any of `sloppy`, `strict`, or `magic`. Defaults to `magic`, which will automatically run "strict mode only" statements in strict mode. ## Persistent History By default, the REPL will persist history between `node` REPL sessions by saving to a `.node_repl_history` file in the user's home directory. This can be disabled by setting the environment variable `NODE_REPL_HISTORY=""`. ### NODE_REPL_HISTORY_FILE Stability: 0 - Deprecated: Use `NODE_REPL_HISTORY` instead. Previously in Node.js/io.js v2.x, REPL history was controlled by using a `NODE_REPL_HISTORY_FILE` environment variable, and the history was saved in JSON format. This variable has now been deprecated, and your REPL history will automatically be converted to using plain text. The new file will be saved to either your home directory, or a directory defined by the `NODE_REPL_HISTORY` variable, as documented below. ## REPL Features Inside the REPL, Control+D will exit. Multi-line expressions can be input. Tab completion is supported for both global and local variables. Core modules will be loaded on-demand into the environment. For example, accessing `fs` will `require()` the `fs` module as `global.fs`. The special variable `_` (underscore) contains the result of the last expression. > [ 'a', 'b', 'c' ] [ 'a', 'b', 'c' ] > _.length 3 > _ += 1 4 The REPL provides access to any variables in the global scope. You can expose a variable to the REPL explicitly by assigning it to the `context` object associated with each `REPLServer`. For example: // repl_test.js const repl = require('repl'); var msg = 'message'; repl.start('> ').context.m = msg; Things in the `context` object appear as local within the REPL: mjr:~$ node repl_test.js > m 'message' There are a few special REPL commands: - `.break` - While inputting a multi-line expression, sometimes you get lost or just don't care about completing it. `.break` will start over. - `.clear` - Resets the `context` object to an empty object and clears any multi-line expression. - `.exit` - Close the I/O stream, which will cause the REPL to exit. - `.help` - Show this list of special commands. - `.save` - Save the current REPL session to a file >.save ./file/to/save.js - `.load` - Load a file into the current REPL session. >.load ./file/to/load.js The following key combinations in the REPL have these special effects: - `C` - Similar to the `.break` keyword. Terminates the current command. Press twice on a blank line to forcibly exit. - `D` - Similar to the `.exit` keyword. - `` - Show both global and local(scope) variables ### Customizing Object displays in the REPL The REPL module internally uses [`util.inspect()`][], when printing values. However, `util.inspect` delegates the call to the object's `inspect()` function, if it has one. You can read more about this delegation [here][]. For example, if you have defined an `inspect()` function on an object, like this: > var obj = { foo: 'this will not show up in the inspect() output' }; undefined > obj.inspect = function() { ... return { bar: 'baz' }; ... }; [Function] and try to print `obj` in REPL, it will invoke the custom `inspect()` function: > obj { bar: 'baz' } ## Class: REPLServer This inherits from [Readline Interface][] with the following events: ### Event: 'exit' `function () {}` Emitted when the user exits the REPL in any of the defined ways. Namely, typing `.exit` at the repl, pressing Ctrl+C twice to signal `SIGINT`, or pressing Ctrl+D to signal `'end'` on the `input` stream. Example of listening for `exit`: replServer.on('exit', () => { console.log('Got "exit" event from repl!'); process.exit(); }); ### Event: 'reset' `function (context) {}` Emitted when the REPL's context is reset. This happens when you type `.clear`. If you start the repl with `{ useGlobal: true }` then this event will never be emitted. Example of listening for `reset`: // Extend the initial repl context. var replServer = repl.start({ options ... }); someExtension.extend(r.context); // When a new context is created extend it as well. replServer.on('reset', (context) => { console.log('repl has a new context'); someExtension.extend(context); }); ### replServer.defineCommand(keyword, cmd) * `keyword` {String} * `cmd` {Object|Function} Makes a command available in the REPL. The command is invoked by typing a `.` followed by the keyword. The `cmd` is an object with the following values: - `help` - help text to be displayed when `.help` is entered (Optional). - `action` - a function to execute, potentially taking in a string argument, when the command is invoked, bound to the REPLServer instance (Required). If a function is provided instead of an object for `cmd`, it is treated as the `action`. Example of defining a command: // repl_test.js const repl = require('repl'); var replServer = repl.start(); replServer.defineCommand('sayhello', { help: 'Say hello', action: function(name) { this.write(`Hello, ${name}!\n'); this.displayPrompt(); } }); Example of invoking that command from the REPL: > .sayhello Node.js User Hello, Node.js User! ### replServer.displayPrompt([preserveCursor]) * `preserveCursor` {Boolean} Like [`readline.prompt`][] except also adding indents with ellipses when inside blocks. The `preserveCursor` argument is passed to [`readline.prompt`][]. This is used primarily with `defineCommand`. It's also used internally to render each prompt line. ## repl.start(options) Returns and starts a `REPLServer` instance, that inherits from [Readline Interface][]. Accepts an "options" Object that takes the following values: - `prompt` - the prompt and `stream` for all I/O. Defaults to `> `. - `input` - the readable stream to listen to. Defaults to `process.stdin`. - `output` - the writable stream to write readline data to. Defaults to `process.stdout`. - `terminal` - pass `true` if the `stream` should be treated like a TTY, and have ANSI/VT100 escape codes written to it. Defaults to checking `isTTY` on the `output` stream upon instantiation. - `eval` - function that will be used to eval each given line. Defaults to an async wrapper for `eval()`. See below for an example of a custom `eval`. - `useColors` - a boolean which specifies whether or not the `writer` function should output colors. If a different `writer` function is set then this does nothing. Defaults to the repl's `terminal` value. - `useGlobal` - if set to `true`, then the repl will use the `global` object, instead of running scripts in a separate context. Defaults to `false`. - `ignoreUndefined` - if set to `true`, then the repl will not output the return value of command if it's `undefined`. Defaults to `false`. - `writer` - the function to invoke for each command that gets evaluated which returns the formatting (including coloring) to display. Defaults to `util.inspect`. - `replMode` - controls whether the repl runs all commands in strict mode, default mode, or a hybrid mode ("magic" mode.) Acceptable values are: * `repl.REPL_MODE_SLOPPY` - run commands in sloppy mode. * `repl.REPL_MODE_STRICT` - run commands in strict mode. This is equivalent to prefacing every repl statement with `'use strict'`. * `repl.REPL_MODE_MAGIC` - attempt to run commands in default mode. If they fail to parse, re-try in strict mode. You can use your own `eval` function if it has following signature: function eval(cmd, context, filename, callback) { callback(null, result); } On tab completion - `eval` will be called with `.scope` as an input string. It is expected to return an array of scope names to be used for the auto-completion. Multiple REPLs may be started against the same running instance of Node.js. Each will share the same global object but will have unique I/O. Here is an example that starts a REPL on stdin, a Unix socket, and a TCP socket: const net = require('net'); const repl = require('repl'); var connections = 0; repl.start({ prompt: 'Node.js via stdin> ', input: process.stdin, output: process.stdout }); net.createServer((socket) => { connections += 1; repl.start({ prompt: 'Node.js via Unix socket> ', input: socket, output: socket }).on('exit', () => { socket.end(); }) }).listen('/tmp/node-repl-sock'); net.createServer((socket) => { connections += 1; repl.start({ prompt: 'Node.js via TCP socket> ', input: socket, output: socket }).on('exit', () => { socket.end(); }); }).listen(5001); Running this program from the command line will start a REPL on stdin. Other REPL clients may connect through the Unix socket or TCP socket. `telnet` is useful for connecting to TCP sockets, and `socat` can be used to connect to both Unix and TCP sockets. By starting a REPL from a Unix socket-based server instead of stdin, you can connect to a long-running Node.js process without restarting it. For an example of running a "full-featured" (`terminal`) REPL over a `net.Server` and `net.Socket` instance, see: https://gist.github.com/2209310 For an example of running a REPL instance over `curl(1)`, see: https://gist.github.com/2053342 [`readline.prompt`]: readline.html#readline_rl_prompt_preservecursor [`util.inspect()`]: util.html#util_util_inspect_object_options [here]: util.html#util_custom_inspect_function_on_objects [Readline Interface]: readline.html#readline_class_interface node-v4.2.6/doc/api/stream.html000644 000766 000024 00000240527 12650222331 016453 0ustar00iojsstaff000000 000000 Stream Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Stream#

Stability: 2 - Stable

A stream is an abstract interface implemented by various objects in Node.js. For example a request to an HTTP server is a stream, as is stdout. Streams are readable, writable, or both. All streams are instances of EventEmitter.

You can load the Stream base classes by doing require('stream'). There are base classes provided for Readable streams, Writable streams, Duplex streams, and Transform streams.

This document is split up into 3 sections:

  1. The first section explains the parts of the API that you need to be aware of to use streams in your programs.
  2. The second section explains the parts of the API that you need to use if you implement your own custom streams yourself. The API is designed to make this easy for you to do.
  3. The third section goes into more depth about how streams work, including some of the internal mechanisms and functions that you should probably not modify unless you definitely know what you are doing.

API for Stream Consumers#

Streams can be either Readable, Writable, or both (Duplex).

All streams are EventEmitters, but they also have other custom methods and properties depending on whether they are Readable, Writable, or Duplex.

If a stream is both Readable and Writable, then it implements all of the methods and events below. So, a Duplex or Transform stream is fully described by this API, though their implementation may be somewhat different.

It is not necessary to implement Stream interfaces in order to consume streams in your programs. If you are implementing streaming interfaces in your own program, please also refer to API for Stream Implementors below.

Almost all Node.js programs, no matter how simple, use Streams in some way. Here is an example of using Streams in an Node.js program:

const http = require('http');

var server = http.createServer( (req, res) => {
  // req is an http.IncomingMessage, which is a Readable Stream
  // res is an http.ServerResponse, which is a Writable Stream

  var body = '';
  // we want to get the data as utf8 strings
  // If you don't set an encoding, then you'll get Buffer objects
  req.setEncoding('utf8');

  // Readable streams emit 'data' events once a listener is added
  req.on('data', (chunk) => {
    body += chunk;
  });

  // the end event tells you that you have entire body
  req.on('end', () => {
    try {
      var data = JSON.parse(body);
    } catch (er) {
      // uh oh!  bad json!
      res.statusCode = 400;
      return res.end(`error: ${er.message}`);
    }

    // write back something interesting to the user:
    res.write(typeof data);
    res.end();
  });
});

server.listen(1337);

// $ curl localhost:1337 -d '{}'
// object
// $ curl localhost:1337 -d '"foo"'
// string
// $ curl localhost:1337 -d 'not json'
// error: Unexpected token o

Class: stream.Duplex#

Duplex streams are streams that implement both the Readable and Writable interfaces. See above for usage.

Examples of Duplex streams include:

Class: stream.Readable#

The Readable stream interface is the abstraction for a source of data that you are reading from. In other words, data comes out of a Readable stream.

A Readable stream will not start emitting data until you indicate that you are ready to receive it.

Readable streams have two "modes": a flowing mode and a paused mode. When in flowing mode, data is read from the underlying system and provided to your program as fast as possible. In paused mode, you must explicitly call stream.read() to get chunks of data out. Streams start out in paused mode.

Note: If no data event handlers are attached, and there are no pipe() destinations, and the stream is switched into flowing mode, then data will be lost.

You can switch to flowing mode by doing any of the following:

  • Adding a 'data' event handler to listen for data.
  • Calling the resume() method to explicitly open the flow.
  • Calling the pipe() method to send the data to a Writable.

You can switch back to paused mode by doing either of the following:

  • If there are no pipe destinations, by calling the pause() method.
  • If there are pipe destinations, by removing any 'data' event handlers, and removing all pipe destinations by calling the unpipe() method.

Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data.

Examples of readable streams include:

Event: 'close'#

Emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. The event indicates that no more events will be emitted, and no further computation will occur.

Not all streams will emit the 'close' event.

Event: 'data'#

  • chunk Buffer | String The chunk of data.

Attaching a 'data' event listener to a stream that has not been explicitly paused will switch the stream into flowing mode. Data will then be passed as soon as it is available.

If you just want to get all the data out of the stream as fast as possible, this is the best way to do so.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
});

Event: 'end'#

This event fires when there will be no more data to read.

Note that the 'end' event will not fire unless the data is completely consumed. This can be done by switching into flowing mode, or by calling read() repeatedly until you get to the end.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
});
readable.on('end', () => {
  console.log('there will be no more data.');
});

Event: 'error'#

  • Error Object

Emitted if there was an error receiving data.

Event: 'readable'#

When a chunk of data can be read from the stream, it will emit a 'readable' event.

In some cases, listening for a 'readable' event will cause some data to be read into the internal buffer from the underlying system, if it hadn't already.

var readable = getReadableStreamSomehow();
readable.on('readable', () => {
  // there is some data to read now
});

Once the internal buffer is drained, a 'readable' event will fire again when more data is available.

The 'readable' event is not emitted in the "flowing" mode with the sole exception of the last one, on end-of-stream.

The 'readable' event indicates that the stream has new information: either new data is available or the end of the stream has been reached. In the former case, .read() will return that data. In the latter case, .read() will return null. For instance, in the following example, foo.txt is an empty file:

const fs = require('fs');
var rr = fs.createReadStream('foo.txt');
rr.on('readable', () => {
  console.log('readable:', rr.read());
});
rr.on('end', () => {
  console.log('end');
});

The output of running this script is:

bash-3.2$ node test.js
readable: null
end

readable.isPaused()#

  • Return: Boolean

This method returns whether or not the readable has been explicitly paused by client code (using readable.pause() without a corresponding readable.resume()).

var readable = new stream.Readable

readable.isPaused() // === false
readable.pause()
readable.isPaused() // === true
readable.resume()
readable.isPaused() // === false

readable.pause()#

  • Return: this

This method will cause a stream in flowing mode to stop emitting 'data' events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer.

var readable = getReadableStreamSomehow();
readable.on('data', (chunk) => {
  console.log('got %d bytes of data', chunk.length);
  readable.pause();
  console.log('there will be no more data for 1 second');
  setTimeout(() => {
    console.log('now data will start flowing again');
    readable.resume();
  }, 1000);
});

readable.pipe(destination[, options])#

  • destination Writable Stream The destination for writing data
  • options Object Pipe options
    • end Boolean End the writer when the reader ends. Default = true

This method pulls all the data out of a readable stream, and writes it to the supplied destination, automatically managing the flow so that the destination is not overwhelmed by a fast readable stream.

Multiple destinations can be piped to safely.

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt'
readable.pipe(writable);

This function returns the destination stream, so you can set up pipe chains like so:

var r = fs.createReadStream('file.txt');
var z = zlib.createGzip();
var w = fs.createWriteStream('file.txt.gz');
r.pipe(z).pipe(w);

For example, emulating the Unix cat command:

process.stdin.pipe(process.stdout);

By default end() is called on the destination when the source stream emits end, so that destination is no longer writable. Pass { end: false } as options to keep the destination stream open.

This keeps writer open so that "Goodbye" can be written at the end.

reader.pipe(writer, { end: false });
reader.on('end', () => {
  writer.end('Goodbye\n');
});

Note that process.stderr and process.stdout are never closed until the process exits, regardless of the specified options.

readable.read([size])#

  • size Number Optional argument to specify how much data to read.
  • Return String | Buffer | null

The read() method pulls some data out of the internal buffer and returns it. If there is no data available, then it will return null.

If you pass in a size argument, then it will return that many bytes. If size bytes are not available, then it will return null, unless we've ended, in which case it will return the data remaining in the buffer.

If you do not specify a size argument, then it will return all the data in the internal buffer.

This method should only be called in paused mode. In flowing mode, this method is called automatically until the internal buffer is drained.

var readable = getReadableStreamSomehow();
readable.on('readable', () => {
  var chunk;
  while (null !== (chunk = readable.read())) {
    console.log('got %d bytes of data', chunk.length);
  }
});

If this method returns a data chunk, then it will also trigger the emission of a 'data' event.

Note that calling readable.read([size]) after the 'end' event has been triggered will return null. No runtime error will be raised.

readable.resume()#

  • Return: this

This method will cause the readable stream to resume emitting data events.

This method will switch the stream into flowing mode. If you do not want to consume the data from a stream, but you do want to get to its 'end' event, you can call readable.resume() to open the flow of data.

var readable = getReadableStreamSomehow();
readable.resume();
readable.on('end', () => {
  console.log('got to the end, but did not read anything');
});

readable.setEncoding(encoding)#

  • encoding String The encoding to use.
  • Return: this

Call this function to cause the stream to return strings of the specified encoding instead of Buffer objects. For example, if you do readable.setEncoding('utf8'), then the output data will be interpreted as UTF-8 data, and returned as strings. If you do readable.setEncoding('hex'), then the data will be encoded in hexadecimal string format.

This properly handles multi-byte characters that would otherwise be potentially mangled if you simply pulled the Buffers directly and called buf.toString(encoding) on them. If you want to read the data as strings, always use this method.

var readable = getReadableStreamSomehow();
readable.setEncoding('utf8');
readable.on('data', (chunk) => {
  assert.equal(typeof chunk, 'string');
  console.log('got %d characters of string data', chunk.length);
});

readable.unpipe([destination])#

  • destination Writable Stream Optional specific stream to unpipe

This method will remove the hooks set up for a previous pipe() call.

If the destination is not specified, then all pipes are removed.

If the destination is specified, but no pipe is set up for it, then this is a no-op.

var readable = getReadableStreamSomehow();
var writable = fs.createWriteStream('file.txt');
// All the data from readable goes into 'file.txt',
// but only for the first second
readable.pipe(writable);
setTimeout(() => {
  console.log('stop writing to file.txt');
  readable.unpipe(writable);
  console.log('manually close the file stream');
  writable.end();
}, 1000);

readable.unshift(chunk)#

  • chunk Buffer | String Chunk of data to unshift onto the read queue

This is useful in certain cases where a stream is being consumed by a parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party.

Note that stream.unshift(chunk) cannot be called after the 'end' event has been triggered; a runtime error will be raised.

If you find that you must often call stream.unshift(chunk) in your programs, consider implementing a Transform stream instead. (See API for Stream Implementors, below.)

// Pull off a header delimited by \n\n
// use unshift() if we get too much
// Call the callback with (error, header, stream)
const StringDecoder = require('string_decoder').StringDecoder;
function parseHeader(stream, callback) {
  stream.on('error', callback);
  stream.on('readable', onReadable);
  var decoder = new StringDecoder('utf8');
  var header = '';
  function onReadable() {
    var chunk;
    while (null !== (chunk = stream.read())) {
      var str = decoder.write(chunk);
      if (str.match(/\n\n/)) {
        // found the header boundary
        var split = str.split(/\n\n/);
        header += split.shift();
        var remaining = split.join('\n\n');
        var buf = new Buffer(remaining, 'utf8');
        if (buf.length)
          stream.unshift(buf);
        stream.removeListener('error', callback);
        stream.removeListener('readable', onReadable);
        // now the body of the message can be read from the stream.
        callback(null, header, stream);
      } else {
        // still reading the header.
        header += str;
      }
    }
  }
}

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not end the reading process by resetting the internal reading state of the stream. This can cause unexpected results if unshift is called during a read (i.e. from within a _read implementation on a custom stream). Following the call to unshift with an immediate stream.push('') will reset the reading state appropriately, however it is best to simply avoid calling unshift while in the process of performing a read.

readable.wrap(stream)#

  • stream Stream An "old style" readable stream

Versions of Node.js prior to v0.10 had streams that did not implement the entire Streams API as it is today. (See "Compatibility" below for more information.)

If you are using an older Node.js library that emits 'data' events and has a pause() method that is advisory only, then you can use the wrap() method to create a Readable stream that uses the old stream as its data source.

You will very rarely ever need to call this function, but it exists as a convenience for interacting with old Node.js programs and libraries.

For example:

const OldReader = require('./old-api-module.js').OldReader;
const Readable = require('stream').Readable;
const oreader = new OldReader;
const myReader = new Readable().wrap(oreader);

myReader.on('readable', () => {
  myReader.read(); // etc.
});

Class: stream.Transform#

Transform streams are Duplex streams where the output is in some way computed from the input. They implement both the Readable and Writable interfaces. See above for usage.

Examples of Transform streams include:

Class: stream.Writable#

The Writable stream interface is an abstraction for a destination that you are writing data to.

Examples of writable streams include:

Event: 'drain'#

If a writable.write(chunk) call returns false, then the 'drain' event will indicate when it is appropriate to begin writing more data to the stream.

// Write the data to the supplied writable stream one million times.
// Be attentive to back-pressure.
function writeOneMillionTimes(writer, data, encoding, callback) {
  var i = 1000000;
  write();
  function write() {
    var ok = true;
    do {
      i -= 1;
      if (i === 0) {
        // last time!
        writer.write(data, encoding, callback);
      } else {
        // see if we should continue, or wait
        // don't pass the callback, because we're not done yet.
        ok = writer.write(data, encoding);
      }
    } while (i > 0 && ok);
    if (i > 0) {
      // had to stop early!
      // write some more once it drains
      writer.once('drain', write);
    }
  }
}

Event: 'error'#

  • Error object

Emitted if there was an error when writing or piping data.

Event: 'finish'#

When the end() method has been called, and all data has been flushed to the underlying system, this event is emitted.

var writer = getWritableStreamSomehow();
for (var i = 0; i < 100; i ++) {
  writer.write('hello, #${i}!\n');
}
writer.end('this is the end\n');
writer.on('finish', () => {
  console.error('all writes are now complete.');
});

Event: 'pipe'#

  • src Readable Stream source stream that is piping to this writable

This is emitted whenever the pipe() method is called on a readable stream, adding this writable to its set of destinations.

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('pipe', (src) => {
  console.error('something is piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);

Event: 'unpipe'#

This is emitted whenever the unpipe() method is called on a readable stream, removing this writable from its set of destinations.

var writer = getWritableStreamSomehow();
var reader = getReadableStreamSomehow();
writer.on('unpipe', (src) => {
  console.error('something has stopped piping into the writer');
  assert.equal(src, reader);
});
reader.pipe(writer);
reader.unpipe(writer);

writable.cork()#

Forces buffering of all writes.

Buffered data will be flushed either at .uncork() or at .end() call.

writable.end([chunk][, encoding][, callback])#

  • chunk String | Buffer Optional data to write
  • encoding String The encoding, if chunk is a String
  • callback Function Optional callback for when the stream is finished

Call this method when no more data will be written to the stream. If supplied, the callback is attached as a listener on the 'finish' event.

Calling write() after calling end() will raise an error.

// write 'hello, ' and then end with 'world!'
var file = fs.createWriteStream('example.txt');
file.write('hello, ');
file.end('world!');
// writing more now is not allowed!

writable.setDefaultEncoding(encoding)#

  • encoding String The new default encoding

Sets the default encoding for a writable stream.

writable.uncork()#

Flush all data, buffered since .cork() call.

writable.write(chunk[, encoding][, callback])#

  • chunk String | Buffer The data to write
  • encoding String The encoding, if chunk is a String
  • callback Function Callback for when this chunk of data is flushed
  • Returns: Boolean True if the data was handled completely.

This method writes some data to the underlying system, and calls the supplied callback once the data has been fully handled.

The return value indicates if you should continue writing right now. If the data had to be buffered internally, then it will return false. Otherwise, it will return true.

This return value is strictly advisory. You MAY continue to write, even if it returns false. However, writes will be buffered in memory, so it is best not to do this excessively. Instead, wait for the 'drain' event before writing more data.

API for Stream Implementors#

To implement any sort of stream, the pattern is the same:

  1. Extend the appropriate parent class in your own subclass. (The util.inherits method is particularly helpful for this.)
  2. Call the appropriate parent class constructor in your constructor, to be sure that the internal mechanisms are set up properly.
  3. Implement one or more specific methods, as detailed below.

The class to extend and the method(s) to implement depend on the sort of stream class you are writing:

Use-case

Class

Method(s) to implement

Reading only

Readable

_read

Writing only

Writable

_write, _writev

Reading and writing

Duplex

_read, _write, _writev

Operate on written data, then read the result

Transform

_transform, _flush

In your implementation code, it is very important to never call the methods described in API for Stream Consumers above. Otherwise, you can potentially cause adverse side effects in programs that consume your streaming interfaces.

Class: stream.Duplex#

A "duplex" stream is one that is both Readable and Writable, such as a TCP socket connection.

Note that stream.Duplex is an abstract class designed to be extended with an underlying implementation of the _read(size) and _write(chunk, encoding, callback) methods as you would with a Readable or Writable stream class.

Since JavaScript doesn't have multiple prototypal inheritance, this class prototypally inherits from Readable, and then parasitically from Writable. It is thus up to the user to implement both the lowlevel _read(n) method as well as the lowlevel _write(chunk, encoding, callback) method on extension duplex classes.

new stream.Duplex(options)#

  • options Object Passed to both Writable and Readable constructors. Also has the following fields:
    • allowHalfOpen Boolean Default=true. If set to false, then the stream will automatically end the readable side when the writable side ends and vice versa.
    • readableObjectMode Boolean Default=false. Sets objectMode for readable side of the stream. Has no effect if objectMode is true.
    • writableObjectMode Boolean Default=false. Sets objectMode for writable side of the stream. Has no effect if objectMode is true.

In classes that extend the Duplex class, make sure to call the constructor so that the buffering settings can be properly initialized.

Class: stream.PassThrough#

This is a trivial implementation of a Transform stream that simply passes the input bytes across to the output. Its purpose is mainly for examples and testing, but there are occasionally use cases where it can come in handy as a building block for novel sorts of streams.

Class: stream.Readable#

stream.Readable is an abstract class designed to be extended with an underlying implementation of the _read(size) method.

Please see above under API for Stream Consumers for how to consume streams in your programs. What follows is an explanation of how to implement Readable streams in your programs.

new stream.Readable([options])#

  • options Object
    • highWaterMark Number The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for objectMode streams
    • encoding String If specified, then buffers will be decoded to strings using the specified encoding. Default=null
    • objectMode Boolean Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false

In classes that extend the Readable class, make sure to call the Readable constructor so that the buffering settings can be properly initialized.

readable._read(size)#

  • size Number Number of bytes to read asynchronously

Note: Implement this method, but do NOT call it directly.

This method is prefixed with an underscore because it is internal to the class that defines it and should only be called by the internal Readable class methods. All Readable stream implementations must provide a _read method to fetch data from the underlying resource.

When _read is called, if data is available from the resource, _read should start pushing that data into the read queue by calling this.push(dataChunk). _read should continue reading from the resource and pushing data until push returns false, at which point it should stop reading from the resource. Only when _read is called again after it has stopped should it start reading more data from the resource and pushing that data onto the queue.

Note: once the _read() method is called, it will not be called again until the push method is called.

The size argument is advisory. Implementations where a "read" is a single call that returns data can use this to know how much data to fetch. Implementations where that is not relevant, such as TCP or TLS, may ignore this argument, and simply provide data whenever it becomes available. There is no need, for example to "wait" until size bytes are available before calling stream.push(chunk).

readable.push(chunk[, encoding])#

  • chunk Buffer | null | String Chunk of data to push into the read queue
  • encoding String Encoding of String chunks. Must be a valid Buffer encoding, such as 'utf8' or 'ascii'
  • return Boolean Whether or not more pushes should be performed

Note: This method should be called by Readable implementors, NOT by consumers of Readable streams.

If a value other than null is passed, The push() method adds a chunk of data into the queue for subsequent stream processors to consume. If null is passed, it signals the end of the stream (EOF), after which no more data can be written.

The data added with push can be pulled out by calling the read() method when the 'readable' event fires.

This API is designed to be as flexible as possible. For example, you may be wrapping a lower-level source which has some sort of pause/resume mechanism, and a data callback. In those cases, you could wrap the low-level source object by doing something like this:

// source is an object with readStop() and readStart() methods,
// and an `ondata` member that gets called when it has data, and
// an `onend` member that gets called when the data is over.

util.inherits(SourceWrapper, Readable);

function SourceWrapper(options) {
  Readable.call(this, options);

  this._source = getLowlevelSourceObject();
  var self = this;

  // Every time there's data, we push it into the internal buffer.
  this._source.ondata = function(chunk) {
    // if push() returns false, then we need to stop reading from source
    if (!self.push(chunk))
      self._source.readStop();
  };

  // When the source ends, we push the EOF-signaling `null` chunk
  this._source.onend = function() {
    self.push(null);
  };
}

// _read will be called when the stream wants to pull more data in
// the advisory size argument is ignored in this case.
SourceWrapper.prototype._read = function(size) {
  this._source.readStart();
};

Example: A Counting Stream#

This is a basic example of a Readable stream. It emits the numerals from 1 to 1,000,000 in ascending order, and then ends.

const Readable = require('stream').Readable;
const util = require('util');
util.inherits(Counter, Readable);

function Counter(opt) {
  Readable.call(this, opt);
  this._max = 1000000;
  this._index = 1;
}

Counter.prototype._read = function() {
  var i = this._index++;
  if (i > this._max)
    this.push(null);
  else {
    var str = '' + i;
    var buf = new Buffer(str, 'ascii');
    this.push(buf);
  }
};

Example: SimpleProtocol v1 (Sub-optimal)#

This is similar to the parseHeader function described above, but implemented as a custom stream. Also, note that this implementation does not convert the incoming data to a string.

However, this would be better implemented as a Transform stream. See below for a better implementation.

// A parser for a simple data protocol.
// The "header" is a JSON object, followed by 2 \n characters, and
// then a message body.
//
// NOTE: This can be done more simply as a Transform stream!
// Using Readable directly for this is sub-optimal.  See the
// alternative example below under the Transform section.

const Readable = require('stream').Readable;
const util = require('util');

util.inherits(SimpleProtocol, Readable);

function SimpleProtocol(source, options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(source, options);

  Readable.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;

  // source is a readable stream, such as a socket or file
  this._source = source;

  var self = this;
  source.on('end', () => {
    self.push(null);
  });

  // give it a kick whenever the source is readable
  // read(0) will not consume any bytes
  source.on('readable', () => {
    self.read(0);
  });

  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._read = function(n) {
  if (!this._inBody) {
    var chunk = this._source.read();

    // if the source doesn't have data, we don't have data yet.
    if (chunk === null)
      return this.push('');

    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
      this.push('');
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // now, because we got some extra data, unshift the rest
      // back into the read queue so that our consumer will see it.
      var b = chunk.slice(split);
      this.unshift(b);
      // calling unshift by itself does not reset the reading state
      // of the stream; since we're inside _read, doing an additional
      // push('') will reset the state appropriately.
      this.push('');

      // and let them know that we are done parsing the header.
      this.emit('header', this.header);
    }
  } else {
    // from there on, just provide the data to our consumer.
    // careful not to push(null), since that would indicate EOF.
    var chunk = this._source.read();
    if (chunk) this.push(chunk);
  }
};

// Usage:
// var parser = new SimpleProtocol(source);
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

Class: stream.Transform#

A "transform" stream is a duplex stream where the output is causally connected in some way to the input, such as a zlib stream or a crypto stream.

There is no requirement that the output be the same size as the input, the same number of chunks, or arrive at the same time. For example, a Hash stream will only ever have a single chunk of output which is provided when the input is ended. A zlib stream will produce output that is either much smaller or much larger than its input.

Rather than implement the _read() and _write() methods, Transform classes must implement the _transform() method, and may optionally also implement the _flush() method. (See below.)

new stream.Transform([options])#

  • options Object Passed to both Writable and Readable constructors.

In classes that extend the Transform class, make sure to call the constructor so that the buffering settings can be properly initialized.

Events: 'finish' and 'end'#

The 'finish' and 'end' events are from the parent Writable and Readable classes respectively. The 'finish' event is fired after .end() is called and all chunks have been processed by _transform, end is fired after all data has been output which is after the callback in _flush has been called.

transform._flush(callback)#

  • callback Function Call this function (optionally with an error argument) when you are done flushing any remaining data.

Note: This function MUST NOT be called directly. It MAY be implemented by child classes, and if so, will be called by the internal Transform class methods only.

In some cases, your transform operation may need to emit a bit more data at the end of the stream. For example, a Zlib compression stream will store up some internal state so that it can optimally compress the output. At the end, however, it needs to do the best it can with what is left, so that the data will be complete.

In those cases, you can implement a _flush method, which will be called at the very end, after all the written data is consumed, but before emitting end to signal the end of the readable side. Just like with _transform, call transform.push(chunk) zero or more times, as appropriate, and call callback when the flush operation is complete.

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

transform._transform(chunk, encoding, callback)#

  • chunk Buffer | String The chunk to be transformed. Will always be a buffer unless the decodeStrings option was set to false.
  • encoding String If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case.
  • callback Function Call this function (optionally with an error argument and data) when you are done processing the supplied chunk.

Note: This function MUST NOT be called directly. It should be implemented by child classes, and called by the internal Transform class methods only.

All Transform stream implementations must provide a _transform method to accept input and produce output.

_transform should do whatever has to be done in this specific Transform class, to handle the bytes being written, and pass them off to the readable portion of the interface. Do asynchronous I/O, process things, and so on.

Call transform.push(outputChunk) 0 or more times to generate output from this input chunk, depending on how much data you want to output as a result of this chunk.

Call the callback function only when the current chunk is completely consumed. Note that there may or may not be output as a result of any particular input chunk. If you supply a second argument to the callback it will be passed to the push method. In other words the following are equivalent:

transform.prototype._transform = function (data, encoding, callback) {
  this.push(data);
  callback();
};

transform.prototype._transform = function (data, encoding, callback) {
  callback(null, data);
};

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

Example: SimpleProtocol parser v2#

The example above of a simple protocol parser can be implemented simply by using the higher level Transform stream class, similar to the parseHeader and SimpleProtocol v1 examples above.

In this example, rather than providing the input as an argument, it would be piped into the parser, which is a more idiomatic Node.js stream approach.

const util = require('util');
const Transform = require('stream').Transform;
util.inherits(SimpleProtocol, Transform);

function SimpleProtocol(options) {
  if (!(this instanceof SimpleProtocol))
    return new SimpleProtocol(options);

  Transform.call(this, options);
  this._inBody = false;
  this._sawFirstCr = false;
  this._rawHeader = [];
  this.header = null;
}

SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
  if (!this._inBody) {
    // check if the chunk has a \n\n
    var split = -1;
    for (var i = 0; i < chunk.length; i++) {
      if (chunk[i] === 10) { // '\n'
        if (this._sawFirstCr) {
          split = i;
          break;
        } else {
          this._sawFirstCr = true;
        }
      } else {
        this._sawFirstCr = false;
      }
    }

    if (split === -1) {
      // still waiting for the \n\n
      // stash the chunk, and try again.
      this._rawHeader.push(chunk);
    } else {
      this._inBody = true;
      var h = chunk.slice(0, split);
      this._rawHeader.push(h);
      var header = Buffer.concat(this._rawHeader).toString();
      try {
        this.header = JSON.parse(header);
      } catch (er) {
        this.emit('error', new Error('invalid simple protocol data'));
        return;
      }
      // and let them know that we are done parsing the header.
      this.emit('header', this.header);

      // now, because we got some extra data, emit this first.
      this.push(chunk.slice(split));
    }
  } else {
    // from there on, just provide the data to our consumer as-is.
    this.push(chunk);
  }
  done();
};

// Usage:
// var parser = new SimpleProtocol();
// source.pipe(parser)
// Now parser is a readable stream that will emit 'header'
// with the parsed header data.

Class: stream.Writable#

stream.Writable is an abstract class designed to be extended with an underlying implementation of the _write(chunk, encoding, callback) method.

Please see above under API for Stream Consumers for how to consume writable streams in your programs. What follows is an explanation of how to implement Writable streams in your programs.

new stream.Writable([options])#

  • options Object
    • highWaterMark Number Buffer level when write() starts returning false. Default=16kb, or 16 for objectMode streams
    • decodeStrings Boolean Whether or not to decode strings into Buffers before passing them to _write(). Default=true
    • objectMode Boolean Whether or not the write(anyObj) is a valid operation. If set you can write arbitrary data instead of only Buffer / String data. Default=false

In classes that extend the Writable class, make sure to call the constructor so that the buffering settings can be properly initialized.

writable._write(chunk, encoding, callback)#

  • chunk Buffer | String The chunk to be written. Will always be a buffer unless the decodeStrings option was set to false.
  • encoding String If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case.
  • callback Function Call this function (optionally with an error argument) when you are done processing the supplied chunk.

All Writable stream implementations must provide a _write() method to send data to the underlying resource.

Note: This function MUST NOT be called directly. It should be implemented by child classes, and called by the internal Writable class methods only.

Call the callback using the standard callback(error) pattern to signal that the write completed successfully or with an error.

If the decodeStrings flag is set in the constructor options, then chunk may be a string rather than a Buffer, and encoding will indicate the sort of string that it is. This is to support implementations that have an optimized handling for certain string data encodings. If you do not explicitly set the decodeStrings option to false, then you can safely ignore the encoding argument, and assume that chunk will always be a Buffer.

This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you are expected to override this method in your own extension classes.

writable._writev(chunks, callback)#

  • chunks Array The chunks to be written. Each chunk has following format: { chunk: ..., encoding: ... }.
  • callback Function Call this function (optionally with an error argument) when you are done processing the supplied chunks.

Note: This function MUST NOT be called directly. It may be implemented by child classes, and called by the internal Writable class methods only.

This function is completely optional to implement. In most cases it is unnecessary. If implemented, it will be called with all the chunks that are buffered in the write queue.

Simplified Constructor API#

In simple cases there is now the added benefit of being able to construct a stream without inheritance.

This can be done by passing the appropriate methods as constructor options:

Examples:

Duplex#

var duplex = new stream.Duplex({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  },
  write: function(chunk, encoding, next) {
    // sets this._write under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

// or

var duplex = new stream.Duplex({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  },
  writev: function(chunks, next) {
    // sets this._writev under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

Readable#

var readable = new stream.Readable({
  read: function(n) {
    // sets this._read under the hood

    // push data onto the read queue, passing null
    // will signal the end of the stream (EOF)
    this.push(chunk);
  }
});

Transform#

var transform = new stream.Transform({
  transform: function(chunk, encoding, next) {
    // sets this._transform under the hood

    // generate output as many times as needed
    // this.push(chunk);

    // call when the current chunk is consumed
    next();
  },
  flush: function(done) {
    // sets this._flush under the hood

    // generate output as many times as needed
    // this.push(chunk);

    done();
  }
});

Writable#

var writable = new stream.Writable({
  write: function(chunk, encoding, next) {
    // sets this._write under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

// or

var writable = new stream.Writable({
  writev: function(chunks, next) {
    // sets this._writev under the hood

    // An optional error can be passed as the first argument
    next()
  }
});

Streams: Under the Hood#

Buffering#

Both Writable and Readable streams will buffer data on an internal object which can be retrieved from _writableState.getBuffer() or _readableState.buffer, respectively.

The amount of data that will potentially be buffered depends on the highWaterMark option which is passed into the constructor.

Buffering in Readable streams happens when the implementation calls stream.push(chunk). If the consumer of the Stream does not call stream.read(), then the data will sit in the internal queue until it is consumed.

Buffering in Writable streams happens when the user calls stream.write(chunk) repeatedly, even when write() returns false.

The purpose of streams, especially with the pipe() method, is to limit the buffering of data to acceptable levels, so that sources and destinations of varying speed will not overwhelm the available memory.

Compatibility with Older Node.js Versions#

In versions of Node.js prior to v0.10, the Readable stream interface was simpler, but also less powerful and less useful.

  • Rather than waiting for you to call the read() method, 'data' events would start emitting immediately. If you needed to do some I/O to decide how to handle data, then you had to store the chunks in some kind of buffer so that they would not be lost.
  • The pause() method was advisory, rather than guaranteed. This meant that you still had to be prepared to receive 'data' events even when the stream was in a paused state.

In Node.js v0.10, the Readable class described below was added. For backwards compatibility with older Node.js programs, Readable streams switch into "flowing mode" when a 'data' event handler is added, or when the resume() method is called. The effect is that, even if you are not using the new read() method and 'readable' event, you no longer have to worry about losing 'data' chunks.

Most programs will continue to function normally. However, this introduces an edge case in the following conditions:

  • No 'data' event handler is added.
  • The resume() method is never called.
  • The stream is not piped to any writable destination.

For example, consider the following code:

// WARNING!  BROKEN!
net.createServer((socket) => {

  // we add an 'end' method, but never consume the data
  socket.on('end', () => {
    // It will never get here.
    socket.end('I got your message (but didnt read it)\n');
  });

}).listen(1337);

In versions of Node.js prior to v0.10, the incoming message data would be simply discarded. However, in Node.js v0.10 and beyond, the socket will remain paused forever.

The workaround in this situation is to call the resume() method to start the flow of data:

// Workaround
net.createServer((socket) => {

  socket.on('end', () => {
    socket.end('I got your message (but didnt read it)\n');
  });

  // start the flow of data, discarding it.
  socket.resume();

}).listen(1337);

In addition to new Readable streams switching into flowing mode, pre-v0.10 style streams can be wrapped in a Readable class using the wrap() method.

Object Mode#

Normally, Streams operate on Strings and Buffers exclusively.

Streams that are in object mode can emit generic JavaScript values other than Buffers and Strings.

A Readable stream in object mode will always return a single item from a call to stream.read(size), regardless of what the size argument is.

A Writable stream in object mode will always ignore the encoding argument to stream.write(data, encoding).

The special value null still retains its special value for object mode streams. That is, for object mode readable streams, null as a return value from stream.read() indicates that there is no more data, and stream.push(null) will signal the end of stream data (EOF).

No streams in Node.js core are object mode streams. This pattern is only used by userland streaming libraries.

You should set objectMode in your stream child class constructor on the options object. Setting objectMode mid-stream is not safe.

For Duplex streams objectMode can be set exclusively for readable or writable side with readableObjectMode and writableObjectMode respectively. These options can be used to implement parsers and serializers with Transform streams.

const util = require('util');
const StringDecoder = require('string_decoder').StringDecoder;
const Transform = require('stream').Transform;
util.inherits(JSONParseStream, Transform);

// Gets \n-delimited JSON string data, and emits the parsed objects
function JSONParseStream() {
  if (!(this instanceof JSONParseStream))
    return new JSONParseStream();

  Transform.call(this, { readableObjectMode : true });

  this._buffer = '';
  this._decoder = new StringDecoder('utf8');
}

JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
  this._buffer += this._decoder.write(chunk);
  // split on newlines
  var lines = this._buffer.split(/\r?\n/);
  // keep the last partial line buffered
  this._buffer = lines.pop();
  for (var l = 0; l < lines.length; l++) {
    var line = lines[l];
    try {
      var obj = JSON.parse(line);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

JSONParseStream.prototype._flush = function(cb) {
  // Just handle any leftover
  var rem = this._buffer.trim();
  if (rem) {
    try {
      var obj = JSON.parse(rem);
    } catch (er) {
      this.emit('error', er);
      return;
    }
    // push the parsed object out to the readable consumer
    this.push(obj);
  }
  cb();
};

stream.read(0)#

There are some cases where you want to trigger a refresh of the underlying readable stream mechanisms, without actually consuming any data. In that case, you can call stream.read(0), which will always return null.

If the internal read buffer is below the highWaterMark, and the stream is not currently reading, then calling read(0) will trigger a low-level _read call.

There is almost never a need to do this. However, you will see some cases in Node.js's internals where this is done, particularly in the Readable stream class internals.

stream.push('')#

Pushing a zero-byte string or Buffer (when not in Object mode) has an interesting side effect. Because it is a call to stream.push(), it will end the reading process. However, it does not add any data to the readable buffer, so there's nothing for a user to consume.

Very rarely, there are cases where you have no data to provide now, but the consumer of your stream (or, perhaps, another bit of your own code) will know when to check again, by calling stream.read(0). In those cases, you may call stream.push('').

So far, the only use case for this functionality is in the tls.CryptoStream class, which is deprecated in Node.js/io.js v1.0. If you find that you have to use stream.push(''), please consider another approach, because it almost certainly indicates that something is horribly wrong.

node-v4.2.6/doc/api/stream.json000644 000766 000024 00000374165 12650222331 016466 0ustar00iojsstaff000000 000000 { "source": "doc/api/stream.markdown", "modules": [ { "textRaw": "Stream", "name": "stream", "stability": 2, "stabilityText": "Stable", "desc": "

A stream is an abstract interface implemented by various objects in\nNode.js. For example a [request to an HTTP server][] is a stream, as is\n[stdout][]. Streams are readable, writable, or both. All streams are\ninstances of [EventEmitter][].\n\n

\n

You can load the Stream base classes by doing require('stream').\nThere are base classes provided for [Readable][] streams, [Writable][]\nstreams, [Duplex][] streams, and [Transform][] streams.\n\n

\n

This document is split up into 3 sections:\n\n

\n
    \n
  1. The first section explains the parts of the API that you need to be\naware of to use streams in your programs.
  2. \n
  3. The second section explains the parts of the API that you need to\nuse if you implement your own custom streams yourself. The API is\ndesigned to make this easy for you to do.
  4. \n
  5. The third section goes into more depth about how streams work,\nincluding some of the internal mechanisms and functions that you\nshould probably not modify unless you definitely know what you are\ndoing.
  6. \n
\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

Duplex streams are streams that implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Duplex streams include:\n\n

\n
    \n
  • [tcp sockets][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

The Readable stream interface is the abstraction for a source of\ndata that you are reading from. In other words, data comes out of a\nReadable stream.\n\n

\n

A Readable stream will not start emitting data until you indicate that\nyou are ready to receive it.\n\n

\n

Readable streams have two "modes": a flowing mode and a paused\nmode. When in flowing mode, data is read from the underlying system\nand provided to your program as fast as possible. In paused mode, you\nmust explicitly call stream.read() to get chunks of data out.\nStreams start out in paused mode.\n\n

\n

Note: If no data event handlers are attached, and there are no\n[pipe()][] destinations, and the stream is switched into flowing\nmode, then data will be lost.\n\n

\n

You can switch to flowing mode by doing any of the following:\n\n

\n
    \n
  • Adding a ['data'][] event handler to listen for data.
  • \n
  • Calling the [resume()][] method to explicitly open the flow.
  • \n
  • Calling the [pipe()][] method to send the data to a [Writable][].
  • \n
\n

You can switch back to paused mode by doing either of the following:\n\n

\n
    \n
  • If there are no pipe destinations, by calling the [pause()][]\nmethod.
  • \n
  • If there are pipe destinations, by removing any ['data'][] event\nhandlers, and removing all pipe destinations by calling the\n[unpipe()][] method.
  • \n
\n

Note that, for backwards compatibility reasons, removing 'data'\nevent handlers will not automatically pause the stream. Also, if\nthere are piped destinations, then calling pause() will not\nguarantee that the stream will remain paused once those\ndestinations drain and ask for more data.\n\n

\n

Examples of readable streams include:\n\n

\n
    \n
  • [http responses, on the client][]
  • \n
  • [http requests, on the server][]
  • \n
  • [fs read streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdout and stderr][]
  • \n
  • [process.stdin][]
  • \n
\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the stream and any of its underlying resources (a file\ndescriptor, for example) have been closed. The event indicates that\nno more events will be emitted, and no further computation will occur.\n\n

\n

Not all streams will emit the 'close' event.\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Attaching a 'data' event listener to a stream that has not been\nexplicitly paused will switch the stream into flowing mode. Data will\nthen be passed as soon as it is available.\n\n

\n

If you just want to get all the data out of the stream as fast as\npossible, this is the best way to do so.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});
\n" }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

This event fires when there will be no more data to read.\n\n

\n

Note that the 'end' event will not fire unless the data is\ncompletely consumed. This can be done by switching into flowing mode,\nor by calling read() repeatedly until you get to the end.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});\nreadable.on('end', () => {\n  console.log('there will be no more data.');\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error receiving data.\n\n

\n" }, { "textRaw": "Event: 'readable'", "type": "event", "name": "readable", "desc": "

When a chunk of data can be read from the stream, it will emit a\n'readable' event.\n\n

\n

In some cases, listening for a 'readable' event will cause some data\nto be read into the internal buffer from the underlying system, if it\nhadn't already.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  // there is some data to read now\n});
\n

Once the internal buffer is drained, a 'readable' event will fire\nagain when more data is available.\n\n

\n

The 'readable' event is not emitted in the "flowing" mode with the\nsole exception of the last one, on end-of-stream.\n\n

\n

The 'readable' event indicates that the stream has new information:\neither new data is available or the end of the stream has been reached.\nIn the former case, .read() will return that data. In the latter case,\n.read() will return null. For instance, in the following example, foo.txt\nis an empty file:\n\n

\n
const fs = require('fs');\nvar rr = fs.createReadStream('foo.txt');\nrr.on('readable', () => {\n  console.log('readable:', rr.read());\n});\nrr.on('end', () => {\n  console.log('end');\n});
\n

The output of running this script is:\n\n

\n
bash-3.2$ node test.js\nreadable: null\nend
\n", "params": [] } ], "methods": [ { "textRaw": "readable.isPaused()", "type": "method", "name": "isPaused", "signatures": [ { "return": { "textRaw": "Return: `Boolean` ", "name": "return", "desc": "`Boolean`" }, "params": [] }, { "params": [] } ], "desc": "

This method returns whether or not the readable has been explicitly\npaused by client code (using readable.pause() without a corresponding\nreadable.resume()).\n\n

\n
var readable = new stream.Readable\n\nreadable.isPaused() // === false\nreadable.pause()\nreadable.isPaused() // === true\nreadable.resume()\nreadable.isPaused() // === false
\n" }, { "textRaw": "readable.pause()", "type": "method", "name": "pause", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause a stream in flowing mode to stop emitting\n'data' events, switching out of flowing mode. Any data that becomes\navailable will remain in the internal buffer.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n  readable.pause();\n  console.log('there will be no more data for 1 second');\n  setTimeout(() => {\n    console.log('now data will start flowing again');\n    readable.resume();\n  }, 1000);\n});
\n" }, { "textRaw": "readable.pipe(destination[, options])", "type": "method", "name": "pipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} The destination for writing data ", "name": "destination", "type": "[Writable][] Stream", "desc": "The destination for writing data" }, { "textRaw": "`options` {Object} Pipe options ", "options": [ { "textRaw": "`end` {Boolean} End the writer when the reader ends. Default = `true` ", "name": "end", "type": "Boolean", "desc": "End the writer when the reader ends. Default = `true`" } ], "name": "options", "type": "Object", "desc": "Pipe options", "optional": true } ] }, { "params": [ { "name": "destination" }, { "name": "options", "optional": true } ] } ], "desc": "

This method pulls all the data out of a readable stream, and writes it\nto the supplied destination, automatically managing the flow so that\nthe destination is not overwhelmed by a fast readable stream.\n\n

\n

Multiple destinations can be piped to safely.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt'\nreadable.pipe(writable);
\n

This function returns the destination stream, so you can set up pipe\nchains like so:\n\n

\n
var r = fs.createReadStream('file.txt');\nvar z = zlib.createGzip();\nvar w = fs.createWriteStream('file.txt.gz');\nr.pipe(z).pipe(w);
\n

For example, emulating the Unix cat command:\n\n

\n
process.stdin.pipe(process.stdout);
\n

By default [end()][] is called on the destination when the source stream\nemits end, so that destination is no longer writable. Pass { end:\nfalse } as options to keep the destination stream open.\n\n

\n

This keeps writer open so that "Goodbye" can be written at the\nend.\n\n

\n
reader.pipe(writer, { end: false });\nreader.on('end', () => {\n  writer.end('Goodbye\\n');\n});
\n

Note that process.stderr and process.stdout are never closed until\nthe process exits, regardless of the specified options.\n\n

\n" }, { "textRaw": "readable.read([size])", "type": "method", "name": "read", "signatures": [ { "return": { "textRaw": "Return {String | Buffer | null} ", "name": "return", "type": "String | Buffer | null" }, "params": [ { "textRaw": "`size` {Number} Optional argument to specify how much data to read. ", "name": "size", "type": "Number", "desc": "Optional argument to specify how much data to read.", "optional": true } ] }, { "params": [ { "name": "size", "optional": true } ] } ], "desc": "

The read() method pulls some data out of the internal buffer and\nreturns it. If there is no data available, then it will return\nnull.\n\n

\n

If you pass in a size argument, then it will return that many\nbytes. If size bytes are not available, then it will return null,\nunless we've ended, in which case it will return the data remaining\nin the buffer.\n\n

\n

If you do not specify a size argument, then it will return all the\ndata in the internal buffer.\n\n

\n

This method should only be called in paused mode. In flowing mode,\nthis method is called automatically until the internal buffer is\ndrained.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  var chunk;\n  while (null !== (chunk = readable.read())) {\n    console.log('got %d bytes of data', chunk.length);\n  }\n});
\n

If this method returns a data chunk, then it will also trigger the\nemission of a ['data'][] event.\n\n

\n

Note that calling readable.read([size]) after the 'end' event has been\ntriggered will return null. No runtime error will be raised.\n\n

\n" }, { "textRaw": "readable.resume()", "type": "method", "name": "resume", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause the readable stream to resume emitting data\nevents.\n\n

\n

This method will switch the stream into flowing mode. If you do not\nwant to consume the data from a stream, but you do want to get to\nits 'end' event, you can call [readable.resume()][] to open the flow of\ndata.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.resume();\nreadable.on('end', () => {\n  console.log('got to the end, but did not read anything');\n});
\n" }, { "textRaw": "readable.setEncoding(encoding)", "type": "method", "name": "setEncoding", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [ { "textRaw": "`encoding` {String} The encoding to use. ", "name": "encoding", "type": "String", "desc": "The encoding to use." } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Call this function to cause the stream to return strings of the\nspecified encoding instead of Buffer objects. For example, if you do\nreadable.setEncoding('utf8'), then the output data will be\ninterpreted as UTF-8 data, and returned as strings. If you do\nreadable.setEncoding('hex'), then the data will be encoded in\nhexadecimal string format.\n\n

\n

This properly handles multi-byte characters that would otherwise be\npotentially mangled if you simply pulled the Buffers directly and\ncalled buf.toString(encoding) on them. If you want to read the data\nas strings, always use this method.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.setEncoding('utf8');\nreadable.on('data', (chunk) => {\n  assert.equal(typeof chunk, 'string');\n  console.log('got %d characters of string data', chunk.length);\n});
\n" }, { "textRaw": "readable.unpipe([destination])", "type": "method", "name": "unpipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} Optional specific stream to unpipe ", "name": "destination", "type": "[Writable][] Stream", "desc": "Optional specific stream to unpipe", "optional": true } ] }, { "params": [ { "name": "destination", "optional": true } ] } ], "desc": "

This method will remove the hooks set up for a previous pipe() call.\n\n

\n

If the destination is not specified, then all pipes are removed.\n\n

\n

If the destination is specified, but no pipe is set up for it, then\nthis is a no-op.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt',\n// but only for the first second\nreadable.pipe(writable);\nsetTimeout(() => {\n  console.log('stop writing to file.txt');\n  readable.unpipe(writable);\n  console.log('manually close the file stream');\n  writable.end();\n}, 1000);
\n" }, { "textRaw": "readable.unshift(chunk)", "type": "method", "name": "unshift", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} Chunk of data to unshift onto the read queue ", "name": "chunk", "type": "Buffer | String", "desc": "Chunk of data to unshift onto the read queue" } ] }, { "params": [ { "name": "chunk" } ] } ], "desc": "

This is useful in certain cases where a stream is being consumed by a\nparser, which needs to "un-consume" some data that it has\noptimistically pulled out of the source, so that the stream can be\npassed on to some other party.\n\n

\n

Note that stream.unshift(chunk) cannot be called after the 'end' event\nhas been triggered; a runtime error will be raised.\n\n

\n

If you find that you must often call stream.unshift(chunk) in your\nprograms, consider implementing a [Transform][] stream instead. (See API\nfor Stream Implementors, below.)\n\n

\n
// Pull off a header delimited by \\n\\n\n// use unshift() if we get too much\n// Call the callback with (error, header, stream)\nconst StringDecoder = require('string_decoder').StringDecoder;\nfunction parseHeader(stream, callback) {\n  stream.on('error', callback);\n  stream.on('readable', onReadable);\n  var decoder = new StringDecoder('utf8');\n  var header = '';\n  function onReadable() {\n    var chunk;\n    while (null !== (chunk = stream.read())) {\n      var str = decoder.write(chunk);\n      if (str.match(/\\n\\n/)) {\n        // found the header boundary\n        var split = str.split(/\\n\\n/);\n        header += split.shift();\n        var remaining = split.join('\\n\\n');\n        var buf = new Buffer(remaining, 'utf8');\n        if (buf.length)\n          stream.unshift(buf);\n        stream.removeListener('error', callback);\n        stream.removeListener('readable', onReadable);\n        // now the body of the message can be read from the stream.\n        callback(null, header, stream);\n      } else {\n        // still reading the header.\n        header += str;\n      }\n    }\n  }\n}
\n

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not\nend the reading process by resetting the internal reading state of the\nstream. This can cause unexpected results if unshift is called during a\nread (i.e. from within a _read implementation on a custom stream). Following\nthe call to unshift with an immediate stream.push('') will reset the\nreading state appropriately, however it is best to simply avoid calling\nunshift while in the process of performing a read.\n\n

\n" }, { "textRaw": "readable.wrap(stream)", "type": "method", "name": "wrap", "signatures": [ { "params": [ { "textRaw": "`stream` {Stream} An \"old style\" readable stream ", "name": "stream", "type": "Stream", "desc": "An \"old style\" readable stream" } ] }, { "params": [ { "name": "stream" } ] } ], "desc": "

Versions of Node.js prior to v0.10 had streams that did not implement the\nentire Streams API as it is today. (See "Compatibility" below for\nmore information.)\n\n

\n

If you are using an older Node.js library that emits 'data' events and\nhas a [pause()][] method that is advisory only, then you can use the\nwrap() method to create a [Readable][] stream that uses the old stream\nas its data source.\n\n

\n

You will very rarely ever need to call this function, but it exists\nas a convenience for interacting with old Node.js programs and libraries.\n\n

\n

For example:\n\n

\n
const OldReader = require('./old-api-module.js').OldReader;\nconst Readable = require('stream').Readable;\nconst oreader = new OldReader;\nconst myReader = new Readable().wrap(oreader);\n\nmyReader.on('readable', () => {\n  myReader.read(); // etc.\n});
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

Transform streams are [Duplex][] streams where the output is in some way\ncomputed from the input. They implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Transform streams include:\n\n

\n
    \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

The Writable stream interface is an abstraction for a destination\nthat you are writing data to.\n\n

\n

Examples of writable streams include:\n\n

\n
    \n
  • [http requests, on the client][]
  • \n
  • [http responses, on the server][]
  • \n
  • [fs write streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdin][]
  • \n
  • [process.stdout][], [process.stderr][]
  • \n
\n", "events": [ { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

If a [writable.write(chunk)][] call returns false, then the 'drain'\nevent will indicate when it is appropriate to begin writing more data\nto the stream.\n\n

\n
// Write the data to the supplied writable stream one million times.\n// Be attentive to back-pressure.\nfunction writeOneMillionTimes(writer, data, encoding, callback) {\n  var i = 1000000;\n  write();\n  function write() {\n    var ok = true;\n    do {\n      i -= 1;\n      if (i === 0) {\n        // last time!\n        writer.write(data, encoding, callback);\n      } else {\n        // see if we should continue, or wait\n        // don't pass the callback, because we're not done yet.\n        ok = writer.write(data, encoding);\n      }\n    } while (i > 0 && ok);\n    if (i > 0) {\n      // had to stop early!\n      // write some more once it drains\n      writer.once('drain', write);\n    }\n  }\n}
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error when writing or piping data.\n\n

\n" }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

When the [end()][] method has been called, and all data has been flushed\nto the underlying system, this event is emitted.\n\n

\n
var writer = getWritableStreamSomehow();\nfor (var i = 0; i < 100; i ++) {\n  writer.write('hello, #${i}!\\n');\n}\nwriter.end('this is the end\\n');\nwriter.on('finish', () => {\n  console.error('all writes are now complete.');\n});
\n", "params": [] }, { "textRaw": "Event: 'pipe'", "type": "event", "name": "pipe", "params": [], "desc": "

This is emitted whenever the pipe() method is called on a readable\nstream, adding this writable to its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('pipe', (src) => {\n  console.error('something is piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);
\n" }, { "textRaw": "Event: 'unpipe'", "type": "event", "name": "unpipe", "params": [], "desc": "

This is emitted whenever the [unpipe()][] method is called on a\nreadable stream, removing this writable from its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('unpipe', (src) => {\n  console.error('something has stopped piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);\nreader.unpipe(writer);
\n" } ], "methods": [ { "textRaw": "writable.cork()", "type": "method", "name": "cork", "desc": "

Forces buffering of all writes.\n\n

\n

Buffered data will be flushed either at .uncork() or at .end() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.end([chunk][, encoding][, callback])", "type": "method", "name": "end", "signatures": [ { "params": [ { "textRaw": "`chunk` {String | Buffer} Optional data to write ", "name": "chunk", "type": "String | Buffer", "desc": "Optional data to write", "optional": true }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Optional callback for when the stream is finished ", "name": "callback", "type": "Function", "desc": "Optional callback for when the stream is finished", "optional": true } ] }, { "params": [ { "name": "chunk", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Call this method when no more data will be written to the stream. If\nsupplied, the callback is attached as a listener on the 'finish' event.\n\n

\n

Calling [write()][] after calling [end()][] will raise an error.\n\n

\n
// write 'hello, ' and then end with 'world!'\nvar file = fs.createWriteStream('example.txt');\nfile.write('hello, ');\nfile.end('world!');\n// writing more now is not allowed!
\n" }, { "textRaw": "writable.setDefaultEncoding(encoding)", "type": "method", "name": "setDefaultEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The new default encoding ", "name": "encoding", "type": "String", "desc": "The new default encoding" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Sets the default encoding for a writable stream.\n\n

\n" }, { "textRaw": "writable.uncork()", "type": "method", "name": "uncork", "desc": "

Flush all data, buffered since .cork() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "signatures": [ { "return": { "textRaw": "Returns: {Boolean} True if the data was handled completely. ", "name": "return", "type": "Boolean", "desc": "True if the data was handled completely." }, "params": [ { "textRaw": "`chunk` {String | Buffer} The data to write ", "name": "chunk", "type": "String | Buffer", "desc": "The data to write" }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Callback for when this chunk of data is flushed ", "name": "callback", "type": "Function", "desc": "Callback for when this chunk of data is flushed", "optional": true } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This method writes some data to the underlying system, and calls the\nsupplied callback once the data has been fully handled.\n\n

\n

The return value indicates if you should continue writing right now.\nIf the data had to be buffered internally, then it will return\nfalse. Otherwise, it will return true.\n\n

\n

This return value is strictly advisory. You MAY continue to write,\neven if it returns false. However, writes will be buffered in\nmemory, so it is best not to do this excessively. Instead, wait for\nthe 'drain' event before writing more data.\n\n\n

\n" } ] } ], "miscs": [ { "textRaw": "API for Stream Consumers", "name": "API for Stream Consumers", "type": "misc", "desc": "

Streams can be either [Readable][], [Writable][], or both ([Duplex][]).\n\n

\n

All streams are EventEmitters, but they also have other custom methods\nand properties depending on whether they are Readable, Writable, or\nDuplex.\n\n

\n

If a stream is both Readable and Writable, then it implements all of\nthe methods and events below. So, a [Duplex][] or [Transform][] stream is\nfully described by this API, though their implementation may be\nsomewhat different.\n\n

\n

It is not necessary to implement Stream interfaces in order to consume\nstreams in your programs. If you are implementing streaming\ninterfaces in your own program, please also refer to\n[API for Stream Implementors][] below.\n\n

\n

Almost all Node.js programs, no matter how simple, use Streams in some\nway. Here is an example of using Streams in an Node.js program:\n\n

\n
const http = require('http');\n\nvar server = http.createServer( (req, res) => {\n  // req is an http.IncomingMessage, which is a Readable Stream\n  // res is an http.ServerResponse, which is a Writable Stream\n\n  var body = '';\n  // we want to get the data as utf8 strings\n  // If you don't set an encoding, then you'll get Buffer objects\n  req.setEncoding('utf8');\n\n  // Readable streams emit 'data' events once a listener is added\n  req.on('data', (chunk) => {\n    body += chunk;\n  });\n\n  // the end event tells you that you have entire body\n  req.on('end', () => {\n    try {\n      var data = JSON.parse(body);\n    } catch (er) {\n      // uh oh!  bad json!\n      res.statusCode = 400;\n      return res.end(`error: ${er.message}`);\n    }\n\n    // write back something interesting to the user:\n    res.write(typeof data);\n    res.end();\n  });\n});\n\nserver.listen(1337);\n\n// $ curl localhost:1337 -d '{}'\n// object\n// $ curl localhost:1337 -d '"foo"'\n// string\n// $ curl localhost:1337 -d 'not json'\n// error: Unexpected token o
\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

Duplex streams are streams that implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Duplex streams include:\n\n

\n
    \n
  • [tcp sockets][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

The Readable stream interface is the abstraction for a source of\ndata that you are reading from. In other words, data comes out of a\nReadable stream.\n\n

\n

A Readable stream will not start emitting data until you indicate that\nyou are ready to receive it.\n\n

\n

Readable streams have two "modes": a flowing mode and a paused\nmode. When in flowing mode, data is read from the underlying system\nand provided to your program as fast as possible. In paused mode, you\nmust explicitly call stream.read() to get chunks of data out.\nStreams start out in paused mode.\n\n

\n

Note: If no data event handlers are attached, and there are no\n[pipe()][] destinations, and the stream is switched into flowing\nmode, then data will be lost.\n\n

\n

You can switch to flowing mode by doing any of the following:\n\n

\n
    \n
  • Adding a ['data'][] event handler to listen for data.
  • \n
  • Calling the [resume()][] method to explicitly open the flow.
  • \n
  • Calling the [pipe()][] method to send the data to a [Writable][].
  • \n
\n

You can switch back to paused mode by doing either of the following:\n\n

\n
    \n
  • If there are no pipe destinations, by calling the [pause()][]\nmethod.
  • \n
  • If there are pipe destinations, by removing any ['data'][] event\nhandlers, and removing all pipe destinations by calling the\n[unpipe()][] method.
  • \n
\n

Note that, for backwards compatibility reasons, removing 'data'\nevent handlers will not automatically pause the stream. Also, if\nthere are piped destinations, then calling pause() will not\nguarantee that the stream will remain paused once those\ndestinations drain and ask for more data.\n\n

\n

Examples of readable streams include:\n\n

\n
    \n
  • [http responses, on the client][]
  • \n
  • [http requests, on the server][]
  • \n
  • [fs read streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdout and stderr][]
  • \n
  • [process.stdin][]
  • \n
\n", "events": [ { "textRaw": "Event: 'close'", "type": "event", "name": "close", "desc": "

Emitted when the stream and any of its underlying resources (a file\ndescriptor, for example) have been closed. The event indicates that\nno more events will be emitted, and no further computation will occur.\n\n

\n

Not all streams will emit the 'close' event.\n\n

\n", "params": [] }, { "textRaw": "Event: 'data'", "type": "event", "name": "data", "params": [], "desc": "

Attaching a 'data' event listener to a stream that has not been\nexplicitly paused will switch the stream into flowing mode. Data will\nthen be passed as soon as it is available.\n\n

\n

If you just want to get all the data out of the stream as fast as\npossible, this is the best way to do so.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});
\n" }, { "textRaw": "Event: 'end'", "type": "event", "name": "end", "desc": "

This event fires when there will be no more data to read.\n\n

\n

Note that the 'end' event will not fire unless the data is\ncompletely consumed. This can be done by switching into flowing mode,\nor by calling read() repeatedly until you get to the end.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n});\nreadable.on('end', () => {\n  console.log('there will be no more data.');\n});
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error receiving data.\n\n

\n" }, { "textRaw": "Event: 'readable'", "type": "event", "name": "readable", "desc": "

When a chunk of data can be read from the stream, it will emit a\n'readable' event.\n\n

\n

In some cases, listening for a 'readable' event will cause some data\nto be read into the internal buffer from the underlying system, if it\nhadn't already.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  // there is some data to read now\n});
\n

Once the internal buffer is drained, a 'readable' event will fire\nagain when more data is available.\n\n

\n

The 'readable' event is not emitted in the "flowing" mode with the\nsole exception of the last one, on end-of-stream.\n\n

\n

The 'readable' event indicates that the stream has new information:\neither new data is available or the end of the stream has been reached.\nIn the former case, .read() will return that data. In the latter case,\n.read() will return null. For instance, in the following example, foo.txt\nis an empty file:\n\n

\n
const fs = require('fs');\nvar rr = fs.createReadStream('foo.txt');\nrr.on('readable', () => {\n  console.log('readable:', rr.read());\n});\nrr.on('end', () => {\n  console.log('end');\n});
\n

The output of running this script is:\n\n

\n
bash-3.2$ node test.js\nreadable: null\nend
\n", "params": [] } ], "methods": [ { "textRaw": "readable.isPaused()", "type": "method", "name": "isPaused", "signatures": [ { "return": { "textRaw": "Return: `Boolean` ", "name": "return", "desc": "`Boolean`" }, "params": [] }, { "params": [] } ], "desc": "

This method returns whether or not the readable has been explicitly\npaused by client code (using readable.pause() without a corresponding\nreadable.resume()).\n\n

\n
var readable = new stream.Readable\n\nreadable.isPaused() // === false\nreadable.pause()\nreadable.isPaused() // === true\nreadable.resume()\nreadable.isPaused() // === false
\n" }, { "textRaw": "readable.pause()", "type": "method", "name": "pause", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause a stream in flowing mode to stop emitting\n'data' events, switching out of flowing mode. Any data that becomes\navailable will remain in the internal buffer.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('data', (chunk) => {\n  console.log('got %d bytes of data', chunk.length);\n  readable.pause();\n  console.log('there will be no more data for 1 second');\n  setTimeout(() => {\n    console.log('now data will start flowing again');\n    readable.resume();\n  }, 1000);\n});
\n" }, { "textRaw": "readable.pipe(destination[, options])", "type": "method", "name": "pipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} The destination for writing data ", "name": "destination", "type": "[Writable][] Stream", "desc": "The destination for writing data" }, { "textRaw": "`options` {Object} Pipe options ", "options": [ { "textRaw": "`end` {Boolean} End the writer when the reader ends. Default = `true` ", "name": "end", "type": "Boolean", "desc": "End the writer when the reader ends. Default = `true`" } ], "name": "options", "type": "Object", "desc": "Pipe options", "optional": true } ] }, { "params": [ { "name": "destination" }, { "name": "options", "optional": true } ] } ], "desc": "

This method pulls all the data out of a readable stream, and writes it\nto the supplied destination, automatically managing the flow so that\nthe destination is not overwhelmed by a fast readable stream.\n\n

\n

Multiple destinations can be piped to safely.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt'\nreadable.pipe(writable);
\n

This function returns the destination stream, so you can set up pipe\nchains like so:\n\n

\n
var r = fs.createReadStream('file.txt');\nvar z = zlib.createGzip();\nvar w = fs.createWriteStream('file.txt.gz');\nr.pipe(z).pipe(w);
\n

For example, emulating the Unix cat command:\n\n

\n
process.stdin.pipe(process.stdout);
\n

By default [end()][] is called on the destination when the source stream\nemits end, so that destination is no longer writable. Pass { end:\nfalse } as options to keep the destination stream open.\n\n

\n

This keeps writer open so that "Goodbye" can be written at the\nend.\n\n

\n
reader.pipe(writer, { end: false });\nreader.on('end', () => {\n  writer.end('Goodbye\\n');\n});
\n

Note that process.stderr and process.stdout are never closed until\nthe process exits, regardless of the specified options.\n\n

\n" }, { "textRaw": "readable.read([size])", "type": "method", "name": "read", "signatures": [ { "return": { "textRaw": "Return {String | Buffer | null} ", "name": "return", "type": "String | Buffer | null" }, "params": [ { "textRaw": "`size` {Number} Optional argument to specify how much data to read. ", "name": "size", "type": "Number", "desc": "Optional argument to specify how much data to read.", "optional": true } ] }, { "params": [ { "name": "size", "optional": true } ] } ], "desc": "

The read() method pulls some data out of the internal buffer and\nreturns it. If there is no data available, then it will return\nnull.\n\n

\n

If you pass in a size argument, then it will return that many\nbytes. If size bytes are not available, then it will return null,\nunless we've ended, in which case it will return the data remaining\nin the buffer.\n\n

\n

If you do not specify a size argument, then it will return all the\ndata in the internal buffer.\n\n

\n

This method should only be called in paused mode. In flowing mode,\nthis method is called automatically until the internal buffer is\ndrained.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.on('readable', () => {\n  var chunk;\n  while (null !== (chunk = readable.read())) {\n    console.log('got %d bytes of data', chunk.length);\n  }\n});
\n

If this method returns a data chunk, then it will also trigger the\nemission of a ['data'][] event.\n\n

\n

Note that calling readable.read([size]) after the 'end' event has been\ntriggered will return null. No runtime error will be raised.\n\n

\n" }, { "textRaw": "readable.resume()", "type": "method", "name": "resume", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [] }, { "params": [] } ], "desc": "

This method will cause the readable stream to resume emitting data\nevents.\n\n

\n

This method will switch the stream into flowing mode. If you do not\nwant to consume the data from a stream, but you do want to get to\nits 'end' event, you can call [readable.resume()][] to open the flow of\ndata.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.resume();\nreadable.on('end', () => {\n  console.log('got to the end, but did not read anything');\n});
\n" }, { "textRaw": "readable.setEncoding(encoding)", "type": "method", "name": "setEncoding", "signatures": [ { "return": { "textRaw": "Return: `this` ", "name": "return", "desc": "`this`" }, "params": [ { "textRaw": "`encoding` {String} The encoding to use. ", "name": "encoding", "type": "String", "desc": "The encoding to use." } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Call this function to cause the stream to return strings of the\nspecified encoding instead of Buffer objects. For example, if you do\nreadable.setEncoding('utf8'), then the output data will be\ninterpreted as UTF-8 data, and returned as strings. If you do\nreadable.setEncoding('hex'), then the data will be encoded in\nhexadecimal string format.\n\n

\n

This properly handles multi-byte characters that would otherwise be\npotentially mangled if you simply pulled the Buffers directly and\ncalled buf.toString(encoding) on them. If you want to read the data\nas strings, always use this method.\n\n

\n
var readable = getReadableStreamSomehow();\nreadable.setEncoding('utf8');\nreadable.on('data', (chunk) => {\n  assert.equal(typeof chunk, 'string');\n  console.log('got %d characters of string data', chunk.length);\n});
\n" }, { "textRaw": "readable.unpipe([destination])", "type": "method", "name": "unpipe", "signatures": [ { "params": [ { "textRaw": "`destination` {[Writable][] Stream} Optional specific stream to unpipe ", "name": "destination", "type": "[Writable][] Stream", "desc": "Optional specific stream to unpipe", "optional": true } ] }, { "params": [ { "name": "destination", "optional": true } ] } ], "desc": "

This method will remove the hooks set up for a previous pipe() call.\n\n

\n

If the destination is not specified, then all pipes are removed.\n\n

\n

If the destination is specified, but no pipe is set up for it, then\nthis is a no-op.\n\n

\n
var readable = getReadableStreamSomehow();\nvar writable = fs.createWriteStream('file.txt');\n// All the data from readable goes into 'file.txt',\n// but only for the first second\nreadable.pipe(writable);\nsetTimeout(() => {\n  console.log('stop writing to file.txt');\n  readable.unpipe(writable);\n  console.log('manually close the file stream');\n  writable.end();\n}, 1000);
\n" }, { "textRaw": "readable.unshift(chunk)", "type": "method", "name": "unshift", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} Chunk of data to unshift onto the read queue ", "name": "chunk", "type": "Buffer | String", "desc": "Chunk of data to unshift onto the read queue" } ] }, { "params": [ { "name": "chunk" } ] } ], "desc": "

This is useful in certain cases where a stream is being consumed by a\nparser, which needs to "un-consume" some data that it has\noptimistically pulled out of the source, so that the stream can be\npassed on to some other party.\n\n

\n

Note that stream.unshift(chunk) cannot be called after the 'end' event\nhas been triggered; a runtime error will be raised.\n\n

\n

If you find that you must often call stream.unshift(chunk) in your\nprograms, consider implementing a [Transform][] stream instead. (See API\nfor Stream Implementors, below.)\n\n

\n
// Pull off a header delimited by \\n\\n\n// use unshift() if we get too much\n// Call the callback with (error, header, stream)\nconst StringDecoder = require('string_decoder').StringDecoder;\nfunction parseHeader(stream, callback) {\n  stream.on('error', callback);\n  stream.on('readable', onReadable);\n  var decoder = new StringDecoder('utf8');\n  var header = '';\n  function onReadable() {\n    var chunk;\n    while (null !== (chunk = stream.read())) {\n      var str = decoder.write(chunk);\n      if (str.match(/\\n\\n/)) {\n        // found the header boundary\n        var split = str.split(/\\n\\n/);\n        header += split.shift();\n        var remaining = split.join('\\n\\n');\n        var buf = new Buffer(remaining, 'utf8');\n        if (buf.length)\n          stream.unshift(buf);\n        stream.removeListener('error', callback);\n        stream.removeListener('readable', onReadable);\n        // now the body of the message can be read from the stream.\n        callback(null, header, stream);\n      } else {\n        // still reading the header.\n        header += str;\n      }\n    }\n  }\n}
\n

Note that, unlike stream.push(chunk), stream.unshift(chunk) will not\nend the reading process by resetting the internal reading state of the\nstream. This can cause unexpected results if unshift is called during a\nread (i.e. from within a _read implementation on a custom stream). Following\nthe call to unshift with an immediate stream.push('') will reset the\nreading state appropriately, however it is best to simply avoid calling\nunshift while in the process of performing a read.\n\n

\n" }, { "textRaw": "readable.wrap(stream)", "type": "method", "name": "wrap", "signatures": [ { "params": [ { "textRaw": "`stream` {Stream} An \"old style\" readable stream ", "name": "stream", "type": "Stream", "desc": "An \"old style\" readable stream" } ] }, { "params": [ { "name": "stream" } ] } ], "desc": "

Versions of Node.js prior to v0.10 had streams that did not implement the\nentire Streams API as it is today. (See "Compatibility" below for\nmore information.)\n\n

\n

If you are using an older Node.js library that emits 'data' events and\nhas a [pause()][] method that is advisory only, then you can use the\nwrap() method to create a [Readable][] stream that uses the old stream\nas its data source.\n\n

\n

You will very rarely ever need to call this function, but it exists\nas a convenience for interacting with old Node.js programs and libraries.\n\n

\n

For example:\n\n

\n
const OldReader = require('./old-api-module.js').OldReader;\nconst Readable = require('stream').Readable;\nconst oreader = new OldReader;\nconst myReader = new Readable().wrap(oreader);\n\nmyReader.on('readable', () => {\n  myReader.read(); // etc.\n});
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

Transform streams are [Duplex][] streams where the output is in some way\ncomputed from the input. They implement both the [Readable][] and\n[Writable][] interfaces. See above for usage.\n\n

\n

Examples of Transform streams include:\n\n

\n
    \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
\n" }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

The Writable stream interface is an abstraction for a destination\nthat you are writing data to.\n\n

\n

Examples of writable streams include:\n\n

\n
    \n
  • [http requests, on the client][]
  • \n
  • [http responses, on the server][]
  • \n
  • [fs write streams][]
  • \n
  • [zlib streams][]
  • \n
  • [crypto streams][]
  • \n
  • [tcp sockets][]
  • \n
  • [child process stdin][]
  • \n
  • [process.stdout][], [process.stderr][]
  • \n
\n", "events": [ { "textRaw": "Event: 'drain'", "type": "event", "name": "drain", "desc": "

If a [writable.write(chunk)][] call returns false, then the 'drain'\nevent will indicate when it is appropriate to begin writing more data\nto the stream.\n\n

\n
// Write the data to the supplied writable stream one million times.\n// Be attentive to back-pressure.\nfunction writeOneMillionTimes(writer, data, encoding, callback) {\n  var i = 1000000;\n  write();\n  function write() {\n    var ok = true;\n    do {\n      i -= 1;\n      if (i === 0) {\n        // last time!\n        writer.write(data, encoding, callback);\n      } else {\n        // see if we should continue, or wait\n        // don't pass the callback, because we're not done yet.\n        ok = writer.write(data, encoding);\n      }\n    } while (i > 0 && ok);\n    if (i > 0) {\n      // had to stop early!\n      // write some more once it drains\n      writer.once('drain', write);\n    }\n  }\n}
\n", "params": [] }, { "textRaw": "Event: 'error'", "type": "event", "name": "error", "params": [], "desc": "

Emitted if there was an error when writing or piping data.\n\n

\n" }, { "textRaw": "Event: 'finish'", "type": "event", "name": "finish", "desc": "

When the [end()][] method has been called, and all data has been flushed\nto the underlying system, this event is emitted.\n\n

\n
var writer = getWritableStreamSomehow();\nfor (var i = 0; i < 100; i ++) {\n  writer.write('hello, #${i}!\\n');\n}\nwriter.end('this is the end\\n');\nwriter.on('finish', () => {\n  console.error('all writes are now complete.');\n});
\n", "params": [] }, { "textRaw": "Event: 'pipe'", "type": "event", "name": "pipe", "params": [], "desc": "

This is emitted whenever the pipe() method is called on a readable\nstream, adding this writable to its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('pipe', (src) => {\n  console.error('something is piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);
\n" }, { "textRaw": "Event: 'unpipe'", "type": "event", "name": "unpipe", "params": [], "desc": "

This is emitted whenever the [unpipe()][] method is called on a\nreadable stream, removing this writable from its set of destinations.\n\n

\n
var writer = getWritableStreamSomehow();\nvar reader = getReadableStreamSomehow();\nwriter.on('unpipe', (src) => {\n  console.error('something has stopped piping into the writer');\n  assert.equal(src, reader);\n});\nreader.pipe(writer);\nreader.unpipe(writer);
\n" } ], "methods": [ { "textRaw": "writable.cork()", "type": "method", "name": "cork", "desc": "

Forces buffering of all writes.\n\n

\n

Buffered data will be flushed either at .uncork() or at .end() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.end([chunk][, encoding][, callback])", "type": "method", "name": "end", "signatures": [ { "params": [ { "textRaw": "`chunk` {String | Buffer} Optional data to write ", "name": "chunk", "type": "String | Buffer", "desc": "Optional data to write", "optional": true }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Optional callback for when the stream is finished ", "name": "callback", "type": "Function", "desc": "Optional callback for when the stream is finished", "optional": true } ] }, { "params": [ { "name": "chunk", "optional": true }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

Call this method when no more data will be written to the stream. If\nsupplied, the callback is attached as a listener on the 'finish' event.\n\n

\n

Calling [write()][] after calling [end()][] will raise an error.\n\n

\n
// write 'hello, ' and then end with 'world!'\nvar file = fs.createWriteStream('example.txt');\nfile.write('hello, ');\nfile.end('world!');\n// writing more now is not allowed!
\n" }, { "textRaw": "writable.setDefaultEncoding(encoding)", "type": "method", "name": "setDefaultEncoding", "signatures": [ { "params": [ { "textRaw": "`encoding` {String} The new default encoding ", "name": "encoding", "type": "String", "desc": "The new default encoding" } ] }, { "params": [ { "name": "encoding" } ] } ], "desc": "

Sets the default encoding for a writable stream.\n\n

\n" }, { "textRaw": "writable.uncork()", "type": "method", "name": "uncork", "desc": "

Flush all data, buffered since .cork() call.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "writable.write(chunk[, encoding][, callback])", "type": "method", "name": "write", "signatures": [ { "return": { "textRaw": "Returns: {Boolean} True if the data was handled completely. ", "name": "return", "type": "Boolean", "desc": "True if the data was handled completely." }, "params": [ { "textRaw": "`chunk` {String | Buffer} The data to write ", "name": "chunk", "type": "String | Buffer", "desc": "The data to write" }, { "textRaw": "`encoding` {String} The encoding, if `chunk` is a String ", "name": "encoding", "type": "String", "desc": "The encoding, if `chunk` is a String", "optional": true }, { "textRaw": "`callback` {Function} Callback for when this chunk of data is flushed ", "name": "callback", "type": "Function", "desc": "Callback for when this chunk of data is flushed", "optional": true } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding", "optional": true }, { "name": "callback", "optional": true } ] } ], "desc": "

This method writes some data to the underlying system, and calls the\nsupplied callback once the data has been fully handled.\n\n

\n

The return value indicates if you should continue writing right now.\nIf the data had to be buffered internally, then it will return\nfalse. Otherwise, it will return true.\n\n

\n

This return value is strictly advisory. You MAY continue to write,\neven if it returns false. However, writes will be buffered in\nmemory, so it is best not to do this excessively. Instead, wait for\nthe 'drain' event before writing more data.\n\n\n

\n" } ] } ] }, { "textRaw": "API for Stream Implementors", "name": "API for Stream Implementors", "type": "misc", "desc": "

To implement any sort of stream, the pattern is the same:\n\n

\n
    \n
  1. Extend the appropriate parent class in your own subclass. (The\n[util.inherits][] method is particularly helpful for this.)
  2. \n
  3. Call the appropriate parent class constructor in your constructor,\nto be sure that the internal mechanisms are set up properly.
  4. \n
  5. Implement one or more specific methods, as detailed below.
  6. \n
\n

The class to extend and the method(s) to implement depend on the sort\nof stream class you are writing:\n\n

\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n

Use-case

\n
\n

Class

\n
\n

Method(s) to implement

\n
\n

Reading only

\n
\n

Readable

\n
\n

[_read][]

\n
\n

Writing only

\n
\n

Writable

\n
\n

[_write][], [_writev][]

\n
\n

Reading and writing

\n
\n

Duplex

\n
\n

[_read][], [_write][], [_writev][]

\n
\n

Operate on written data, then read the result

\n
\n

Transform

\n
\n

[_transform][], [_flush][]

\n
\n\n

In your implementation code, it is very important to never call the\nmethods described in [API for Stream Consumers][] above. Otherwise, you\ncan potentially cause adverse side effects in programs that consume\nyour streaming interfaces.\n\n

\n", "classes": [ { "textRaw": "Class: stream.Duplex", "type": "class", "name": "stream.Duplex", "desc": "

A "duplex" stream is one that is both Readable and Writable, such as a\nTCP socket connection.\n\n

\n

Note that stream.Duplex is an abstract class designed to be extended\nwith an underlying implementation of the _read(size) and\n[_write(chunk, encoding, callback)][] methods as you would with a\nReadable or Writable stream class.\n\n

\n

Since JavaScript doesn't have multiple prototypal inheritance, this\nclass prototypally inherits from Readable, and then parasitically from\nWritable. It is thus up to the user to implement both the lowlevel\n_read(n) method as well as the lowlevel\n[_write(chunk, encoding, callback)][] method on extension duplex classes.\n\n

\n", "methods": [ { "textRaw": "new stream.Duplex(options)", "type": "method", "name": "Duplex", "signatures": [ { "params": [ { "textRaw": "`options` {Object} Passed to both Writable and Readable constructors. Also has the following fields: ", "options": [ { "textRaw": "`allowHalfOpen` {Boolean} Default=true. If set to `false`, then the stream will automatically end the readable side when the writable side ends and vice versa. ", "name": "allowHalfOpen", "type": "Boolean", "desc": "Default=true. If set to `false`, then the stream will automatically end the readable side when the writable side ends and vice versa." }, { "textRaw": "`readableObjectMode` {Boolean} Default=false. Sets `objectMode` for readable side of the stream. Has no effect if `objectMode` is `true`. ", "name": "readableObjectMode", "type": "Boolean", "desc": "Default=false. Sets `objectMode` for readable side of the stream. Has no effect if `objectMode` is `true`." }, { "textRaw": "`writableObjectMode` {Boolean} Default=false. Sets `objectMode` for writable side of the stream. Has no effect if `objectMode` is `true`. ", "name": "writableObjectMode", "type": "Boolean", "desc": "Default=false. Sets `objectMode` for writable side of the stream. Has no effect if `objectMode` is `true`." } ], "name": "options", "type": "Object", "desc": "Passed to both Writable and Readable constructors. Also has the following fields:" } ] }, { "params": [ { "name": "options" } ] } ], "desc": "

In classes that extend the Duplex class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" } ] }, { "textRaw": "Class: stream.PassThrough", "type": "class", "name": "stream.PassThrough", "desc": "

This is a trivial implementation of a [Transform][] stream that simply\npasses the input bytes across to the output. Its purpose is mainly\nfor examples and testing, but there are occasionally use cases where\nit can come in handy as a building block for novel sorts of streams.\n\n

\n" }, { "textRaw": "Class: stream.Readable", "type": "class", "name": "stream.Readable", "desc": "

stream.Readable is an abstract class designed to be extended with an\nunderlying implementation of the [_read(size)][] method.\n\n

\n

Please see above under [API for Stream Consumers][] for how to consume\nstreams in your programs. What follows is an explanation of how to\nimplement Readable streams in your programs.\n\n

\n", "methods": [ { "textRaw": "new stream.Readable([options])", "type": "method", "name": "Readable", "signatures": [ { "params": [ { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`highWaterMark` {Number} The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for `objectMode` streams ", "name": "highWaterMark", "type": "Number", "desc": "The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for `objectMode` streams" }, { "textRaw": "`encoding` {String} If specified, then buffers will be decoded to strings using the specified encoding. Default=null ", "name": "encoding", "type": "String", "desc": "If specified, then buffers will be decoded to strings using the specified encoding. Default=null" }, { "textRaw": "`objectMode` {Boolean} Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false ", "name": "objectMode", "type": "Boolean", "desc": "Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Readable class, make sure to call the\nReadable constructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "readable.\\_read(size)", "type": "method", "name": "\\_read", "signatures": [ { "params": [ { "textRaw": "`size` {Number} Number of bytes to read asynchronously ", "name": "size", "type": "Number", "desc": "Number of bytes to read asynchronously" } ] }, { "params": [ { "name": "size" } ] } ], "desc": "

Note: Implement this method, but do NOT call it directly.\n\n

\n

This method is prefixed with an underscore because it is internal to the\nclass that defines it and should only be called by the internal Readable\nclass methods. All Readable stream implementations must provide a _read\nmethod to fetch data from the underlying resource.\n\n

\n

When _read is called, if data is available from the resource, _read should\nstart pushing that data into the read queue by calling this.push(dataChunk).\n_read should continue reading from the resource and pushing data until push\nreturns false, at which point it should stop reading from the resource. Only\nwhen _read is called again after it has stopped should it start reading\nmore data from the resource and pushing that data onto the queue.\n\n

\n

Note: once the _read() method is called, it will not be called again until\nthe push method is called.\n\n

\n

The size argument is advisory. Implementations where a "read" is a\nsingle call that returns data can use this to know how much data to\nfetch. Implementations where that is not relevant, such as TCP or\nTLS, may ignore this argument, and simply provide data whenever it\nbecomes available. There is no need, for example to "wait" until\nsize bytes are available before calling [stream.push(chunk)][].\n\n

\n" } ], "examples": [ { "textRaw": "readable.push(chunk[, encoding])", "type": "example", "name": "push", "signatures": [ { "return": { "textRaw": "return {Boolean} Whether or not more pushes should be performed ", "name": "return", "type": "Boolean", "desc": "Whether or not more pushes should be performed" }, "params": [ { "textRaw": "`chunk` {Buffer | null | String} Chunk of data to push into the read queue ", "name": "chunk", "type": "Buffer | null | String", "desc": "Chunk of data to push into the read queue" }, { "textRaw": "`encoding` {String} Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'` ", "name": "encoding", "type": "String", "desc": "Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'`", "optional": true } ] } ], "desc": "

Note: This method should be called by Readable implementors, NOT\nby consumers of Readable streams.\n\n

\n

If a value other than null is passed, The push() method adds a chunk of data\ninto the queue for subsequent stream processors to consume. If null is\npassed, it signals the end of the stream (EOF), after which no more data\ncan be written.\n\n

\n

The data added with push can be pulled out by calling the read() method\nwhen the 'readable' event fires.\n\n

\n

This API is designed to be as flexible as possible. For example,\nyou may be wrapping a lower-level source which has some sort of\npause/resume mechanism, and a data callback. In those cases, you\ncould wrap the low-level source object by doing something like this:\n\n

\n
// source is an object with readStop() and readStart() methods,\n// and an `ondata` member that gets called when it has data, and\n// an `onend` member that gets called when the data is over.\n\nutil.inherits(SourceWrapper, Readable);\n\nfunction SourceWrapper(options) {\n  Readable.call(this, options);\n\n  this._source = getLowlevelSourceObject();\n  var self = this;\n\n  // Every time there's data, we push it into the internal buffer.\n  this._source.ondata = function(chunk) {\n    // if push() returns false, then we need to stop reading from source\n    if (!self.push(chunk))\n      self._source.readStop();\n  };\n\n  // When the source ends, we push the EOF-signaling `null` chunk\n  this._source.onend = function() {\n    self.push(null);\n  };\n}\n\n// _read will be called when the stream wants to pull more data in\n// the advisory size argument is ignored in this case.\nSourceWrapper.prototype._read = function(size) {\n  this._source.readStart();\n};
\n

Example: A Counting Stream

\n

This is a basic example of a Readable stream. It emits the numerals\nfrom 1 to 1,000,000 in ascending order, and then ends.\n\n

\n
const Readable = require('stream').Readable;\nconst util = require('util');\nutil.inherits(Counter, Readable);\n\nfunction Counter(opt) {\n  Readable.call(this, opt);\n  this._max = 1000000;\n  this._index = 1;\n}\n\nCounter.prototype._read = function() {\n  var i = this._index++;\n  if (i > this._max)\n    this.push(null);\n  else {\n    var str = '' + i;\n    var buf = new Buffer(str, 'ascii');\n    this.push(buf);\n  }\n};
\n

Example: SimpleProtocol v1 (Sub-optimal)

\n

This is similar to the parseHeader function described above, but\nimplemented as a custom stream. Also, note that this implementation\ndoes not convert the incoming data to a string.\n\n

\n

However, this would be better implemented as a [Transform][] stream. See\nbelow for a better implementation.\n\n

\n
// A parser for a simple data protocol.\n// The "header" is a JSON object, followed by 2 \\n characters, and\n// then a message body.\n//\n// NOTE: This can be done more simply as a Transform stream!\n// Using Readable directly for this is sub-optimal.  See the\n// alternative example below under the Transform section.\n\nconst Readable = require('stream').Readable;\nconst util = require('util');\n\nutil.inherits(SimpleProtocol, Readable);\n\nfunction SimpleProtocol(source, options) {\n  if (!(this instanceof SimpleProtocol))\n    return new SimpleProtocol(source, options);\n\n  Readable.call(this, options);\n  this._inBody = false;\n  this._sawFirstCr = false;\n\n  // source is a readable stream, such as a socket or file\n  this._source = source;\n\n  var self = this;\n  source.on('end', () => {\n    self.push(null);\n  });\n\n  // give it a kick whenever the source is readable\n  // read(0) will not consume any bytes\n  source.on('readable', () => {\n    self.read(0);\n  });\n\n  this._rawHeader = [];\n  this.header = null;\n}\n\nSimpleProtocol.prototype._read = function(n) {\n  if (!this._inBody) {\n    var chunk = this._source.read();\n\n    // if the source doesn't have data, we don't have data yet.\n    if (chunk === null)\n      return this.push('');\n\n    // check if the chunk has a \\n\\n\n    var split = -1;\n    for (var i = 0; i < chunk.length; i++) {\n      if (chunk[i] === 10) { // '\\n'\n        if (this._sawFirstCr) {\n          split = i;\n          break;\n        } else {\n          this._sawFirstCr = true;\n        }\n      } else {\n        this._sawFirstCr = false;\n      }\n    }\n\n    if (split === -1) {\n      // still waiting for the \\n\\n\n      // stash the chunk, and try again.\n      this._rawHeader.push(chunk);\n      this.push('');\n    } else {\n      this._inBody = true;\n      var h = chunk.slice(0, split);\n      this._rawHeader.push(h);\n      var header = Buffer.concat(this._rawHeader).toString();\n      try {\n        this.header = JSON.parse(header);\n      } catch (er) {\n        this.emit('error', new Error('invalid simple protocol data'));\n        return;\n      }\n      // now, because we got some extra data, unshift the rest\n      // back into the read queue so that our consumer will see it.\n      var b = chunk.slice(split);\n      this.unshift(b);\n      // calling unshift by itself does not reset the reading state\n      // of the stream; since we're inside _read, doing an additional\n      // push('') will reset the state appropriately.\n      this.push('');\n\n      // and let them know that we are done parsing the header.\n      this.emit('header', this.header);\n    }\n  } else {\n    // from there on, just provide the data to our consumer.\n    // careful not to push(null), since that would indicate EOF.\n    var chunk = this._source.read();\n    if (chunk) this.push(chunk);\n  }\n};\n\n// Usage:\n// var parser = new SimpleProtocol(source);\n// Now parser is a readable stream that will emit 'header'\n// with the parsed header data.
\n" } ] }, { "textRaw": "Class: stream.Transform", "type": "class", "name": "stream.Transform", "desc": "

A "transform" stream is a duplex stream where the output is causally\nconnected in some way to the input, such as a [zlib][] stream or a\n[crypto][] stream.\n\n

\n

There is no requirement that the output be the same size as the input,\nthe same number of chunks, or arrive at the same time. For example, a\nHash stream will only ever have a single chunk of output which is\nprovided when the input is ended. A zlib stream will produce output\nthat is either much smaller or much larger than its input.\n\n

\n

Rather than implement the [_read()][] and [_write()][] methods, Transform\nclasses must implement the _transform() method, and may optionally\nalso implement the _flush() method. (See below.)\n\n

\n", "methods": [ { "textRaw": "new stream.Transform([options])", "type": "method", "name": "Transform", "signatures": [ { "params": [ { "textRaw": "`options` {Object} Passed to both Writable and Readable constructors. ", "name": "options", "type": "Object", "desc": "Passed to both Writable and Readable constructors.", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Transform class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "transform.\\_flush(callback)", "type": "method", "name": "\\_flush", "signatures": [ { "params": [ { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done flushing any remaining data. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done flushing any remaining data." } ] }, { "params": [ { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It MAY be implemented\nby child classes, and if so, will be called by the internal Transform\nclass methods only.\n\n

\n

In some cases, your transform operation may need to emit a bit more\ndata at the end of the stream. For example, a Zlib compression\nstream will store up some internal state so that it can optimally\ncompress the output. At the end, however, it needs to do the best it\ncan with what is left, so that the data will be complete.\n\n

\n

In those cases, you can implement a _flush method, which will be\ncalled at the very end, after all the written data is consumed, but\nbefore emitting end to signal the end of the readable side. Just\nlike with _transform, call transform.push(chunk) zero or more\ntimes, as appropriate, and call callback when the flush operation is\ncomplete.\n\n

\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n" }, { "textRaw": "transform.\\_transform(chunk, encoding, callback)", "type": "method", "name": "\\_transform", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. ", "name": "chunk", "type": "Buffer | String", "desc": "The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`." }, { "textRaw": "`encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. ", "name": "encoding", "type": "String", "desc": "If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument and data) when you are done processing the supplied chunk. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument and data) when you are done processing the supplied chunk." } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding" }, { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It should be\nimplemented by child classes, and called by the internal Transform\nclass methods only.\n\n

\n

All Transform stream implementations must provide a _transform\nmethod to accept input and produce output.\n\n

\n

_transform should do whatever has to be done in this specific\nTransform class, to handle the bytes being written, and pass them off\nto the readable portion of the interface. Do asynchronous I/O,\nprocess things, and so on.\n\n

\n

Call transform.push(outputChunk) 0 or more times to generate output\nfrom this input chunk, depending on how much data you want to output\nas a result of this chunk.\n\n

\n

Call the callback function only when the current chunk is completely\nconsumed. Note that there may or may not be output as a result of any\nparticular input chunk. If you supply a second argument to the callback\nit will be passed to the push method. In other words the following are\nequivalent:\n\n

\n
transform.prototype._transform = function (data, encoding, callback) {\n  this.push(data);\n  callback();\n};\n\ntransform.prototype._transform = function (data, encoding, callback) {\n  callback(null, data);\n};
\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n

Example: SimpleProtocol parser v2

\n

The example above of a simple protocol parser can be implemented\nsimply by using the higher level [Transform][] stream class, similar to\nthe parseHeader and SimpleProtocol v1 examples above.\n\n

\n

In this example, rather than providing the input as an argument, it\nwould be piped into the parser, which is a more idiomatic Node.js stream\napproach.\n\n

\n
const util = require('util');\nconst Transform = require('stream').Transform;\nutil.inherits(SimpleProtocol, Transform);\n\nfunction SimpleProtocol(options) {\n  if (!(this instanceof SimpleProtocol))\n    return new SimpleProtocol(options);\n\n  Transform.call(this, options);\n  this._inBody = false;\n  this._sawFirstCr = false;\n  this._rawHeader = [];\n  this.header = null;\n}\n\nSimpleProtocol.prototype._transform = function(chunk, encoding, done) {\n  if (!this._inBody) {\n    // check if the chunk has a \\n\\n\n    var split = -1;\n    for (var i = 0; i < chunk.length; i++) {\n      if (chunk[i] === 10) { // '\\n'\n        if (this._sawFirstCr) {\n          split = i;\n          break;\n        } else {\n          this._sawFirstCr = true;\n        }\n      } else {\n        this._sawFirstCr = false;\n      }\n    }\n\n    if (split === -1) {\n      // still waiting for the \\n\\n\n      // stash the chunk, and try again.\n      this._rawHeader.push(chunk);\n    } else {\n      this._inBody = true;\n      var h = chunk.slice(0, split);\n      this._rawHeader.push(h);\n      var header = Buffer.concat(this._rawHeader).toString();\n      try {\n        this.header = JSON.parse(header);\n      } catch (er) {\n        this.emit('error', new Error('invalid simple protocol data'));\n        return;\n      }\n      // and let them know that we are done parsing the header.\n      this.emit('header', this.header);\n\n      // now, because we got some extra data, emit this first.\n      this.push(chunk.slice(split));\n    }\n  } else {\n    // from there on, just provide the data to our consumer as-is.\n    this.push(chunk);\n  }\n  done();\n};\n\n// Usage:\n// var parser = new SimpleProtocol();\n// source.pipe(parser)\n// Now parser is a readable stream that will emit 'header'\n// with the parsed header data.
\n" } ], "modules": [ { "textRaw": "Events: 'finish' and 'end'", "name": "events:_'finish'_and_'end'", "desc": "

The ['finish'][] and ['end'][] events are from the parent Writable\nand Readable classes respectively. The 'finish' event is fired after\n.end() is called and all chunks have been processed by _transform,\nend is fired after all data has been output which is after the callback\nin _flush has been called.\n\n

\n", "type": "module", "displayName": "Events: 'finish' and 'end'" } ] }, { "textRaw": "Class: stream.Writable", "type": "class", "name": "stream.Writable", "desc": "

stream.Writable is an abstract class designed to be extended with an\nunderlying implementation of the [_write(chunk, encoding, callback)][] method.\n\n

\n

Please see above under [API for Stream Consumers][] for how to consume\nwritable streams in your programs. What follows is an explanation of\nhow to implement Writable streams in your programs.\n\n

\n", "methods": [ { "textRaw": "new stream.Writable([options])", "type": "method", "name": "Writable", "signatures": [ { "params": [ { "textRaw": "`options` {Object} ", "options": [ { "textRaw": "`highWaterMark` {Number} Buffer level when [`write()`][] starts returning false. Default=16kb, or 16 for `objectMode` streams ", "name": "highWaterMark", "type": "Number", "desc": "Buffer level when [`write()`][] starts returning false. Default=16kb, or 16 for `objectMode` streams" }, { "textRaw": "`decodeStrings` {Boolean} Whether or not to decode strings into Buffers before passing them to [`_write()`][]. Default=true ", "name": "decodeStrings", "type": "Boolean", "desc": "Whether or not to decode strings into Buffers before passing them to [`_write()`][]. Default=true" }, { "textRaw": "`objectMode` {Boolean} Whether or not the `write(anyObj)` is a valid operation. If set you can write arbitrary data instead of only `Buffer` / `String` data. Default=false ", "name": "objectMode", "type": "Boolean", "desc": "Whether or not the `write(anyObj)` is a valid operation. If set you can write arbitrary data instead of only `Buffer` / `String` data. Default=false" } ], "name": "options", "type": "Object", "optional": true } ] }, { "params": [ { "name": "options", "optional": true } ] } ], "desc": "

In classes that extend the Writable class, make sure to call the\nconstructor so that the buffering settings can be properly\ninitialized.\n\n

\n" }, { "textRaw": "writable.\\_write(chunk, encoding, callback)", "type": "method", "name": "\\_write", "signatures": [ { "params": [ { "textRaw": "`chunk` {Buffer | String} The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. ", "name": "chunk", "type": "Buffer | String", "desc": "The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`." }, { "textRaw": "`encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. ", "name": "encoding", "type": "String", "desc": "If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunk. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done processing the supplied chunk." } ] }, { "params": [ { "name": "chunk" }, { "name": "encoding" }, { "name": "callback" } ] } ], "desc": "

All Writable stream implementations must provide a [_write()][]\nmethod to send data to the underlying resource.\n\n

\n

Note: This function MUST NOT be called directly. It should be\nimplemented by child classes, and called by the internal Writable\nclass methods only.\n\n

\n

Call the callback using the standard callback(error) pattern to\nsignal that the write completed successfully or with an error.\n\n

\n

If the decodeStrings flag is set in the constructor options, then\nchunk may be a string rather than a Buffer, and encoding will\nindicate the sort of string that it is. This is to support\nimplementations that have an optimized handling for certain string\ndata encodings. If you do not explicitly set the decodeStrings\noption to false, then you can safely ignore the encoding argument,\nand assume that chunk will always be a Buffer.\n\n

\n

This method is prefixed with an underscore because it is internal to\nthe class that defines it, and should not be called directly by user\nprograms. However, you are expected to override this method in\nyour own extension classes.\n\n

\n" }, { "textRaw": "writable.\\_writev(chunks, callback)", "type": "method", "name": "\\_writev", "signatures": [ { "params": [ { "textRaw": "`chunks` {Array} The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`. ", "name": "chunks", "type": "Array", "desc": "The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`." }, { "textRaw": "`callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunks. ", "name": "callback", "type": "Function", "desc": "Call this function (optionally with an error argument) when you are done processing the supplied chunks." } ] }, { "params": [ { "name": "chunks" }, { "name": "callback" } ] } ], "desc": "

Note: This function MUST NOT be called directly. It may be\nimplemented by child classes, and called by the internal Writable\nclass methods only.\n\n

\n

This function is completely optional to implement. In most cases it is\nunnecessary. If implemented, it will be called with all the chunks\nthat are buffered in the write queue.\n\n\n

\n" } ] } ] }, { "textRaw": "Simplified Constructor API", "name": "Simplified Constructor API", "type": "misc", "desc": "

In simple cases there is now the added benefit of being able to construct a stream without inheritance.\n\n

\n

This can be done by passing the appropriate methods as constructor options:\n\n

\n

Examples:\n\n

\n", "miscs": [ { "textRaw": "Duplex", "name": "duplex", "desc": "
var duplex = new stream.Duplex({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  },\n  write: function(chunk, encoding, next) {\n    // sets this._write under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});\n\n// or\n\nvar duplex = new stream.Duplex({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  },\n  writev: function(chunks, next) {\n    // sets this._writev under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});
\n", "type": "misc", "displayName": "Duplex" }, { "textRaw": "Readable", "name": "readable", "desc": "
var readable = new stream.Readable({\n  read: function(n) {\n    // sets this._read under the hood\n\n    // push data onto the read queue, passing null\n    // will signal the end of the stream (EOF)\n    this.push(chunk);\n  }\n});
\n", "type": "misc", "displayName": "Readable" }, { "textRaw": "Transform", "name": "transform", "desc": "
var transform = new stream.Transform({\n  transform: function(chunk, encoding, next) {\n    // sets this._transform under the hood\n\n    // generate output as many times as needed\n    // this.push(chunk);\n\n    // call when the current chunk is consumed\n    next();\n  },\n  flush: function(done) {\n    // sets this._flush under the hood\n\n    // generate output as many times as needed\n    // this.push(chunk);\n\n    done();\n  }\n});
\n", "type": "misc", "displayName": "Transform" }, { "textRaw": "Writable", "name": "writable", "desc": "
var writable = new stream.Writable({\n  write: function(chunk, encoding, next) {\n    // sets this._write under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});\n\n// or\n\nvar writable = new stream.Writable({\n  writev: function(chunks, next) {\n    // sets this._writev under the hood\n\n    // An optional error can be passed as the first argument\n    next()\n  }\n});
\n", "type": "misc", "displayName": "Writable" } ] }, { "textRaw": "Streams: Under the Hood", "name": "Streams: Under the Hood", "type": "misc", "miscs": [ { "textRaw": "Buffering", "name": "Buffering", "type": "misc", "desc": "

Both Writable and Readable streams will buffer data on an internal\nobject which can be retrieved from _writableState.getBuffer() or\n_readableState.buffer, respectively.\n\n

\n

The amount of data that will potentially be buffered depends on the\nhighWaterMark option which is passed into the constructor.\n\n

\n

Buffering in Readable streams happens when the implementation calls\n[stream.push(chunk)][]. If the consumer of the Stream does not call\nstream.read(), then the data will sit in the internal queue until it\nis consumed.\n\n

\n

Buffering in Writable streams happens when the user calls\n[stream.write(chunk)][] repeatedly, even when write() returns false.\n\n

\n

The purpose of streams, especially with the pipe() method, is to\nlimit the buffering of data to acceptable levels, so that sources and\ndestinations of varying speed will not overwhelm the available memory.\n\n

\n" }, { "textRaw": "Compatibility with Older Node.js Versions", "name": "Compatibility with Older Node.js Versions", "type": "misc", "desc": "

In versions of Node.js prior to v0.10, the Readable stream interface was\nsimpler, but also less powerful and less useful.\n\n

\n
    \n
  • Rather than waiting for you to call the read() method, 'data'\nevents would start emitting immediately. If you needed to do some\nI/O to decide how to handle data, then you had to store the chunks\nin some kind of buffer so that they would not be lost.
  • \n
  • The [pause()][] method was advisory, rather than guaranteed. This\nmeant that you still had to be prepared to receive 'data' events\neven when the stream was in a paused state.
  • \n
\n

In Node.js v0.10, the Readable class described below was added.\nFor backwards compatibility with older Node.js programs, Readable streams\nswitch into "flowing mode" when a 'data' event handler is added, or\nwhen the [resume()][] method is called. The effect is that, even if\nyou are not using the new read() method and 'readable' event, you\nno longer have to worry about losing 'data' chunks.\n\n

\n

Most programs will continue to function normally. However, this\nintroduces an edge case in the following conditions:\n\n

\n
    \n
  • No ['data'][] event handler is added.
  • \n
  • The [resume()][] method is never called.
  • \n
  • The stream is not piped to any writable destination.
  • \n
\n

For example, consider the following code:\n\n

\n
// WARNING!  BROKEN!\nnet.createServer((socket) => {\n\n  // we add an 'end' method, but never consume the data\n  socket.on('end', () => {\n    // It will never get here.\n    socket.end('I got your message (but didnt read it)\\n');\n  });\n\n}).listen(1337);
\n

In versions of Node.js prior to v0.10, the incoming message data would be\nsimply discarded. However, in Node.js v0.10 and beyond,\nthe socket will remain paused forever.\n\n

\n

The workaround in this situation is to call the resume() method to\nstart the flow of data:\n\n

\n
// Workaround\nnet.createServer((socket) => {\n\n  socket.on('end', () => {\n    socket.end('I got your message (but didnt read it)\\n');\n  });\n\n  // start the flow of data, discarding it.\n  socket.resume();\n\n}).listen(1337);
\n

In addition to new Readable streams switching into flowing mode,\npre-v0.10 style streams can be wrapped in a Readable class using the\nwrap() method.\n\n\n

\n" }, { "textRaw": "Object Mode", "name": "Object Mode", "type": "misc", "desc": "

Normally, Streams operate on Strings and Buffers exclusively.\n\n

\n

Streams that are in object mode can emit generic JavaScript values\nother than Buffers and Strings.\n\n

\n

A Readable stream in object mode will always return a single item from\na call to stream.read(size), regardless of what the size argument\nis.\n\n

\n

A Writable stream in object mode will always ignore the encoding\nargument to stream.write(data, encoding).\n\n

\n

The special value null still retains its special value for object\nmode streams. That is, for object mode readable streams, null as a\nreturn value from stream.read() indicates that there is no more\ndata, and [stream.push(null)][] will signal the end of stream data\n(EOF).\n\n

\n

No streams in Node.js core are object mode streams. This pattern is only\nused by userland streaming libraries.\n\n

\n

You should set objectMode in your stream child class constructor on\nthe options object. Setting objectMode mid-stream is not safe.\n\n

\n

For Duplex streams objectMode can be set exclusively for readable or\nwritable side with readableObjectMode and writableObjectMode\nrespectively. These options can be used to implement parsers and\nserializers with Transform streams.\n\n

\n
const util = require('util');\nconst StringDecoder = require('string_decoder').StringDecoder;\nconst Transform = require('stream').Transform;\nutil.inherits(JSONParseStream, Transform);\n\n// Gets \\n-delimited JSON string data, and emits the parsed objects\nfunction JSONParseStream() {\n  if (!(this instanceof JSONParseStream))\n    return new JSONParseStream();\n\n  Transform.call(this, { readableObjectMode : true });\n\n  this._buffer = '';\n  this._decoder = new StringDecoder('utf8');\n}\n\nJSONParseStream.prototype._transform = function(chunk, encoding, cb) {\n  this._buffer += this._decoder.write(chunk);\n  // split on newlines\n  var lines = this._buffer.split(/\\r?\\n/);\n  // keep the last partial line buffered\n  this._buffer = lines.pop();\n  for (var l = 0; l < lines.length; l++) {\n    var line = lines[l];\n    try {\n      var obj = JSON.parse(line);\n    } catch (er) {\n      this.emit('error', er);\n      return;\n    }\n    // push the parsed object out to the readable consumer\n    this.push(obj);\n  }\n  cb();\n};\n\nJSONParseStream.prototype._flush = function(cb) {\n  // Just handle any leftover\n  var rem = this._buffer.trim();\n  if (rem) {\n    try {\n      var obj = JSON.parse(rem);\n    } catch (er) {\n      this.emit('error', er);\n      return;\n    }\n    // push the parsed object out to the readable consumer\n    this.push(obj);\n  }\n  cb();\n};
\n" }, { "textRaw": "`stream.read(0)`", "name": "`stream.read(0)`", "desc": "

There are some cases where you want to trigger a refresh of the\nunderlying readable stream mechanisms, without actually consuming any\ndata. In that case, you can call stream.read(0), which will always\nreturn null.\n\n

\n

If the internal read buffer is below the highWaterMark, and the\nstream is not currently reading, then calling read(0) will trigger\na low-level _read call.\n\n

\n

There is almost never a need to do this. However, you will see some\ncases in Node.js's internals where this is done, particularly in the\nReadable stream class internals.\n\n

\n", "type": "misc", "displayName": "`stream.read(0)`" }, { "textRaw": "`stream.push('')`", "name": "`stream.push('')`", "desc": "

Pushing a zero-byte string or Buffer (when not in [Object mode][]) has an\ninteresting side effect. Because it is a call to\n[stream.push()][], it will end the reading process. However, it\ndoes not add any data to the readable buffer, so there's nothing for\na user to consume.\n\n

\n

Very rarely, there are cases where you have no data to provide now,\nbut the consumer of your stream (or, perhaps, another bit of your own\ncode) will know when to check again, by calling stream.read(0). In\nthose cases, you may call stream.push('').\n\n

\n

So far, the only use case for this functionality is in the\n[tls.CryptoStream][] class, which is deprecated in Node.js/io.js v1.0. If you\nfind that you have to use stream.push(''), please consider another\napproach, because it almost certainly indicates that something is\nhorribly wrong.\n\n

\n", "type": "misc", "displayName": "`stream.push('')`" } ] } ], "type": "module", "displayName": "Stream" } ] } node-v4.2.6/doc/api/stream.markdown000644 000766 000024 00000155603 12650222326 017335 0ustar00iojsstaff000000 000000 # Stream Stability: 2 - Stable A stream is an abstract interface implemented by various objects in Node.js. For example a [request to an HTTP server][] is a stream, as is [`stdout`][]. Streams are readable, writable, or both. All streams are instances of [`EventEmitter`][]. You can load the Stream base classes by doing `require('stream')`. There are base classes provided for [Readable][] streams, [Writable][] streams, [Duplex][] streams, and [Transform][] streams. This document is split up into 3 sections: 1. The first section explains the parts of the API that you need to be aware of to use streams in your programs. 2. The second section explains the parts of the API that you need to use if you implement your own custom streams yourself. The API is designed to make this easy for you to do. 3. The third section goes into more depth about how streams work, including some of the internal mechanisms and functions that you should probably not modify unless you definitely know what you are doing. ## API for Stream Consumers Streams can be either [Readable][], [Writable][], or both ([Duplex][]). All streams are EventEmitters, but they also have other custom methods and properties depending on whether they are Readable, Writable, or Duplex. If a stream is both Readable and Writable, then it implements all of the methods and events below. So, a [Duplex][] or [Transform][] stream is fully described by this API, though their implementation may be somewhat different. It is not necessary to implement Stream interfaces in order to consume streams in your programs. If you **are** implementing streaming interfaces in your own program, please also refer to [API for Stream Implementors][] below. Almost all Node.js programs, no matter how simple, use Streams in some way. Here is an example of using Streams in an Node.js program: ```javascript const http = require('http'); var server = http.createServer( (req, res) => { // req is an http.IncomingMessage, which is a Readable Stream // res is an http.ServerResponse, which is a Writable Stream var body = ''; // we want to get the data as utf8 strings // If you don't set an encoding, then you'll get Buffer objects req.setEncoding('utf8'); // Readable streams emit 'data' events once a listener is added req.on('data', (chunk) => { body += chunk; }); // the end event tells you that you have entire body req.on('end', () => { try { var data = JSON.parse(body); } catch (er) { // uh oh! bad json! res.statusCode = 400; return res.end(`error: ${er.message}`); } // write back something interesting to the user: res.write(typeof data); res.end(); }); }); server.listen(1337); // $ curl localhost:1337 -d '{}' // object // $ curl localhost:1337 -d '"foo"' // string // $ curl localhost:1337 -d 'not json' // error: Unexpected token o ``` ### Class: stream.Duplex Duplex streams are streams that implement both the [Readable][] and [Writable][] interfaces. See above for usage. Examples of Duplex streams include: * [tcp sockets][] * [zlib streams][] * [crypto streams][] ### Class: stream.Readable The Readable stream interface is the abstraction for a *source* of data that you are reading from. In other words, data comes *out* of a Readable stream. A Readable stream will not start emitting data until you indicate that you are ready to receive it. Readable streams have two "modes": a **flowing mode** and a **paused mode**. When in flowing mode, data is read from the underlying system and provided to your program as fast as possible. In paused mode, you must explicitly call `stream.read()` to get chunks of data out. Streams start out in paused mode. **Note**: If no data event handlers are attached, and there are no [`pipe()`][] destinations, and the stream is switched into flowing mode, then data will be lost. You can switch to flowing mode by doing any of the following: * Adding a [`'data'`][] event handler to listen for data. * Calling the [`resume()`][] method to explicitly open the flow. * Calling the [`pipe()`][] method to send the data to a [Writable][]. You can switch back to paused mode by doing either of the following: * If there are no pipe destinations, by calling the [`pause()`][] method. * If there are pipe destinations, by removing any [`'data'`][] event handlers, and removing all pipe destinations by calling the [`unpipe()`][] method. Note that, for backwards compatibility reasons, removing `'data'` event handlers will **not** automatically pause the stream. Also, if there are piped destinations, then calling `pause()` will not guarantee that the stream will *remain* paused once those destinations drain and ask for more data. Examples of readable streams include: * [http responses, on the client][] * [http requests, on the server][] * [fs read streams][] * [zlib streams][] * [crypto streams][] * [tcp sockets][] * [child process stdout and stderr][] * [`process.stdin`][] #### Event: 'close' Emitted when the stream and any of its underlying resources (a file descriptor, for example) have been closed. The event indicates that no more events will be emitted, and no further computation will occur. Not all streams will emit the `'close'` event. #### Event: 'data' * `chunk` {Buffer | String} The chunk of data. Attaching a `'data'` event listener to a stream that has not been explicitly paused will switch the stream into flowing mode. Data will then be passed as soon as it is available. If you just want to get all the data out of the stream as fast as possible, this is the best way to do so. ```javascript var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); }); ``` #### Event: 'end' This event fires when there will be no more data to read. Note that the `'end'` event **will not fire** unless the data is completely consumed. This can be done by switching into flowing mode, or by calling `read()` repeatedly until you get to the end. ```javascript var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); }); readable.on('end', () => { console.log('there will be no more data.'); }); ``` #### Event: 'error' * {Error Object} Emitted if there was an error receiving data. #### Event: 'readable' When a chunk of data can be read from the stream, it will emit a `'readable'` event. In some cases, listening for a `'readable'` event will cause some data to be read into the internal buffer from the underlying system, if it hadn't already. ```javascript var readable = getReadableStreamSomehow(); readable.on('readable', () => { // there is some data to read now }); ``` Once the internal buffer is drained, a `'readable'` event will fire again when more data is available. The `'readable'` event is not emitted in the "flowing" mode with the sole exception of the last one, on end-of-stream. The `'readable'` event indicates that the stream has new information: either new data is available or the end of the stream has been reached. In the former case, `.read()` will return that data. In the latter case, `.read()` will return null. For instance, in the following example, `foo.txt` is an empty file: ```javascript const fs = require('fs'); var rr = fs.createReadStream('foo.txt'); rr.on('readable', () => { console.log('readable:', rr.read()); }); rr.on('end', () => { console.log('end'); }); ``` The output of running this script is: ``` bash-3.2$ node test.js readable: null end ``` #### readable.isPaused() * Return: `Boolean` This method returns whether or not the `readable` has been **explicitly** paused by client code (using `readable.pause()` without a corresponding `readable.resume()`). ```javascript var readable = new stream.Readable readable.isPaused() // === false readable.pause() readable.isPaused() // === true readable.resume() readable.isPaused() // === false ``` #### readable.pause() * Return: `this` This method will cause a stream in flowing mode to stop emitting `'data'` events, switching out of flowing mode. Any data that becomes available will remain in the internal buffer. ```javascript var readable = getReadableStreamSomehow(); readable.on('data', (chunk) => { console.log('got %d bytes of data', chunk.length); readable.pause(); console.log('there will be no more data for 1 second'); setTimeout(() => { console.log('now data will start flowing again'); readable.resume(); }, 1000); }); ``` #### readable.pipe(destination[, options]) * `destination` {[Writable][] Stream} The destination for writing data * `options` {Object} Pipe options * `end` {Boolean} End the writer when the reader ends. Default = `true` This method pulls all the data out of a readable stream, and writes it to the supplied destination, automatically managing the flow so that the destination is not overwhelmed by a fast readable stream. Multiple destinations can be piped to safely. ```javascript var readable = getReadableStreamSomehow(); var writable = fs.createWriteStream('file.txt'); // All the data from readable goes into 'file.txt' readable.pipe(writable); ``` This function returns the destination stream, so you can set up pipe chains like so: ```javascript var r = fs.createReadStream('file.txt'); var z = zlib.createGzip(); var w = fs.createWriteStream('file.txt.gz'); r.pipe(z).pipe(w); ``` For example, emulating the Unix `cat` command: ```javascript process.stdin.pipe(process.stdout); ``` By default [`end()`][] is called on the destination when the source stream emits `end`, so that `destination` is no longer writable. Pass `{ end: false }` as `options` to keep the destination stream open. This keeps `writer` open so that "Goodbye" can be written at the end. ```javascript reader.pipe(writer, { end: false }); reader.on('end', () => { writer.end('Goodbye\n'); }); ``` Note that `process.stderr` and `process.stdout` are never closed until the process exits, regardless of the specified options. #### readable.read([size]) * `size` {Number} Optional argument to specify how much data to read. * Return {String | Buffer | null} The `read()` method pulls some data out of the internal buffer and returns it. If there is no data available, then it will return `null`. If you pass in a `size` argument, then it will return that many bytes. If `size` bytes are not available, then it will return `null`, unless we've ended, in which case it will return the data remaining in the buffer. If you do not specify a `size` argument, then it will return all the data in the internal buffer. This method should only be called in paused mode. In flowing mode, this method is called automatically until the internal buffer is drained. ```javascript var readable = getReadableStreamSomehow(); readable.on('readable', () => { var chunk; while (null !== (chunk = readable.read())) { console.log('got %d bytes of data', chunk.length); } }); ``` If this method returns a data chunk, then it will also trigger the emission of a [`'data'`][] event. Note that calling `readable.read([size])` after the `'end'` event has been triggered will return `null`. No runtime error will be raised. #### readable.resume() * Return: `this` This method will cause the readable stream to resume emitting `data` events. This method will switch the stream into flowing mode. If you do *not* want to consume the data from a stream, but you *do* want to get to its `'end'` event, you can call [`readable.resume()`][] to open the flow of data. ```javascript var readable = getReadableStreamSomehow(); readable.resume(); readable.on('end', () => { console.log('got to the end, but did not read anything'); }); ``` #### readable.setEncoding(encoding) * `encoding` {String} The encoding to use. * Return: `this` Call this function to cause the stream to return strings of the specified encoding instead of Buffer objects. For example, if you do `readable.setEncoding('utf8')`, then the output data will be interpreted as UTF-8 data, and returned as strings. If you do `readable.setEncoding('hex')`, then the data will be encoded in hexadecimal string format. This properly handles multi-byte characters that would otherwise be potentially mangled if you simply pulled the Buffers directly and called `buf.toString(encoding)` on them. If you want to read the data as strings, always use this method. ```javascript var readable = getReadableStreamSomehow(); readable.setEncoding('utf8'); readable.on('data', (chunk) => { assert.equal(typeof chunk, 'string'); console.log('got %d characters of string data', chunk.length); }); ``` #### readable.unpipe([destination]) * `destination` {[Writable][] Stream} Optional specific stream to unpipe This method will remove the hooks set up for a previous `pipe()` call. If the destination is not specified, then all pipes are removed. If the destination is specified, but no pipe is set up for it, then this is a no-op. ```javascript var readable = getReadableStreamSomehow(); var writable = fs.createWriteStream('file.txt'); // All the data from readable goes into 'file.txt', // but only for the first second readable.pipe(writable); setTimeout(() => { console.log('stop writing to file.txt'); readable.unpipe(writable); console.log('manually close the file stream'); writable.end(); }, 1000); ``` #### readable.unshift(chunk) * `chunk` {Buffer | String} Chunk of data to unshift onto the read queue This is useful in certain cases where a stream is being consumed by a parser, which needs to "un-consume" some data that it has optimistically pulled out of the source, so that the stream can be passed on to some other party. Note that `stream.unshift(chunk)` cannot be called after the `'end'` event has been triggered; a runtime error will be raised. If you find that you must often call `stream.unshift(chunk)` in your programs, consider implementing a [Transform][] stream instead. (See API for Stream Implementors, below.) ```javascript // Pull off a header delimited by \n\n // use unshift() if we get too much // Call the callback with (error, header, stream) const StringDecoder = require('string_decoder').StringDecoder; function parseHeader(stream, callback) { stream.on('error', callback); stream.on('readable', onReadable); var decoder = new StringDecoder('utf8'); var header = ''; function onReadable() { var chunk; while (null !== (chunk = stream.read())) { var str = decoder.write(chunk); if (str.match(/\n\n/)) { // found the header boundary var split = str.split(/\n\n/); header += split.shift(); var remaining = split.join('\n\n'); var buf = new Buffer(remaining, 'utf8'); if (buf.length) stream.unshift(buf); stream.removeListener('error', callback); stream.removeListener('readable', onReadable); // now the body of the message can be read from the stream. callback(null, header, stream); } else { // still reading the header. header += str; } } } } ``` Note that, unlike `stream.push(chunk)`, `stream.unshift(chunk)` will not end the reading process by resetting the internal reading state of the stream. This can cause unexpected results if `unshift` is called during a read (i.e. from within a `_read` implementation on a custom stream). Following the call to `unshift` with an immediate `stream.push('')` will reset the reading state appropriately, however it is best to simply avoid calling `unshift` while in the process of performing a read. #### readable.wrap(stream) * `stream` {Stream} An "old style" readable stream Versions of Node.js prior to v0.10 had streams that did not implement the entire Streams API as it is today. (See "Compatibility" below for more information.) If you are using an older Node.js library that emits `'data'` events and has a [`pause()`][] method that is advisory only, then you can use the `wrap()` method to create a [Readable][] stream that uses the old stream as its data source. You will very rarely ever need to call this function, but it exists as a convenience for interacting with old Node.js programs and libraries. For example: ```javascript const OldReader = require('./old-api-module.js').OldReader; const Readable = require('stream').Readable; const oreader = new OldReader; const myReader = new Readable().wrap(oreader); myReader.on('readable', () => { myReader.read(); // etc. }); ``` ### Class: stream.Transform Transform streams are [Duplex][] streams where the output is in some way computed from the input. They implement both the [Readable][] and [Writable][] interfaces. See above for usage. Examples of Transform streams include: * [zlib streams][] * [crypto streams][] ### Class: stream.Writable The Writable stream interface is an abstraction for a *destination* that you are writing data *to*. Examples of writable streams include: * [http requests, on the client][] * [http responses, on the server][] * [fs write streams][] * [zlib streams][] * [crypto streams][] * [tcp sockets][] * [child process stdin][] * [`process.stdout`][], [`process.stderr`][] #### Event: 'drain' If a [`writable.write(chunk)`][] call returns false, then the `'drain'` event will indicate when it is appropriate to begin writing more data to the stream. ```javascript // Write the data to the supplied writable stream one million times. // Be attentive to back-pressure. function writeOneMillionTimes(writer, data, encoding, callback) { var i = 1000000; write(); function write() { var ok = true; do { i -= 1; if (i === 0) { // last time! writer.write(data, encoding, callback); } else { // see if we should continue, or wait // don't pass the callback, because we're not done yet. ok = writer.write(data, encoding); } } while (i > 0 && ok); if (i > 0) { // had to stop early! // write some more once it drains writer.once('drain', write); } } } ``` #### Event: 'error' * {Error object} Emitted if there was an error when writing or piping data. #### Event: 'finish' When the [`end()`][] method has been called, and all data has been flushed to the underlying system, this event is emitted. ```javascript var writer = getWritableStreamSomehow(); for (var i = 0; i < 100; i ++) { writer.write('hello, #${i}!\n'); } writer.end('this is the end\n'); writer.on('finish', () => { console.error('all writes are now complete.'); }); ``` #### Event: 'pipe' * `src` {[Readable][] Stream} source stream that is piping to this writable This is emitted whenever the `pipe()` method is called on a readable stream, adding this writable to its set of destinations. ```javascript var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); writer.on('pipe', (src) => { console.error('something is piping into the writer'); assert.equal(src, reader); }); reader.pipe(writer); ``` #### Event: 'unpipe' * `src` {[Readable][] Stream} The source stream that [unpiped][] this writable This is emitted whenever the [`unpipe()`][] method is called on a readable stream, removing this writable from its set of destinations. ```javascript var writer = getWritableStreamSomehow(); var reader = getReadableStreamSomehow(); writer.on('unpipe', (src) => { console.error('something has stopped piping into the writer'); assert.equal(src, reader); }); reader.pipe(writer); reader.unpipe(writer); ``` #### writable.cork() Forces buffering of all writes. Buffered data will be flushed either at `.uncork()` or at `.end()` call. #### writable.end([chunk][, encoding][, callback]) * `chunk` {String | Buffer} Optional data to write * `encoding` {String} The encoding, if `chunk` is a String * `callback` {Function} Optional callback for when the stream is finished Call this method when no more data will be written to the stream. If supplied, the callback is attached as a listener on the `'finish'` event. Calling [`write()`][] after calling [`end()`][] will raise an error. ```javascript // write 'hello, ' and then end with 'world!' var file = fs.createWriteStream('example.txt'); file.write('hello, '); file.end('world!'); // writing more now is not allowed! ``` #### writable.setDefaultEncoding(encoding) * `encoding` {String} The new default encoding Sets the default encoding for a writable stream. #### writable.uncork() Flush all data, buffered since `.cork()` call. #### writable.write(chunk[, encoding][, callback]) * `chunk` {String | Buffer} The data to write * `encoding` {String} The encoding, if `chunk` is a String * `callback` {Function} Callback for when this chunk of data is flushed * Returns: {Boolean} True if the data was handled completely. This method writes some data to the underlying system, and calls the supplied callback once the data has been fully handled. The return value indicates if you should continue writing right now. If the data had to be buffered internally, then it will return `false`. Otherwise, it will return `true`. This return value is strictly advisory. You MAY continue to write, even if it returns `false`. However, writes will be buffered in memory, so it is best not to do this excessively. Instead, wait for the `'drain'` event before writing more data. ## API for Stream Implementors To implement any sort of stream, the pattern is the same: 1. Extend the appropriate parent class in your own subclass. (The [`util.inherits`][] method is particularly helpful for this.) 2. Call the appropriate parent class constructor in your constructor, to be sure that the internal mechanisms are set up properly. 3. Implement one or more specific methods, as detailed below. The class to extend and the method(s) to implement depend on the sort of stream class you are writing:

Use-case

Class

Method(s) to implement

Reading only

[Readable](#stream_class_stream_readable_1)

[_read][]

Writing only

[Writable](#stream_class_stream_writable_1)

[_write][], [_writev][]

Reading and writing

[Duplex](#stream_class_stream_duplex_1)

[_read][], [_write][], [_writev][]

Operate on written data, then read the result

[Transform](#stream_class_stream_transform_1)

[_transform][], [_flush][]

In your implementation code, it is very important to never call the methods described in [API for Stream Consumers][] above. Otherwise, you can potentially cause adverse side effects in programs that consume your streaming interfaces. ### Class: stream.Duplex A "duplex" stream is one that is both Readable and Writable, such as a TCP socket connection. Note that `stream.Duplex` is an abstract class designed to be extended with an underlying implementation of the `_read(size)` and [`_write(chunk, encoding, callback)`][] methods as you would with a Readable or Writable stream class. Since JavaScript doesn't have multiple prototypal inheritance, this class prototypally inherits from Readable, and then parasitically from Writable. It is thus up to the user to implement both the lowlevel `_read(n)` method as well as the lowlevel [`_write(chunk, encoding, callback)`][] method on extension duplex classes. #### new stream.Duplex(options) * `options` {Object} Passed to both Writable and Readable constructors. Also has the following fields: * `allowHalfOpen` {Boolean} Default=true. If set to `false`, then the stream will automatically end the readable side when the writable side ends and vice versa. * `readableObjectMode` {Boolean} Default=false. Sets `objectMode` for readable side of the stream. Has no effect if `objectMode` is `true`. * `writableObjectMode` {Boolean} Default=false. Sets `objectMode` for writable side of the stream. Has no effect if `objectMode` is `true`. In classes that extend the Duplex class, make sure to call the constructor so that the buffering settings can be properly initialized. ### Class: stream.PassThrough This is a trivial implementation of a [Transform][] stream that simply passes the input bytes across to the output. Its purpose is mainly for examples and testing, but there are occasionally use cases where it can come in handy as a building block for novel sorts of streams. ### Class: stream.Readable `stream.Readable` is an abstract class designed to be extended with an underlying implementation of the [`_read(size)`][] method. Please see above under [API for Stream Consumers][] for how to consume streams in your programs. What follows is an explanation of how to implement Readable streams in your programs. #### new stream.Readable([options]) * `options` {Object} * `highWaterMark` {Number} The maximum number of bytes to store in the internal buffer before ceasing to read from the underlying resource. Default=16kb, or 16 for `objectMode` streams * `encoding` {String} If specified, then buffers will be decoded to strings using the specified encoding. Default=null * `objectMode` {Boolean} Whether this stream should behave as a stream of objects. Meaning that stream.read(n) returns a single value instead of a Buffer of size n. Default=false In classes that extend the Readable class, make sure to call the Readable constructor so that the buffering settings can be properly initialized. #### readable.\_read(size) * `size` {Number} Number of bytes to read asynchronously Note: **Implement this method, but do NOT call it directly.** This method is prefixed with an underscore because it is internal to the class that defines it and should only be called by the internal Readable class methods. All Readable stream implementations must provide a _read method to fetch data from the underlying resource. When _read is called, if data is available from the resource, `_read` should start pushing that data into the read queue by calling `this.push(dataChunk)`. `_read` should continue reading from the resource and pushing data until push returns false, at which point it should stop reading from the resource. Only when _read is called again after it has stopped should it start reading more data from the resource and pushing that data onto the queue. Note: once the `_read()` method is called, it will not be called again until the `push` method is called. The `size` argument is advisory. Implementations where a "read" is a single call that returns data can use this to know how much data to fetch. Implementations where that is not relevant, such as TCP or TLS, may ignore this argument, and simply provide data whenever it becomes available. There is no need, for example to "wait" until `size` bytes are available before calling [`stream.push(chunk)`][]. #### readable.push(chunk[, encoding]) * `chunk` {Buffer | null | String} Chunk of data to push into the read queue * `encoding` {String} Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'` * return {Boolean} Whether or not more pushes should be performed Note: **This method should be called by Readable implementors, NOT by consumers of Readable streams.** If a value other than null is passed, The `push()` method adds a chunk of data into the queue for subsequent stream processors to consume. If `null` is passed, it signals the end of the stream (EOF), after which no more data can be written. The data added with `push` can be pulled out by calling the `read()` method when the `'readable'` event fires. This API is designed to be as flexible as possible. For example, you may be wrapping a lower-level source which has some sort of pause/resume mechanism, and a data callback. In those cases, you could wrap the low-level source object by doing something like this: ```javascript // source is an object with readStop() and readStart() methods, // and an `ondata` member that gets called when it has data, and // an `onend` member that gets called when the data is over. util.inherits(SourceWrapper, Readable); function SourceWrapper(options) { Readable.call(this, options); this._source = getLowlevelSourceObject(); var self = this; // Every time there's data, we push it into the internal buffer. this._source.ondata = function(chunk) { // if push() returns false, then we need to stop reading from source if (!self.push(chunk)) self._source.readStop(); }; // When the source ends, we push the EOF-signaling `null` chunk this._source.onend = function() { self.push(null); }; } // _read will be called when the stream wants to pull more data in // the advisory size argument is ignored in this case. SourceWrapper.prototype._read = function(size) { this._source.readStart(); }; ``` #### Example: A Counting Stream This is a basic example of a Readable stream. It emits the numerals from 1 to 1,000,000 in ascending order, and then ends. ```javascript const Readable = require('stream').Readable; const util = require('util'); util.inherits(Counter, Readable); function Counter(opt) { Readable.call(this, opt); this._max = 1000000; this._index = 1; } Counter.prototype._read = function() { var i = this._index++; if (i > this._max) this.push(null); else { var str = '' + i; var buf = new Buffer(str, 'ascii'); this.push(buf); } }; ``` #### Example: SimpleProtocol v1 (Sub-optimal) This is similar to the `parseHeader` function described above, but implemented as a custom stream. Also, note that this implementation does not convert the incoming data to a string. However, this would be better implemented as a [Transform][] stream. See below for a better implementation. ```javascript // A parser for a simple data protocol. // The "header" is a JSON object, followed by 2 \n characters, and // then a message body. // // NOTE: This can be done more simply as a Transform stream! // Using Readable directly for this is sub-optimal. See the // alternative example below under the Transform section. const Readable = require('stream').Readable; const util = require('util'); util.inherits(SimpleProtocol, Readable); function SimpleProtocol(source, options) { if (!(this instanceof SimpleProtocol)) return new SimpleProtocol(source, options); Readable.call(this, options); this._inBody = false; this._sawFirstCr = false; // source is a readable stream, such as a socket or file this._source = source; var self = this; source.on('end', () => { self.push(null); }); // give it a kick whenever the source is readable // read(0) will not consume any bytes source.on('readable', () => { self.read(0); }); this._rawHeader = []; this.header = null; } SimpleProtocol.prototype._read = function(n) { if (!this._inBody) { var chunk = this._source.read(); // if the source doesn't have data, we don't have data yet. if (chunk === null) return this.push(''); // check if the chunk has a \n\n var split = -1; for (var i = 0; i < chunk.length; i++) { if (chunk[i] === 10) { // '\n' if (this._sawFirstCr) { split = i; break; } else { this._sawFirstCr = true; } } else { this._sawFirstCr = false; } } if (split === -1) { // still waiting for the \n\n // stash the chunk, and try again. this._rawHeader.push(chunk); this.push(''); } else { this._inBody = true; var h = chunk.slice(0, split); this._rawHeader.push(h); var header = Buffer.concat(this._rawHeader).toString(); try { this.header = JSON.parse(header); } catch (er) { this.emit('error', new Error('invalid simple protocol data')); return; } // now, because we got some extra data, unshift the rest // back into the read queue so that our consumer will see it. var b = chunk.slice(split); this.unshift(b); // calling unshift by itself does not reset the reading state // of the stream; since we're inside _read, doing an additional // push('') will reset the state appropriately. this.push(''); // and let them know that we are done parsing the header. this.emit('header', this.header); } } else { // from there on, just provide the data to our consumer. // careful not to push(null), since that would indicate EOF. var chunk = this._source.read(); if (chunk) this.push(chunk); } }; // Usage: // var parser = new SimpleProtocol(source); // Now parser is a readable stream that will emit 'header' // with the parsed header data. ``` ### Class: stream.Transform A "transform" stream is a duplex stream where the output is causally connected in some way to the input, such as a [zlib][] stream or a [crypto][] stream. There is no requirement that the output be the same size as the input, the same number of chunks, or arrive at the same time. For example, a Hash stream will only ever have a single chunk of output which is provided when the input is ended. A zlib stream will produce output that is either much smaller or much larger than its input. Rather than implement the [`_read()`][] and [`_write()`][] methods, Transform classes must implement the `_transform()` method, and may optionally also implement the `_flush()` method. (See below.) #### new stream.Transform([options]) * `options` {Object} Passed to both Writable and Readable constructors. In classes that extend the Transform class, make sure to call the constructor so that the buffering settings can be properly initialized. #### Events: 'finish' and 'end' The [`'finish'`][] and [`'end'`][] events are from the parent Writable and Readable classes respectively. The `'finish'` event is fired after `.end()` is called and all chunks have been processed by `_transform`, `end` is fired after all data has been output which is after the callback in `_flush` has been called. #### transform.\_flush(callback) * `callback` {Function} Call this function (optionally with an error argument) when you are done flushing any remaining data. Note: **This function MUST NOT be called directly.** It MAY be implemented by child classes, and if so, will be called by the internal Transform class methods only. In some cases, your transform operation may need to emit a bit more data at the end of the stream. For example, a `Zlib` compression stream will store up some internal state so that it can optimally compress the output. At the end, however, it needs to do the best it can with what is left, so that the data will be complete. In those cases, you can implement a `_flush` method, which will be called at the very end, after all the written data is consumed, but before emitting `end` to signal the end of the readable side. Just like with `_transform`, call `transform.push(chunk)` zero or more times, as appropriate, and call `callback` when the flush operation is complete. This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you **are** expected to override this method in your own extension classes. #### transform.\_transform(chunk, encoding, callback) * `chunk` {Buffer | String} The chunk to be transformed. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. * `encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. * `callback` {Function} Call this function (optionally with an error argument and data) when you are done processing the supplied chunk. Note: **This function MUST NOT be called directly.** It should be implemented by child classes, and called by the internal Transform class methods only. All Transform stream implementations must provide a `_transform` method to accept input and produce output. `_transform` should do whatever has to be done in this specific Transform class, to handle the bytes being written, and pass them off to the readable portion of the interface. Do asynchronous I/O, process things, and so on. Call `transform.push(outputChunk)` 0 or more times to generate output from this input chunk, depending on how much data you want to output as a result of this chunk. Call the callback function only when the current chunk is completely consumed. Note that there may or may not be output as a result of any particular input chunk. If you supply a second argument to the callback it will be passed to the push method. In other words the following are equivalent: ```javascript transform.prototype._transform = function (data, encoding, callback) { this.push(data); callback(); }; transform.prototype._transform = function (data, encoding, callback) { callback(null, data); }; ``` This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you **are** expected to override this method in your own extension classes. #### Example: `SimpleProtocol` parser v2 The example above of a simple protocol parser can be implemented simply by using the higher level [Transform][] stream class, similar to the `parseHeader` and `SimpleProtocol v1` examples above. In this example, rather than providing the input as an argument, it would be piped into the parser, which is a more idiomatic Node.js stream approach. ```javascript const util = require('util'); const Transform = require('stream').Transform; util.inherits(SimpleProtocol, Transform); function SimpleProtocol(options) { if (!(this instanceof SimpleProtocol)) return new SimpleProtocol(options); Transform.call(this, options); this._inBody = false; this._sawFirstCr = false; this._rawHeader = []; this.header = null; } SimpleProtocol.prototype._transform = function(chunk, encoding, done) { if (!this._inBody) { // check if the chunk has a \n\n var split = -1; for (var i = 0; i < chunk.length; i++) { if (chunk[i] === 10) { // '\n' if (this._sawFirstCr) { split = i; break; } else { this._sawFirstCr = true; } } else { this._sawFirstCr = false; } } if (split === -1) { // still waiting for the \n\n // stash the chunk, and try again. this._rawHeader.push(chunk); } else { this._inBody = true; var h = chunk.slice(0, split); this._rawHeader.push(h); var header = Buffer.concat(this._rawHeader).toString(); try { this.header = JSON.parse(header); } catch (er) { this.emit('error', new Error('invalid simple protocol data')); return; } // and let them know that we are done parsing the header. this.emit('header', this.header); // now, because we got some extra data, emit this first. this.push(chunk.slice(split)); } } else { // from there on, just provide the data to our consumer as-is. this.push(chunk); } done(); }; // Usage: // var parser = new SimpleProtocol(); // source.pipe(parser) // Now parser is a readable stream that will emit 'header' // with the parsed header data. ``` ### Class: stream.Writable `stream.Writable` is an abstract class designed to be extended with an underlying implementation of the [`_write(chunk, encoding, callback)`][] method. Please see above under [API for Stream Consumers][] for how to consume writable streams in your programs. What follows is an explanation of how to implement Writable streams in your programs. #### new stream.Writable([options]) * `options` {Object} * `highWaterMark` {Number} Buffer level when [`write()`][] starts returning false. Default=16kb, or 16 for `objectMode` streams * `decodeStrings` {Boolean} Whether or not to decode strings into Buffers before passing them to [`_write()`][]. Default=true * `objectMode` {Boolean} Whether or not the `write(anyObj)` is a valid operation. If set you can write arbitrary data instead of only `Buffer` / `String` data. Default=false In classes that extend the Writable class, make sure to call the constructor so that the buffering settings can be properly initialized. #### writable.\_write(chunk, encoding, callback) * `chunk` {Buffer | String} The chunk to be written. Will **always** be a buffer unless the `decodeStrings` option was set to `false`. * `encoding` {String} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. * `callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunk. All Writable stream implementations must provide a [`_write()`][] method to send data to the underlying resource. Note: **This function MUST NOT be called directly.** It should be implemented by child classes, and called by the internal Writable class methods only. Call the callback using the standard `callback(error)` pattern to signal that the write completed successfully or with an error. If the `decodeStrings` flag is set in the constructor options, then `chunk` may be a string rather than a Buffer, and `encoding` will indicate the sort of string that it is. This is to support implementations that have an optimized handling for certain string data encodings. If you do not explicitly set the `decodeStrings` option to `false`, then you can safely ignore the `encoding` argument, and assume that `chunk` will always be a Buffer. This method is prefixed with an underscore because it is internal to the class that defines it, and should not be called directly by user programs. However, you **are** expected to override this method in your own extension classes. #### writable.\_writev(chunks, callback) * `chunks` {Array} The chunks to be written. Each chunk has following format: `{ chunk: ..., encoding: ... }`. * `callback` {Function} Call this function (optionally with an error argument) when you are done processing the supplied chunks. Note: **This function MUST NOT be called directly.** It may be implemented by child classes, and called by the internal Writable class methods only. This function is completely optional to implement. In most cases it is unnecessary. If implemented, it will be called with all the chunks that are buffered in the write queue. ## Simplified Constructor API In simple cases there is now the added benefit of being able to construct a stream without inheritance. This can be done by passing the appropriate methods as constructor options: Examples: ### Duplex ```javascript var duplex = new stream.Duplex({ read: function(n) { // sets this._read under the hood // push data onto the read queue, passing null // will signal the end of the stream (EOF) this.push(chunk); }, write: function(chunk, encoding, next) { // sets this._write under the hood // An optional error can be passed as the first argument next() } }); // or var duplex = new stream.Duplex({ read: function(n) { // sets this._read under the hood // push data onto the read queue, passing null // will signal the end of the stream (EOF) this.push(chunk); }, writev: function(chunks, next) { // sets this._writev under the hood // An optional error can be passed as the first argument next() } }); ``` ### Readable ```javascript var readable = new stream.Readable({ read: function(n) { // sets this._read under the hood // push data onto the read queue, passing null // will signal the end of the stream (EOF) this.push(chunk); } }); ``` ### Transform ```javascript var transform = new stream.Transform({ transform: function(chunk, encoding, next) { // sets this._transform under the hood // generate output as many times as needed // this.push(chunk); // call when the current chunk is consumed next(); }, flush: function(done) { // sets this._flush under the hood // generate output as many times as needed // this.push(chunk); done(); } }); ``` ### Writable ```javascript var writable = new stream.Writable({ write: function(chunk, encoding, next) { // sets this._write under the hood // An optional error can be passed as the first argument next() } }); // or var writable = new stream.Writable({ writev: function(chunks, next) { // sets this._writev under the hood // An optional error can be passed as the first argument next() } }); ``` ## Streams: Under the Hood ### Buffering Both Writable and Readable streams will buffer data on an internal object which can be retrieved from `_writableState.getBuffer()` or `_readableState.buffer`, respectively. The amount of data that will potentially be buffered depends on the `highWaterMark` option which is passed into the constructor. Buffering in Readable streams happens when the implementation calls [`stream.push(chunk)`][]. If the consumer of the Stream does not call `stream.read()`, then the data will sit in the internal queue until it is consumed. Buffering in Writable streams happens when the user calls [`stream.write(chunk)`][] repeatedly, even when `write()` returns `false`. The purpose of streams, especially with the `pipe()` method, is to limit the buffering of data to acceptable levels, so that sources and destinations of varying speed will not overwhelm the available memory. ### Compatibility with Older Node.js Versions In versions of Node.js prior to v0.10, the Readable stream interface was simpler, but also less powerful and less useful. * Rather than waiting for you to call the `read()` method, `'data'` events would start emitting immediately. If you needed to do some I/O to decide how to handle data, then you had to store the chunks in some kind of buffer so that they would not be lost. * The [`pause()`][] method was advisory, rather than guaranteed. This meant that you still had to be prepared to receive `'data'` events even when the stream was in a paused state. In Node.js v0.10, the Readable class described below was added. For backwards compatibility with older Node.js programs, Readable streams switch into "flowing mode" when a `'data'` event handler is added, or when the [`resume()`][] method is called. The effect is that, even if you are not using the new `read()` method and `'readable'` event, you no longer have to worry about losing `'data'` chunks. Most programs will continue to function normally. However, this introduces an edge case in the following conditions: * No [`'data'`][] event handler is added. * The [`resume()`][] method is never called. * The stream is not piped to any writable destination. For example, consider the following code: ```javascript // WARNING! BROKEN! net.createServer((socket) => { // we add an 'end' method, but never consume the data socket.on('end', () => { // It will never get here. socket.end('I got your message (but didnt read it)\n'); }); }).listen(1337); ``` In versions of Node.js prior to v0.10, the incoming message data would be simply discarded. However, in Node.js v0.10 and beyond, the socket will remain paused forever. The workaround in this situation is to call the `resume()` method to start the flow of data: ```javascript // Workaround net.createServer((socket) => { socket.on('end', () => { socket.end('I got your message (but didnt read it)\n'); }); // start the flow of data, discarding it. socket.resume(); }).listen(1337); ``` In addition to new Readable streams switching into flowing mode, pre-v0.10 style streams can be wrapped in a Readable class using the `wrap()` method. ### Object Mode Normally, Streams operate on Strings and Buffers exclusively. Streams that are in **object mode** can emit generic JavaScript values other than Buffers and Strings. A Readable stream in object mode will always return a single item from a call to `stream.read(size)`, regardless of what the size argument is. A Writable stream in object mode will always ignore the `encoding` argument to `stream.write(data, encoding)`. The special value `null` still retains its special value for object mode streams. That is, for object mode readable streams, `null` as a return value from `stream.read()` indicates that there is no more data, and [`stream.push(null)`][] will signal the end of stream data (`EOF`). No streams in Node.js core are object mode streams. This pattern is only used by userland streaming libraries. You should set `objectMode` in your stream child class constructor on the options object. Setting `objectMode` mid-stream is not safe. For Duplex streams `objectMode` can be set exclusively for readable or writable side with `readableObjectMode` and `writableObjectMode` respectively. These options can be used to implement parsers and serializers with Transform streams. ```javascript const util = require('util'); const StringDecoder = require('string_decoder').StringDecoder; const Transform = require('stream').Transform; util.inherits(JSONParseStream, Transform); // Gets \n-delimited JSON string data, and emits the parsed objects function JSONParseStream() { if (!(this instanceof JSONParseStream)) return new JSONParseStream(); Transform.call(this, { readableObjectMode : true }); this._buffer = ''; this._decoder = new StringDecoder('utf8'); } JSONParseStream.prototype._transform = function(chunk, encoding, cb) { this._buffer += this._decoder.write(chunk); // split on newlines var lines = this._buffer.split(/\r?\n/); // keep the last partial line buffered this._buffer = lines.pop(); for (var l = 0; l < lines.length; l++) { var line = lines[l]; try { var obj = JSON.parse(line); } catch (er) { this.emit('error', er); return; } // push the parsed object out to the readable consumer this.push(obj); } cb(); }; JSONParseStream.prototype._flush = function(cb) { // Just handle any leftover var rem = this._buffer.trim(); if (rem) { try { var obj = JSON.parse(rem); } catch (er) { this.emit('error', er); return; } // push the parsed object out to the readable consumer this.push(obj); } cb(); }; ``` ### `stream.read(0)` There are some cases where you want to trigger a refresh of the underlying readable stream mechanisms, without actually consuming any data. In that case, you can call `stream.read(0)`, which will always return null. If the internal read buffer is below the `highWaterMark`, and the stream is not currently reading, then calling `read(0)` will trigger a low-level `_read` call. There is almost never a need to do this. However, you will see some cases in Node.js's internals where this is done, particularly in the Readable stream class internals. ### `stream.push('')` Pushing a zero-byte string or Buffer (when not in [Object mode][]) has an interesting side effect. Because it *is* a call to [`stream.push()`][], it will end the `reading` process. However, it does *not* add any data to the readable buffer, so there's nothing for a user to consume. Very rarely, there are cases where you have no data to provide now, but the consumer of your stream (or, perhaps, another bit of your own code) will know when to check again, by calling `stream.read(0)`. In those cases, you *may* call `stream.push('')`. So far, the only use case for this functionality is in the [`tls.CryptoStream`][] class, which is deprecated in Node.js/io.js v1.0. If you find that you have to use `stream.push('')`, please consider another approach, because it almost certainly indicates that something is horribly wrong. [_read]: #stream_readable_read_size_1 [_write]: #stream_writable_write_chunk_encoding_callback_1 [`'data'`]: #stream_event_data [`'end'`]: #stream_event_end [`'finish'`]: #stream_event_finish [`_read()`]: #stream_readable_read_size_1 [`_read(size)`]: #stream_readable_read_size_1 [`_write()`]: #stream_writable_write_chunk_encoding_callback_1 [`_write(chunk, encoding, callback)`]: #stream_writable_write_chunk_encoding_callback_1 [`end()`]: #stream_writable_end_chunk_encoding_callback [`EventEmitter`]: events.html#events_class_events_eventemitter [`pause()`]: #stream_readable_pause [`pipe()`]: #stream_readable_pipe_destination_options [`process.stderr`]: process.html#process_process_stderr [`process.stdin`]: process.html#process_process_stdin [`process.stdout`]: process.html#process_process_stdout [`readable.resume()`]: #stream_readable_resume [`resume()`]: #stream_readable_resume [`stdout`]: process.html#process_process_stdout [`stream.push()`]: #stream_readable_push_chunk_encoding [`stream.push(chunk)`]: #stream_readable_push_chunk_encoding [`stream.push(null)`]: #stream_readable_push_chunk_encoding [`stream.write(chunk)`]: #stream_writable_write_chunk_encoding_callback [`tls.CryptoStream`]: tls.html#tls_class_cryptostream [`unpipe()`]: #stream_readable_unpipe_destination [`unpipe()`]: #stream_readable_unpipe_destination [`util.inherits`]: util.html#util_util_inherits_constructor_superconstructor [`writable.write(chunk)`]: #stream_writable_write_chunk_encoding_callback [`write()`]: #stream_writable_write_chunk_encoding_callback [`write(chunk, encoding, callback)`]: #stream_writable_write_chunk_encoding_callback [API for Stream Consumers]: #stream_api_for_stream_consumers [API for Stream Implementors]: #stream_api_for_stream_implementors [child process stdin]: child_process.html#child_process_child_stdin [child process stdout and stderr]: child_process.html#child_process_child_stdout [crypto streams]: crypto.html [crypto]: crypto.html [Duplex]: #stream_class_stream_duplex [fs read streams]: fs.html#fs_class_fs_readstream [fs write streams]: fs.html#fs_class_fs_writestream [http requests, on the client]: http.html#http_class_http_clientrequest [http requests, on the server]: http.html#http_http_incomingmessage [http responses, on the client]: http.html#http_http_incomingmessage [http responses, on the server]: http.html#http_class_http_serverresponse [Object mode]: #stream_object_mode [Readable]: #stream_class_stream_readable [request to an HTTP server]: http.html#http_http_incomingmessage [tcp sockets]: net.html#net_class_net_socket [Transform]: #stream_class_stream_transform [unpiped]: #stream_readable_unpipe_destination [Writable]: #stream_class_stream_writable [zlib streams]: zlib.html [zlib]: zlib.html [_transform]: #stream_transform_transform_chunk_encoding_callback [`_transform()`]: #stream_transform_transform_chunk_encoding_callback [`_transform(chunk, encoding, callback)`]: #stream_transform_transform_chunk_encoding_callback [_flush]: #stream_transform_flush_callback [`_flush()`]: #stream_transform_flush_callback [`_flush(callback)`]: #stream_transform_flush_callback [_writev]: #stream_writable_writev_chunks_callback [`_writev()`]: #stream_writable_writev_chunks_callback [`_writev(chunks, callback)`]: #stream_writable_writev_chunks_callback node-v4.2.6/doc/api/string_decoder.html000644 000766 000024 00000012534 12650222331 020146 0ustar00iojsstaff000000 000000 StringDecoder Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


StringDecoder#

Stability: 2 - Stable

To use this module, do require('string_decoder'). StringDecoder decodes a buffer to a string. It is a simple interface to buffer.toString() but provides additional support for utf8.

const StringDecoder = require('string_decoder').StringDecoder;
const decoder = new StringDecoder('utf8');

const cent = new Buffer([0xC2, 0xA2]);
console.log(decoder.write(cent));

const euro = new Buffer([0xE2, 0x82, 0xAC]);
console.log(decoder.write(euro));

Class: StringDecoder#

Accepts a single argument, encoding which defaults to 'utf8'.

decoder.end()#

Returns any trailing bytes that were left in the buffer.

decoder.write(buffer)#

Returns a decoded string.

node-v4.2.6/doc/api/string_decoder.json000644 000766 000024 00000003551 12650222331 020152 0ustar00iojsstaff000000 000000 { "source": "doc/api/string_decoder.markdown", "modules": [ { "textRaw": "StringDecoder", "name": "stringdecoder", "stability": 2, "stabilityText": "Stable", "desc": "

To use this module, do require('string_decoder'). StringDecoder decodes a\nbuffer to a string. It is a simple interface to buffer.toString() but provides\nadditional support for utf8.\n\n

\n
const StringDecoder = require('string_decoder').StringDecoder;\nconst decoder = new StringDecoder('utf8');\n\nconst cent = new Buffer([0xC2, 0xA2]);\nconsole.log(decoder.write(cent));\n\nconst euro = new Buffer([0xE2, 0x82, 0xAC]);\nconsole.log(decoder.write(euro));
\n", "classes": [ { "textRaw": "Class: StringDecoder", "type": "class", "name": "StringDecoder", "desc": "

Accepts a single argument, encoding which defaults to 'utf8'.\n\n

\n", "methods": [ { "textRaw": "decoder.end()", "type": "method", "name": "end", "desc": "

Returns any trailing bytes that were left in the buffer.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "decoder.write(buffer)", "type": "method", "name": "write", "desc": "

Returns a decoded string.\n

\n", "signatures": [ { "params": [ { "name": "buffer" } ] } ] } ] } ], "type": "module", "displayName": "StringDecoder" } ] } node-v4.2.6/doc/api/string_decoder.markdown000644 000766 000024 00000001342 12650222326 021023 0ustar00iojsstaff000000 000000 # StringDecoder Stability: 2 - Stable To use this module, do `require('string_decoder')`. StringDecoder decodes a buffer to a string. It is a simple interface to `buffer.toString()` but provides additional support for utf8. const StringDecoder = require('string_decoder').StringDecoder; const decoder = new StringDecoder('utf8'); const cent = new Buffer([0xC2, 0xA2]); console.log(decoder.write(cent)); const euro = new Buffer([0xE2, 0x82, 0xAC]); console.log(decoder.write(euro)); ## Class: StringDecoder Accepts a single argument, `encoding` which defaults to `'utf8'`. ### decoder.end() Returns any trailing bytes that were left in the buffer. ### decoder.write(buffer) Returns a decoded string. node-v4.2.6/doc/api/synopsis.html000644 000766 000024 00000011113 12650222331 017032 0ustar00iojsstaff000000 000000 Synopsis Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Table of Contents

Synopsis#

An example of a web server written with Node.js which responds with 'Hello World':

const http = require('http');

http.createServer( (request, response) => {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8124);

console.log('Server running at http://127.0.0.1:8124/');

To run the server, put the code into a file called example.js and execute it with the node program

> node example.js
Server running at http://127.0.0.1:8124/

All of the examples in the documentation can be run similarly.

node-v4.2.6/doc/api/synopsis.json000644 000766 000024 00000001577 12650222331 017054 0ustar00iojsstaff000000 000000 { "source": "doc/api/synopsis.markdown", "miscs": [ { "textRaw": "Synopsis", "name": "Synopsis", "type": "misc", "desc": "

An example of a [web server][] written with Node.js which responds with\n'Hello World':\n\n

\n
const http = require('http');\n\nhttp.createServer( (request, response) => {\n  response.writeHead(200, {'Content-Type': 'text/plain'});\n  response.end('Hello World\\n');\n}).listen(8124);\n\nconsole.log('Server running at http://127.0.0.1:8124/');
\n

To run the server, put the code into a file called example.js and execute\nit with the node program\n\n

\n
> node example.js\nServer running at http://127.0.0.1:8124/
\n

All of the examples in the documentation can be run similarly.\n\n

\n" } ] } node-v4.2.6/doc/api/synopsis.markdown000644 000766 000024 00000001205 12650222326 017715 0ustar00iojsstaff000000 000000 # Synopsis An example of a [web server][] written with Node.js which responds with `'Hello World'`: const http = require('http'); http.createServer( (request, response) => { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end('Hello World\n'); }).listen(8124); console.log('Server running at http://127.0.0.1:8124/'); To run the server, put the code into a file called `example.js` and execute it with the node program > node example.js Server running at http://127.0.0.1:8124/ All of the examples in the documentation can be run similarly. [web server]: http.html node-v4.2.6/doc/api/timers.html000644 000766 000024 00000021501 12650222331 016450 0ustar00iojsstaff000000 000000 Timers Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Timers#

Stability: 3 - Locked

All of the timer functions are globals. You do not need to require() this module in order to use them.

clearImmediate(immediateObject)#

Stops an immediate from triggering.

clearInterval(intervalObject)#

Stops an interval from triggering.

clearTimeout(timeoutObject)#

Prevents a timeout from triggering.

ref()#

If you had previously unref()d a timer you can call ref() to explicitly request the timer hold the program open. If the timer is already refd calling ref again will have no effect.

Returns the timer.

setImmediate(callback[, arg][, ...])#

To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout and setInterval. Returns an immediateObject for possible use with clearImmediate(). Optionally you can also pass arguments to the callback.

Callbacks for immediates are queued in the order in which they were created. The entire callback queue is processed every event loop iteration. If you queue an immediate from inside an executing callback, that immediate won't fire until the next event loop iteration.

setInterval(callback, delay[, arg][, ...])#

To schedule the repeated execution of callback every delay milliseconds. Returns a intervalObject for possible use with clearInterval(). Optionally you can also pass arguments to the callback.

To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the delay.

setTimeout(callback, delay[, arg][, ...])#

To schedule execution of a one-time callback after delay milliseconds. Returns a timeoutObject for possible use with clearTimeout(). Optionally you can also pass arguments to the callback.

It is important to note that your callback will probably not be called in exactly delay milliseconds - Node.js makes no guarantees about the exact timing of when the callback will fire, nor of the ordering things will fire in. The callback will be called as close as possible to the time specified.

To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, the timeout is executed immediately, as if the delay was set to 1.

unref()#

The opaque value returned by setTimeout and setInterval also has the method timer.unref() which will allow you to create a timer that is active but if it is the only item left in the event loop, it won't keep the program running. If the timer is already unrefd calling unref again will have no effect.

In the case of setTimeout when you unref you create a separate timer that will wakeup the event loop, creating too many of these may adversely effect event loop performance -- use wisely.

Returns the timer.

node-v4.2.6/doc/api/timers.json000644 000766 000024 00000014772 12650222331 016471 0ustar00iojsstaff000000 000000 { "source": "doc/api/timers.markdown", "modules": [ { "textRaw": "Timers", "name": "timers", "stability": 3, "stabilityText": "Locked", "desc": "

All of the timer functions are globals. You do not need to require()\nthis module in order to use them.\n\n

\n", "methods": [ { "textRaw": "clearImmediate(immediateObject)", "type": "method", "name": "clearImmediate", "desc": "

Stops an immediate from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "immediateObject" } ] } ] }, { "textRaw": "clearInterval(intervalObject)", "type": "method", "name": "clearInterval", "desc": "

Stops an interval from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "intervalObject" } ] } ] }, { "textRaw": "clearTimeout(timeoutObject)", "type": "method", "name": "clearTimeout", "desc": "

Prevents a timeout from triggering.\n\n

\n", "signatures": [ { "params": [ { "name": "timeoutObject" } ] } ] }, { "textRaw": "ref()", "type": "method", "name": "ref", "desc": "

If you had previously unref()d a timer you can call ref() to explicitly\nrequest the timer hold the program open. If the timer is already refd calling\nref again will have no effect.\n\n

\n

Returns the timer.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "setImmediate(callback[, arg][, ...])", "type": "method", "name": "setImmediate", "desc": "

To schedule the "immediate" execution of callback after I/O events\ncallbacks and before [setTimeout][] and [setInterval][]. Returns an\nimmediateObject for possible use with clearImmediate(). Optionally you\ncan also pass arguments to the callback.\n\n

\n

Callbacks for immediates are queued in the order in which they were created.\nThe entire callback queue is processed every event loop iteration. If you queue\nan immediate from inside an executing callback, that immediate won't fire\nuntil the next event loop iteration.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "setInterval(callback, delay[, arg][, ...])", "type": "method", "name": "setInterval", "desc": "

To schedule the repeated execution of callback every delay milliseconds.\nReturns a intervalObject for possible use with clearInterval(). Optionally\nyou can also pass arguments to the callback.\n\n

\n

To follow browser behavior, when using delays larger than 2147483647\nmilliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the\ndelay.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "delay" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "setTimeout(callback, delay[, arg][, ...])", "type": "method", "name": "setTimeout", "desc": "

To schedule execution of a one-time callback after delay milliseconds. Returns a\ntimeoutObject for possible use with clearTimeout(). Optionally you can\nalso pass arguments to the callback.\n\n

\n

It is important to note that your callback will probably not be called in exactly\ndelay milliseconds - Node.js makes no guarantees about the exact timing of when\nthe callback will fire, nor of the ordering things will fire in. The callback will\nbe called as close as possible to the time specified.\n\n

\n

To follow browser behavior, when using delays larger than 2147483647\nmilliseconds (approximately 25 days) or less than 1, the timeout is executed\nimmediately, as if the delay was set to 1.\n\n

\n", "signatures": [ { "params": [ { "name": "callback" }, { "name": "delay" }, { "name": "arg", "optional": true }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "unref()", "type": "method", "name": "unref", "desc": "

The opaque value returned by [setTimeout][] and [setInterval][] also has the method\ntimer.unref() which will allow you to create a timer that is active but if\nit is the only item left in the event loop, it won't keep the program running.\nIf the timer is already unrefd calling unref again will have no effect.\n\n

\n

In the case of setTimeout when you unref you create a separate timer that\nwill wakeup the event loop, creating too many of these may adversely effect\nevent loop performance -- use wisely.\n\n

\n

Returns the timer.\n\n

\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "Timers" } ] } node-v4.2.6/doc/api/timers.markdown000644 000766 000024 00000005627 12650222326 017345 0ustar00iojsstaff000000 000000 # Timers Stability: 3 - Locked All of the timer functions are globals. You do not need to `require()` this module in order to use them. ## clearImmediate(immediateObject) Stops an immediate from triggering. ## clearInterval(intervalObject) Stops an interval from triggering. ## clearTimeout(timeoutObject) Prevents a timeout from triggering. ## ref() If you had previously `unref()`d a timer you can call `ref()` to explicitly request the timer hold the program open. If the timer is already `ref`d calling `ref` again will have no effect. Returns the timer. ## setImmediate(callback[, arg][, ...]) To schedule the "immediate" execution of `callback` after I/O events callbacks and before [`setTimeout`][] and [`setInterval`][]. Returns an `immediateObject` for possible use with `clearImmediate()`. Optionally you can also pass arguments to the callback. Callbacks for immediates are queued in the order in which they were created. The entire callback queue is processed every event loop iteration. If you queue an immediate from inside an executing callback, that immediate won't fire until the next event loop iteration. ## setInterval(callback, delay[, arg][, ...]) To schedule the repeated execution of `callback` every `delay` milliseconds. Returns a `intervalObject` for possible use with `clearInterval()`. Optionally you can also pass arguments to the callback. To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, Node.js will use 1 as the `delay`. ## setTimeout(callback, delay[, arg][, ...]) To schedule execution of a one-time `callback` after `delay` milliseconds. Returns a `timeoutObject` for possible use with `clearTimeout()`. Optionally you can also pass arguments to the callback. It is important to note that your callback will probably not be called in exactly `delay` milliseconds - Node.js makes no guarantees about the exact timing of when the callback will fire, nor of the ordering things will fire in. The callback will be called as close as possible to the time specified. To follow browser behavior, when using delays larger than 2147483647 milliseconds (approximately 25 days) or less than 1, the timeout is executed immediately, as if the `delay` was set to 1. ## unref() The opaque value returned by [`setTimeout`][] and [`setInterval`][] also has the method `timer.unref()` which will allow you to create a timer that is active but if it is the only item left in the event loop, it won't keep the program running. If the timer is already `unref`d calling `unref` again will have no effect. In the case of `setTimeout` when you `unref` you create a separate timer that will wakeup the event loop, creating too many of these may adversely effect event loop performance -- use wisely. Returns the timer. [`setInterval`]: timers.html#timers_setinterval_callback_delay_arg [`setTimeout`]: timers.html#timers_settimeout_callback_delay_arg node-v4.2.6/doc/api/tls.html000644 000766 000024 00000145461 12650222331 015763 0ustar00iojsstaff000000 000000 TLS (SSL) Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


TLS (SSL)#

Stability: 2 - Stable

Use require('tls') to access this module.

The tls module uses OpenSSL to provide Transport Layer Security and/or Secure Socket Layer: encrypted stream communication.

TLS/SSL is a public/private key infrastructure. Each client and each server must have a private key. A private key is created like this:

openssl genrsa -out ryans-key.pem 2048

All servers and some clients need to have a certificate. Certificates are public keys signed by a Certificate Authority or self-signed. The first step to getting a certificate is to create a "Certificate Signing Request" (CSR) file. This is done with:

openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem

To create a self-signed certificate with the CSR, do this:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

Alternatively you can send the CSR to a Certificate Authority for signing.

For Perfect Forward Secrecy, it is required to generate Diffie-Hellman parameters:

openssl dhparam -outform PEM -out dhparam.pem 2048

To create .pfx or .p12, do this:

openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
    -certfile ca-cert.pem -out agent5.pfx
  • in: certificate
  • inkey: private key
  • certfile: all CA certs concatenated in one file like cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

Client-initiated renegotiation attack mitigation#

The TLS protocol lets the client renegotiate certain aspects of the TLS session. Unfortunately, session renegotiation requires a disproportional amount of server-side resources, which makes it a potential vector for denial-of-service attacks.

To mitigate this, renegotiations are limited to three times every 10 minutes. An error is emitted on the tls.TLSSocket instance when the threshold is exceeded. The limits are configurable:

  • tls.CLIENT_RENEG_LIMIT: renegotiation limit, default is 3.

  • tls.CLIENT_RENEG_WINDOW: renegotiation window in seconds, default is 10 minutes.

Don't change the defaults unless you know what you are doing.

To test your server, connect to it with openssl s_client -connect address:port and tap R<CR> (that's the letter R followed by a carriage return) a few times.

Modifying the Default TLS Cipher suite#

Node.js is built with a default suite of enabled and disabled TLS ciphers. Currently, the default cipher suite is:

ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-AES256-GCM-SHA384:
DHE-RSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:
DHE-RSA-AES128-SHA256:
ECDHE-RSA-AES256-SHA384:
DHE-RSA-AES256-SHA384:
ECDHE-RSA-AES256-SHA256:
DHE-RSA-AES256-SHA256:
HIGH:
!aNULL:
!eNULL:
!EXPORT:
!DES:
!RC4:
!MD5:
!PSK:
!SRP:
!CAMELLIA

This default can be overriden entirely using the --tls-cipher-list command line switch. For instance, the following makes ECDHE-RSA-AES128-GCM-SHA256:!RC4 the default TLS cipher suite:

node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"

Note that the default cipher suite included within Node.js has been carefully selected to reflect current security best practices and risk mitigation. Changing the default cipher suite can have a significant impact on the security of an application. The --tls-cipher-list switch should by used only if absolutely necessary.

NPN and SNI#

NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS handshake extensions allowing you:

  • NPN - to use one TLS server for multiple protocols (HTTP, SPDY)
  • SNI - to use one TLS server for multiple hostnames with different SSL certificates.

Perfect Forward Secrecy#

The term "Forward Secrecy" or "Perfect Forward Secrecy" describes a feature of key-agreement (i.e. key-exchange) methods. Practically it means that even if the private key of a (your) server is compromised, communication can only be decrypted by eavesdroppers if they manage to obtain the key-pair specifically generated for each session.

This is achieved by randomly generating a key pair for key-agreement on every handshake (in contrary to the same key for all sessions). Methods implementing this technique, thus offering Perfect Forward Secrecy, are called "ephemeral".

Currently two methods are commonly used to achieve Perfect Forward Secrecy (note the character "E" appended to the traditional abbreviations):

  • DHE - An ephemeral version of the Diffie Hellman key-agreement protocol.
  • ECDHE - An ephemeral version of the Elliptic Curve Diffie Hellman key-agreement protocol.

Ephemeral methods may have some performance drawbacks, because key generation is expensive.

Class: CryptoStream#

Stability: 0 - Deprecated: Use tls.TLSSocket instead.

This is an encrypted stream.

cryptoStream.bytesWritten#

A proxy to the underlying socket's bytesWritten accessor, this will return the total bytes written to the socket, including the TLS overhead.

Class: SecurePair#

Returned by tls.createSecurePair.

Event: 'secure'#

The event is emitted from the SecurePair once the pair has successfully established a secure connection.

Similarly to the checking for the server 'secureConnection' event, pair.cleartext.authorized should be checked to confirm whether the certificate used properly authorized.

Class: tls.Server#

This class is a subclass of net.Server and has the same methods on it. Instead of accepting just raw TCP connections, this accepts encrypted connections using TLS or SSL.

Event: 'clientError'#

function (exception, tlsSocket) { }

When a client connection emits an 'error' event before secure connection is established - it will be forwarded here.

tlsSocket is the tls.TLSSocket that the error originated from.

Event: 'newSession'#

function (sessionId, sessionData, callback) { }

Emitted on creation of TLS session. May be used to store sessions in external storage. callback must be invoked eventually, otherwise no data will be sent or received from secure connection.

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

Event: 'OCSPRequest'#

function (certificate, issuer, callback) { }

Emitted when the client sends a certificate status request. You could parse server's current certificate to obtain OCSP url and certificate id, and after obtaining OCSP response invoke callback(null, resp), where resp is a Buffer instance. Both certificate and issuer are a Buffer DER-representations of the primary and issuer's certificates. They could be used to obtain OCSP certificate id and OCSP endpoint url.

Alternatively, callback(null, null) could be called, meaning that there is no OCSP response.

Calling callback(err) will result in a socket.destroy(err) call.

Typical flow:

  1. Client connects to server and sends 'OCSPRequest' to it (via status info extension in ClientHello.)
  2. Server receives request and invokes 'OCSPRequest' event listener if present
  3. Server grabs OCSP url from either certificate or issuer and performs an OCSP request to the CA
  4. Server receives OCSPResponse from CA and sends it back to client via callback argument
  5. Client validates the response and either destroys socket or performs a handshake.

NOTE: issuer could be null, if the certificate is self-signed or if the issuer is not in the root certificates list. (You could provide an issuer via ca option.)

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

NOTE: you may want to use some npm module like asn1.js to parse the certificates.

Event: 'resumeSession'#

function (sessionId, callback) { }

Emitted when client wants to resume previous TLS session. Event listener may perform lookup in external storage using given sessionId, and invoke callback(null, sessionData) once finished. If session can't be resumed (i.e. doesn't exist in storage) one may call callback(null, null). Calling callback(err) will terminate incoming connection and destroy socket.

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

Here's an example for using TLS session resumption:

var tlsSessionStore = {};
server.on('newSession', (id, data, cb) => {
  tlsSessionStore[id.toString('hex')] = data;
  cb();
});
server.on('resumeSession', (id, cb) => {
  cb(null, tlsSessionStore[id.toString('hex')] || null);
});

Event: 'secureConnection'#

function (tlsSocket) {}

This event is emitted after a new connection has been successfully handshaked. The argument is an instance of tls.TLSSocket. It has all the common stream methods and events.

socket.authorized is a boolean value which indicates if the client has verified by one of the supplied certificate authorities for the server. If socket.authorized is false, then socket.authorizationError is set to describe how authorization failed. Implied but worth mentioning: depending on the settings of the TLS server, you unauthorized connections may be accepted. socket.npnProtocol is a string containing selected NPN protocol. socket.servername is a string containing servername requested with SNI.

server.addContext(hostname, context)#

Add secure context that will be used if client request's SNI hostname is matching passed hostname (wildcards can be used). context can contain key, cert, ca and/or any other properties from tls.createSecureContext options argument.

server.address()#

Returns the bound address, the address family name and port of the server as reported by the operating system. See net.Server.address() for more information.

server.close([callback])#

Stops the server from accepting new connections. This function is asynchronous, the server is finally closed when the server emits a 'close' event. Optionally, you can pass a callback to listen for the 'close' event.

server.connections#

The number of concurrent connections on the server.

server.getTicketKeys()#

Returns Buffer instance holding the keys currently used for encryption/decryption of the TLS Session Tickets

server.listen(port[, hostname][, callback])#

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A port value of zero will assign a random port.

This function is asynchronous. The last parameter callback will be called when the server has been bound.

See net.Server for more information.

server.maxConnections#

Set this property to reject connections when the server's connection count gets high.

server.setTicketKeys(keys)#

Updates the keys for encryption/decryption of the TLS Session Tickets.

NOTE: the buffer should be 48 bytes long. See server ticketKeys option for more information oh how it is going to be used.

NOTE: the change is effective only for the future server connections. Existing or currently pending server connections will use previous keys.

Class: tls.TLSSocket#

This is a wrapped version of net.Socket that does transparent encryption of written data and all required TLS negotiation.

This instance implements a duplex Stream interfaces. It has all the common stream methods and events.

Methods that return TLS connection meta data (e.g. getPeerCertificate will only return data while the connection is open.

new tls.TLSSocket(socket[, options])#

Construct a new TLSSocket object from existing TCP socket.

socket is an instance of net.Socket

options is an optional object that might contain following properties:

  • secureContext: An optional TLS context object from tls.createSecureContext( ... )

  • isServer: If true - TLS socket will be instantiated in server-mode. Default: false

  • server: An optional net.Server instance

  • requestCert: Optional, see tls.createSecurePair

  • rejectUnauthorized: Optional, see tls.createSecurePair

  • NPNProtocols: Optional, see tls.createServer

  • SNICallback: Optional, see tls.createServer

  • session: Optional, a Buffer instance, containing TLS session

  • requestOCSP: Optional, if true - OCSP status request extension would be added to client hello, and 'OCSPResponse' event will be emitted on socket before establishing secure communication

Event: 'OCSPResponse'#

function (response) { }

This event will be emitted if requestOCSP option was set. response is a buffer object, containing server's OCSP response.

Traditionally, the response is a signed object from the server's CA that contains information about server's certificate revocation status.

Event: 'secureConnect'#

This event is emitted after a new connection has been successfully handshaked. The listener will be called no matter if the server's certificate was authorized or not. It is up to the user to test tlsSocket.authorized to see if the server certificate was signed by one of the specified CAs. If tlsSocket.authorized === false then the error can be found in tlsSocket.authorizationError. Also if NPN was used - you can check tlsSocket.npnProtocol for negotiated protocol.

tlsSocket.address()#

Returns the bound address, the address family name and port of the underlying socket as reported by the operating system. Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.authorized#

A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false

tlsSocket.authorizationError#

The reason why the peer's certificate has not been verified. This property becomes available only when tlsSocket.authorized === false.

tlsSocket.encrypted#

Static boolean value, always true. May be used to distinguish TLS sockets from regular ones.

tlsSocket.getCipher()#

Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection.

Example: { name: 'AES256-SHA', version: 'TLSv1/SSLv3' }

See SSL_CIPHER_get_name() and SSL_CIPHER_get_version() in https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS for more information.

tlsSocket.getPeerCertificate([ detailed ])#

Returns an object representing the peer's certificate. The returned object has some properties corresponding to the field of the certificate. If detailed argument is true - the full chain with issuer property will be returned, if false - only the top certificate without issuer property.

Example:

{ subject:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuerInfo:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuer:
   { ... another certificate ... },
  raw: < RAW DER buffer >,
  valid_from: 'Nov 11 09:52:22 2009 GMT',
  valid_to: 'Nov  6 09:52:22 2029 GMT',
  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
  serialNumber: 'B9B0D332A1AA5635' }

If the peer does not provide a certificate, it returns null or an empty object.

tlsSocket.getSession()#

Return ASN.1 encoded TLS session or undefined if none was negotiated. Could be used to speed up handshake establishment when reconnecting to the server.

tlsSocket.getTLSTicket()#

NOTE: Works only with client TLS sockets. Useful only for debugging, for session reuse provide session option to tls.connect.

Return TLS session ticket or undefined if none was negotiated.

tlsSocket.localPort#

The numeric representation of the local port.

tlsSocket.localAddress#

The string representation of the local IP address.

tlsSocket.remoteAddress#

The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'.

tlsSocket.remoteFamily#

The string representation of the remote IP family. 'IPv4' or 'IPv6'.

tlsSocket.remotePort#

The numeric representation of the remote port. For example, 443.

tlsSocket.renegotiate(options, callback)#

Initiate TLS renegotiation process. The options may contain the following fields: rejectUnauthorized, requestCert (See tls.createServer for details). callback(err) will be executed with null as err, once the renegotiation is successfully completed.

NOTE: Can be used to request peer's certificate after the secure connection has been established.

ANOTHER NOTE: When running as the server, socket will be destroyed with an error after handshakeTimeout timeout.

tlsSocket.setMaxSendFragment(size)#

Set maximum TLS fragment size (default and maximum value is: 16384, minimum is: 512). Returns true on success, false otherwise.

Smaller fragment size decreases buffering latency on the client: large fragments are buffered by the TLS layer until the entire fragment is received and its integrity is verified; large fragments can span multiple roundtrips, and their processing can be delayed due to packet loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, which may decrease overall server throughput.

tls.connect(options[, callback])#

tls.connect(port[, host][, options][, callback])#

Creates a new client connection to the given port and host (old API) or options.port and options.host. (If host is omitted, it defaults to localhost.) options should be an object which specifies:

  • host: Host the client should connect to

  • port: Port the client should connect to

  • socket: Establish secure connection on a given socket rather than creating a new socket. If this option is specified, host and port are ignored.

  • path: Creates unix socket connection to path. If this option is specified, host and port are ignored.

  • pfx: A string or Buffer containing the private key, certificate and CA certs of the client in PFX or PKCS12 format.

  • key: A string or Buffer containing the private key of the client in PEM format. (Could be an array of keys).

  • passphrase: A string of passphrase for the private key or pfx.

  • cert: A string or Buffer containing the certificate key of the client in PEM format. (Could be an array of certs).

  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

  • ciphers: A string describing the ciphers to use or exclude, separated by :. Uses the same default cipher suite as tls.createServer.

  • rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error' event is emitted if verification fails; err.code contains the OpenSSL error code. Default: true.

  • NPNProtocols: An array of strings or Buffers containing supported NPN protocols. Buffers should have following format: 0x05hello0x05world, where first byte is next protocol name's length. (Passing array should usually be much simpler: ['hello', 'world'].)

  • servername: Servername for SNI (Server Name Indication) TLS extension.

  • checkServerIdentity(servername, cert): Provide an override for checking server's hostname against the certificate. Should return an error if verification fails. Return undefined if passing.

  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

  • session: A Buffer instance, containing TLS session.

The callback parameter will be added as a listener for the 'secureConnect' event.

tls.connect() returns a tls.TLSSocket object.

Here is an example of a client of echo server as described previously:

const tls = require('tls');
const fs = require('fs');

const options = {
  // These are necessary only if using the client certificate authentication
  key: fs.readFileSync('client-key.pem'),
  cert: fs.readFileSync('client-cert.pem'),

  // This is necessary only if the server uses the self-signed certificate
  ca: [ fs.readFileSync('server-cert.pem') ]
};

var socket = tls.connect(8000, options, () => {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
  console.log(data);
});
socket.on('end', () => {
  server.close();
});

Or

const tls = require('tls');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('client.pfx')
};

var socket = tls.connect(8000, options, () => {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', (data) => {
  console.log(data);
});
socket.on('end', () => {
  server.close();
});

tls.createSecureContext(details)#

Creates a credentials object, with the optional details being a dictionary with keys:

  • pfx : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
  • key: A string or Buffer containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format {pem: key, passphrase: passphrase}. (Required)
  • passphrase : A string of passphrase for the private key or pfx
  • cert : A string holding the PEM encoded certificate
  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
  • ciphers: A string describing the ciphers to use or exclude. Consult https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT for details on the format.
  • honorCipherOrder : When choosing a cipher, use the server's preferences instead of the client preferences. For further details see tls module documentation.

If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.

tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])#

Creates a new secure pair object with two streams, one of which reads/writes encrypted data, and one reads/writes cleartext data. Generally the encrypted one is piped to/from an incoming encrypted data stream, and the cleartext one is used as a replacement for the initial encrypted stream.

  • credentials: A secure context object from tls.createSecureContext( ... )

  • isServer: A boolean indicating whether this tls connection should be opened as a server or a client.

  • requestCert: A boolean indicating whether a server should request a certificate from a connecting client. Only applies to server connections.

  • rejectUnauthorized: A boolean indicating whether a server should automatically reject clients with invalid certificates. Only applies to servers with requestCert enabled.

tls.createSecurePair() returns a SecurePair object with cleartext and encrypted stream properties.

NOTE: cleartext has the same APIs as tls.TLSSocket

tls.createServer(options[, secureConnectionListener])#

Creates a new tls.Server. The connectionListener argument is automatically set as a listener for the 'secureConnection' event. The options object has these possibilities:

  • pfx: A string or Buffer containing the private key, certificate and CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with the key, cert and ca options.)

  • key: A string or Buffer containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format {pem: key, passphrase: passphrase}. (Required)

  • passphrase: A string of passphrase for the private key or pfx.

  • cert: A string or Buffer containing the certificate key of the server in PEM format. (Could be an array of certs). (Required)

  • ca: A string, Buffer or array of strings or Buffers of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections.

  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)

  • ciphers: A string describing the ciphers to use or exclude, separated by :. The default cipher suite is:

    ECDHE-RSA-AES128-GCM-SHA256:
    ECDHE-ECDSA-AES128-GCM-SHA256:
    ECDHE-RSA-AES256-GCM-SHA384:
    ECDHE-ECDSA-AES256-GCM-SHA384:
    DHE-RSA-AES128-GCM-SHA256:
    ECDHE-RSA-AES128-SHA256:
    DHE-RSA-AES128-SHA256:
    ECDHE-RSA-AES256-SHA384:
    DHE-RSA-AES256-SHA384:
    ECDHE-RSA-AES256-SHA256:
    DHE-RSA-AES256-SHA256:
    HIGH:
    !aNULL:
    !eNULL:
    !EXPORT:
    !DES:
    !RC4:
    !MD5:
    !PSK:
    !SRP:
    !CAMELLIA

    The default cipher suite prefers GCM ciphers for Chrome's 'modern cryptography' setting and also prefers ECDHE and DHE ciphers for Perfect Forward secrecy, while offering some backward compatibiltity.

    128 bit AES is preferred over 192 and 256 bit AES in light of specific attacks affecting larger AES key sizes.

    Old clients that rely on insecure and deprecated RC4 or DES-based ciphers (like Internet Explorer 6) aren't able to complete the handshake with the default configuration. If you absolutely must support these clients, the TLS recommendations may offer a compatible cipher suite. For more details on the format, see the OpenSSL cipher list format documentation.

  • ecdhCurve: A string describing a named curve to use for ECDH key agreement or false to disable ECDH.

    Defaults to prime256v1 (NIST P-256). Use crypto.getCurves() to obtain a list of available curve names. On recent releases, openssl ecparam -list_curves will also display the name and description of each available elliptic curve.

  • dhparam: A string or Buffer containing Diffie Hellman parameters, required for Perfect Forward Secrecy. Use openssl dhparam to create it. Its key length should be greater than or equal to 1024 bits, otherwise it throws an error. It is strongly recommended to use 2048 bits or more for stronger security. If omitted or invalid, it is silently discarded and DHE ciphers won't be available.

  • handshakeTimeout: Abort the connection if the SSL/TLS handshake does not finish in this many milliseconds. The default is 120 seconds.

    A 'clientError' is emitted on the tls.Server object whenever a handshake times out.

  • honorCipherOrder : When choosing a cipher, use the server's preferences instead of the client preferences. Default: true.

  • requestCert: If true the server will request a certificate from clients that connect and attempt to verify that certificate. Default: false.

  • rejectUnauthorized: If true the server will reject any connection which is not authorized with the list of supplied CAs. This option only has an effect if requestCert is true. Default: false.

  • NPNProtocols: An array or Buffer of possible NPN protocols. (Protocols should be ordered by their priority).

  • SNICallback(servername, cb): A function that will be called if client supports SNI TLS extension. Two argument will be passed to it: servername, and cb. SNICallback should invoke cb(null, ctx), where ctx is a SecureContext instance. (You can use tls.createSecureContext(...) to get proper SecureContext). If SNICallback wasn't provided - default callback with high-level API will be used (see below).

  • sessionTimeout: An integer specifying the seconds after which TLS session identifiers and TLS session tickets created by the server are timed out. See SSL_CTX_set_timeout for more details.

  • ticketKeys: A 48-byte Buffer instance consisting of 16-byte prefix, 16-byte hmac key, 16-byte AES key. You could use it to accept tls session tickets on multiple instances of tls server.

    NOTE: Automatically shared between cluster module workers.

  • sessionIdContext: A string containing an opaque identifier for session resumption. If requestCert is true, the default is MD5 hash value generated from command-line. (In FIPS mode a truncated SHA1 hash is used instead.) Otherwise, the default is not provided.

  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant SSL_METHODS.

Here is a simple example echo server:

const tls = require('tls');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

  // This is necessary only if the client uses the self-signed certificate.
  ca: [ fs.readFileSync('client-cert.pem') ]
};

var server = tls.createServer(options, (socket) => {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write('welcome!\n');
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, () => {
  console.log('server bound');
});

Or

const tls = require('tls');
const fs = require('fs');

const options = {
  pfx: fs.readFileSync('server.pfx'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

};

var server = tls.createServer(options, (socket) => {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write('welcome!\n');
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, () => {
  console.log('server bound');
});

You can test this server by connecting to it with openssl s_client:

openssl s_client -connect 127.0.0.1:8000

tls.getCiphers()#

Returns an array with the names of the supported SSL ciphers.

Example:

var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
node-v4.2.6/doc/api/tls.json000644 000766 000024 00000153615 12650222331 015770 0ustar00iojsstaff000000 000000 { "source": "doc/api/tls.markdown", "modules": [ { "textRaw": "TLS (SSL)", "name": "tls_(ssl)", "stability": 2, "stabilityText": "Stable", "desc": "

Use require('tls') to access this module.\n\n

\n

The tls module uses OpenSSL to provide Transport Layer Security and/or\nSecure Socket Layer: encrypted stream communication.\n\n

\n

TLS/SSL is a public/private key infrastructure. Each client and each\nserver must have a private key. A private key is created like this:\n\n

\n
openssl genrsa -out ryans-key.pem 2048
\n

All servers and some clients need to have a certificate. Certificates are public\nkeys signed by a Certificate Authority or self-signed. The first step to\ngetting a certificate is to create a "Certificate Signing Request" (CSR)\nfile. This is done with:\n\n

\n
openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem
\n

To create a self-signed certificate with the CSR, do this:\n\n

\n
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
\n

Alternatively you can send the CSR to a Certificate Authority for signing.\n\n

\n

For Perfect Forward Secrecy, it is required to generate Diffie-Hellman\nparameters:\n\n

\n
openssl dhparam -outform PEM -out dhparam.pem 2048
\n

To create .pfx or .p12, do this:\n\n

\n
openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \\\n    -certfile ca-cert.pem -out agent5.pfx
\n
    \n
  • in: certificate
  • \n
  • inkey: private key
  • \n
  • certfile: all CA certs concatenated in one file like\ncat ca1-cert.pem ca2-cert.pem > ca-cert.pem
  • \n
\n", "miscs": [ { "textRaw": "Client-initiated renegotiation attack mitigation", "name": "Client-initiated renegotiation attack mitigation", "type": "misc", "desc": "

The TLS protocol lets the client renegotiate certain aspects of the TLS session.\nUnfortunately, session renegotiation requires a disproportional amount of\nserver-side resources, which makes it a potential vector for denial-of-service\nattacks.\n\n

\n

To mitigate this, renegotiations are limited to three times every 10 minutes. An\nerror is emitted on the [tls.TLSSocket][] instance when the threshold is\nexceeded. The limits are configurable:\n\n

\n
    \n
  • tls.CLIENT_RENEG_LIMIT: renegotiation limit, default is 3.

    \n
  • \n
  • tls.CLIENT_RENEG_WINDOW: renegotiation window in seconds, default is\n10 minutes.

    \n
  • \n
\n

Don't change the defaults unless you know what you are doing.\n\n

\n

To test your server, connect to it with openssl s_client -connect address:port\nand tap R<CR> (that's the letter R followed by a carriage return) a few\ntimes.\n\n\n

\n" }, { "textRaw": "NPN and SNI", "name": "NPN and SNI", "type": "misc", "desc": "

NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS\nhandshake extensions allowing you:\n\n

\n
    \n
  • NPN - to use one TLS server for multiple protocols (HTTP, SPDY)
  • \n
  • SNI - to use one TLS server for multiple hostnames with different SSL\ncertificates.
  • \n
\n" }, { "textRaw": "Perfect Forward Secrecy", "name": "Perfect Forward Secrecy", "type": "misc", "desc": "

The term "[Forward Secrecy]" or "Perfect Forward Secrecy" describes a feature of\nkey-agreement (i.e. key-exchange) methods. Practically it means that even if the\nprivate key of a (your) server is compromised, communication can only be\ndecrypted by eavesdroppers if they manage to obtain the key-pair specifically\ngenerated for each session.\n\n

\n

This is achieved by randomly generating a key pair for key-agreement on every\nhandshake (in contrary to the same key for all sessions). Methods implementing\nthis technique, thus offering Perfect Forward Secrecy, are called "ephemeral".\n\n

\n

Currently two methods are commonly used to achieve Perfect Forward Secrecy (note\nthe character "E" appended to the traditional abbreviations):\n\n

\n
    \n
  • [DHE] - An ephemeral version of the Diffie Hellman key-agreement protocol.
  • \n
  • [ECDHE] - An ephemeral version of the Elliptic Curve Diffie Hellman\nkey-agreement protocol.
  • \n
\n

Ephemeral methods may have some performance drawbacks, because key generation\nis expensive.\n\n\n

\n" } ], "modules": [ { "textRaw": "Modifying the Default TLS Cipher suite", "name": "modifying_the_default_tls_cipher_suite", "desc": "

Node.js is built with a default suite of enabled and disabled TLS ciphers.\nCurrently, the default cipher suite is:\n\n

\n
ECDHE-RSA-AES128-GCM-SHA256:\nECDHE-ECDSA-AES128-GCM-SHA256:\nECDHE-RSA-AES256-GCM-SHA384:\nECDHE-ECDSA-AES256-GCM-SHA384:\nDHE-RSA-AES128-GCM-SHA256:\nECDHE-RSA-AES128-SHA256:\nDHE-RSA-AES128-SHA256:\nECDHE-RSA-AES256-SHA384:\nDHE-RSA-AES256-SHA384:\nECDHE-RSA-AES256-SHA256:\nDHE-RSA-AES256-SHA256:\nHIGH:\n!aNULL:\n!eNULL:\n!EXPORT:\n!DES:\n!RC4:\n!MD5:\n!PSK:\n!SRP:\n!CAMELLIA
\n

This default can be overriden entirely using the --tls-cipher-list command\nline switch. For instance, the following makes\nECDHE-RSA-AES128-GCM-SHA256:!RC4 the default TLS cipher suite:\n\n

\n
node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
\n

Note that the default cipher suite included within Node.js has been carefully\nselected to reflect current security best practices and risk mitigation.\nChanging the default cipher suite can have a significant impact on the security\nof an application. The --tls-cipher-list switch should by used only if\nabsolutely necessary.\n\n\n

\n", "type": "module", "displayName": "Modifying the Default TLS Cipher suite" } ], "classes": [ { "textRaw": "Class: CryptoStream", "type": "class", "name": "CryptoStream", "stability": 0, "stabilityText": "Deprecated: Use [tls.TLSSocket][] instead.", "desc": "

This is an encrypted stream.\n\n

\n", "properties": [ { "textRaw": "cryptoStream.bytesWritten", "name": "bytesWritten", "desc": "

A proxy to the underlying socket's bytesWritten accessor, this will return\nthe total bytes written to the socket, including the TLS overhead.\n\n\n

\n" } ] }, { "textRaw": "Class: SecurePair", "type": "class", "name": "SecurePair", "desc": "

Returned by tls.createSecurePair.\n\n

\n", "events": [ { "textRaw": "Event: 'secure'", "type": "event", "name": "secure", "desc": "

The event is emitted from the SecurePair once the pair has successfully\nestablished a secure connection.\n\n

\n

Similarly to the checking for the server 'secureConnection' event,\npair.cleartext.authorized should be checked to confirm whether the certificate\nused properly authorized.\n\n\n

\n", "params": [] } ] }, { "textRaw": "Class: tls.Server", "type": "class", "name": "tls.Server", "desc": "

This class is a subclass of net.Server and has the same methods on it.\nInstead of accepting just raw TCP connections, this accepts encrypted\nconnections using TLS or SSL.\n\n

\n", "events": [ { "textRaw": "Event: 'clientError'", "type": "event", "name": "clientError", "desc": "

function (exception, tlsSocket) { }\n\n

\n

When a client connection emits an 'error' event before secure connection is\nestablished - it will be forwarded here.\n\n

\n

tlsSocket is the [tls.TLSSocket][] that the error originated from.\n\n

\n", "params": [] }, { "textRaw": "Event: 'newSession'", "type": "event", "name": "newSession", "desc": "

function (sessionId, sessionData, callback) { }\n\n

\n

Emitted on creation of TLS session. May be used to store sessions in external\nstorage. callback must be invoked eventually, otherwise no data will be\nsent or received from secure connection.\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n", "params": [] }, { "textRaw": "Event: 'OCSPRequest'", "type": "event", "name": "OCSPRequest", "desc": "

function (certificate, issuer, callback) { }\n\n

\n

Emitted when the client sends a certificate status request. You could parse\nserver's current certificate to obtain OCSP url and certificate id, and after\nobtaining OCSP response invoke callback(null, resp), where resp is a\nBuffer instance. Both certificate and issuer are a Buffer\nDER-representations of the primary and issuer's certificates. They could be used\nto obtain OCSP certificate id and OCSP endpoint url.\n\n

\n

Alternatively, callback(null, null) could be called, meaning that there is no\nOCSP response.\n\n

\n

Calling callback(err) will result in a socket.destroy(err) call.\n\n

\n

Typical flow:\n\n

\n
    \n
  1. Client connects to server and sends 'OCSPRequest' to it (via status info\nextension in ClientHello.)
  2. \n
  3. Server receives request and invokes 'OCSPRequest' event listener if present
  4. \n
  5. Server grabs OCSP url from either certificate or issuer and performs an\n[OCSP request] to the CA
  6. \n
  7. Server receives OCSPResponse from CA and sends it back to client via\ncallback argument
  8. \n
  9. Client validates the response and either destroys socket or performs a\nhandshake.
  10. \n
\n

NOTE: issuer could be null, if the certificate is self-signed or if the issuer\nis not in the root certificates list. (You could provide an issuer via ca\noption.)\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n

NOTE: you may want to use some npm module like [asn1.js] to parse the\ncertificates.\n\n

\n", "params": [] }, { "textRaw": "Event: 'resumeSession'", "type": "event", "name": "resumeSession", "desc": "

function (sessionId, callback) { }\n\n

\n

Emitted when client wants to resume previous TLS session. Event listener may\nperform lookup in external storage using given sessionId, and invoke\ncallback(null, sessionData) once finished. If session can't be resumed\n(i.e. doesn't exist in storage) one may call callback(null, null). Calling\ncallback(err) will terminate incoming connection and destroy socket.\n\n

\n

NOTE: adding this event listener will have an effect only on connections\nestablished after addition of event listener.\n\n

\n

Here's an example for using TLS session resumption:\n\n

\n
var tlsSessionStore = {};\nserver.on('newSession', (id, data, cb) => {\n  tlsSessionStore[id.toString('hex')] = data;\n  cb();\n});\nserver.on('resumeSession', (id, cb) => {\n  cb(null, tlsSessionStore[id.toString('hex')] || null);\n});
\n", "params": [] }, { "textRaw": "Event: 'secureConnection'", "type": "event", "name": "secureConnection", "desc": "

function (tlsSocket) {}\n\n

\n

This event is emitted after a new connection has been successfully\nhandshaked. The argument is an instance of [tls.TLSSocket][]. It has all the\ncommon stream methods and events.\n\n

\n

socket.authorized is a boolean value which indicates if the\nclient has verified by one of the supplied certificate authorities for the\nserver. If socket.authorized is false, then\nsocket.authorizationError is set to describe how authorization\nfailed. Implied but worth mentioning: depending on the settings of the TLS\nserver, you unauthorized connections may be accepted.\nsocket.npnProtocol is a string containing selected NPN protocol.\nsocket.servername is a string containing servername requested with\nSNI.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "server.addContext(hostname, context)", "type": "method", "name": "addContext", "desc": "

Add secure context that will be used if client request's SNI hostname is\nmatching passed hostname (wildcards can be used). context can contain\nkey, cert, ca and/or any other properties from tls.createSecureContext\noptions argument.\n\n

\n", "signatures": [ { "params": [ { "name": "hostname" }, { "name": "context" } ] } ] }, { "textRaw": "server.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nserver as reported by the operating system. See [net.Server.address()][] for\nmore information.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.close([callback])", "type": "method", "name": "close", "desc": "

Stops the server from accepting new connections. This function is\nasynchronous, the server is finally closed when the server emits a 'close'\nevent. Optionally, you can pass a callback to listen for the 'close' event.\n\n

\n", "signatures": [ { "params": [ { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.getTicketKeys()", "type": "method", "name": "getTicketKeys", "desc": "

Returns Buffer instance holding the keys currently used for\nencryption/decryption of the [TLS Session Tickets][]\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "server.listen(port[, hostname][, callback])", "type": "method", "name": "listen", "desc": "

Begin accepting connections on the specified port and hostname. If the\nhostname is omitted, the server will accept connections on any IPv6 address\n(::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. A\nport value of zero will assign a random port.\n\n

\n

This function is asynchronous. The last parameter callback will be called\nwhen the server has been bound.\n\n

\n

See net.Server for more information.\n\n

\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "hostname", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "server.setTicketKeys(keys)", "type": "method", "name": "setTicketKeys", "desc": "

Updates the keys for encryption/decryption of the [TLS Session Tickets][].\n\n

\n

NOTE: the buffer should be 48 bytes long. See server ticketKeys option for\nmore information oh how it is going to be used.\n\n

\n

NOTE: the change is effective only for the future server connections. Existing\nor currently pending server connections will use previous keys.\n\n\n

\n", "signatures": [ { "params": [ { "name": "keys" } ] } ] } ], "properties": [ { "textRaw": "server.connections", "name": "connections", "desc": "

The number of concurrent connections on the server.\n\n

\n" }, { "textRaw": "server.maxConnections", "name": "maxConnections", "desc": "

Set this property to reject connections when the server's connection count\ngets high.\n\n

\n" } ] }, { "textRaw": "Class: tls.TLSSocket", "type": "class", "name": "tls.TLSSocket", "desc": "

This is a wrapped version of [net.Socket][] that does transparent encryption\nof written data and all required TLS negotiation.\n\n

\n

This instance implements a duplex [Stream][] interfaces. It has all the\ncommon stream methods and events.\n\n

\n

Methods that return TLS connection meta data (e.g. [getPeerCertificate][] will\nonly return data while the connection is open.\n\n

\n" } ], "methods": [ { "textRaw": "new tls.TLSSocket(socket[, options])", "type": "method", "name": "TLSSocket", "desc": "

Construct a new TLSSocket object from existing TCP socket.\n\n

\n

socket is an instance of [net.Socket][]\n\n

\n

options is an optional object that might contain following properties:\n\n

\n
    \n
  • secureContext: An optional TLS context object from\n tls.createSecureContext( ... )

    \n
  • \n
  • isServer: If true - TLS socket will be instantiated in server-mode.\nDefault: false

    \n
  • \n
  • server: An optional [net.Server][] instance

    \n
  • \n
  • requestCert: Optional, see [tls.createSecurePair][]

    \n
  • \n
  • rejectUnauthorized: Optional, see [tls.createSecurePair][]

    \n
  • \n
  • NPNProtocols: Optional, see [tls.createServer][]

    \n
  • \n
  • SNICallback: Optional, see [tls.createServer][]

    \n
  • \n
  • session: Optional, a Buffer instance, containing TLS session

    \n
  • \n
  • requestOCSP: Optional, if true - OCSP status request extension would\nbe added to client hello, and 'OCSPResponse' event will be emitted on socket\nbefore establishing secure communication

    \n
  • \n
\n", "events": [ { "textRaw": "Event: 'OCSPResponse'", "type": "event", "name": "OCSPResponse", "desc": "

function (response) { }\n\n

\n

This event will be emitted if requestOCSP option was set. response is a\nbuffer object, containing server's OCSP response.\n\n

\n

Traditionally, the response is a signed object from the server's CA that\ncontains information about server's certificate revocation status.\n\n

\n", "params": [] }, { "textRaw": "Event: 'secureConnect'", "type": "event", "name": "secureConnect", "desc": "

This event is emitted after a new connection has been successfully handshaked.\nThe listener will be called no matter if the server's certificate was\nauthorized or not. It is up to the user to test tlsSocket.authorized\nto see if the server certificate was signed by one of the specified CAs.\nIf tlsSocket.authorized === false then the error can be found in\ntlsSocket.authorizationError. Also if NPN was used - you can check\ntlsSocket.npnProtocol for negotiated protocol.\n\n

\n", "params": [] } ], "methods": [ { "textRaw": "tlsSocket.address()", "type": "method", "name": "address", "desc": "

Returns the bound address, the address family name and port of the\nunderlying socket as reported by the operating system. Returns an\nobject with three properties, e.g.\n{ port: 12346, family: 'IPv4', address: '127.0.0.1' }\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getCipher()", "type": "method", "name": "getCipher", "desc": "

Returns an object representing the cipher name and the SSL/TLS\nprotocol version of the current connection.\n\n

\n

Example:\n{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }\n\n

\n

See SSL_CIPHER_get_name() and SSL_CIPHER_get_version() in\nhttps://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS for more\ninformation.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getPeerCertificate([ detailed ])", "type": "method", "name": "getPeerCertificate", "desc": "

Returns an object representing the peer's certificate. The returned object has\nsome properties corresponding to the field of the certificate. If detailed\nargument is true - the full chain with issuer property will be returned,\nif false - only the top certificate without issuer property.\n\n

\n

Example:\n\n

\n
{ subject:\n   { C: 'UK',\n     ST: 'Acknack Ltd',\n     L: 'Rhys Jones',\n     O: 'node.js',\n     OU: 'Test TLS Certificate',\n     CN: 'localhost' },\n  issuerInfo:\n   { C: 'UK',\n     ST: 'Acknack Ltd',\n     L: 'Rhys Jones',\n     O: 'node.js',\n     OU: 'Test TLS Certificate',\n     CN: 'localhost' },\n  issuer:\n   { ... another certificate ... },\n  raw: < RAW DER buffer >,\n  valid_from: 'Nov 11 09:52:22 2009 GMT',\n  valid_to: 'Nov  6 09:52:22 2029 GMT',\n  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',\n  serialNumber: 'B9B0D332A1AA5635' }
\n

If the peer does not provide a certificate, it returns null or an empty\nobject.\n\n

\n", "signatures": [ { "params": [ { "name": "detailed", "optional": true } ] } ] }, { "textRaw": "tlsSocket.getSession()", "type": "method", "name": "getSession", "desc": "

Return ASN.1 encoded TLS session or undefined if none was negotiated. Could\nbe used to speed up handshake establishment when reconnecting to the server.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.getTLSTicket()", "type": "method", "name": "getTLSTicket", "desc": "

NOTE: Works only with client TLS sockets. Useful only for debugging, for\nsession reuse provide session option to tls.connect.\n\n

\n

Return TLS session ticket or undefined if none was negotiated.\n\n

\n", "signatures": [ { "params": [] } ] }, { "textRaw": "tlsSocket.renegotiate(options, callback)", "type": "method", "name": "renegotiate", "desc": "

Initiate TLS renegotiation process. The options may contain the following\nfields: rejectUnauthorized, requestCert (See [tls.createServer][]\nfor details). callback(err) will be executed with null as err,\nonce the renegotiation is successfully completed.\n\n

\n

NOTE: Can be used to request peer's certificate after the secure connection\nhas been established.\n\n

\n

ANOTHER NOTE: When running as the server, socket will be destroyed\nwith an error after handshakeTimeout timeout.\n\n

\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "callback" } ] } ] }, { "textRaw": "tlsSocket.setMaxSendFragment(size)", "type": "method", "name": "setMaxSendFragment", "desc": "

Set maximum TLS fragment size (default and maximum value is: 16384, minimum\nis: 512). Returns true on success, false otherwise.\n\n

\n

Smaller fragment size decreases buffering latency on the client: large\nfragments are buffered by the TLS layer until the entire fragment is received\nand its integrity is verified; large fragments can span multiple roundtrips,\nand their processing can be delayed due to packet loss or reordering. However,\nsmaller fragments add extra TLS framing bytes and CPU overhead, which may\ndecrease overall server throughput.\n\n

\n", "signatures": [ { "params": [ { "name": "size" } ] } ] } ], "properties": [ { "textRaw": "tlsSocket.authorized", "name": "authorized", "desc": "

A boolean that is true if the peer certificate was signed by one of the\nspecified CAs, otherwise false\n\n

\n" }, { "textRaw": "tlsSocket.authorizationError", "name": "authorizationError", "desc": "

The reason why the peer's certificate has not been verified. This property\nbecomes available only when tlsSocket.authorized === false.\n\n

\n" }, { "textRaw": "tlsSocket.encrypted", "name": "encrypted", "desc": "

Static boolean value, always true. May be used to distinguish TLS sockets\nfrom regular ones.\n\n

\n" }, { "textRaw": "tlsSocket.localPort", "name": "localPort", "desc": "

The numeric representation of the local port.\n\n

\n" }, { "textRaw": "tlsSocket.localAddress", "name": "localAddress", "desc": "

The string representation of the local IP address.\n\n

\n" }, { "textRaw": "tlsSocket.remoteAddress", "name": "remoteAddress", "desc": "

The string representation of the remote IP address. For example,\n'74.125.127.100' or '2001:4860:a005::68'.\n\n

\n" }, { "textRaw": "tlsSocket.remoteFamily", "name": "remoteFamily", "desc": "

The string representation of the remote IP family. 'IPv4' or 'IPv6'.\n\n

\n" }, { "textRaw": "tlsSocket.remotePort", "name": "remotePort", "desc": "

The numeric representation of the remote port. For example, 443.\n\n

\n" } ], "signatures": [ { "params": [ { "name": "socket" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "tls.connect(options[, callback])", "type": "method", "name": "connect", "desc": "

Creates a new client connection to the given port and host (old API) or\noptions.port and options.host. (If host is omitted, it defaults to\nlocalhost.) options should be an object which specifies:\n\n

\n
    \n
  • host: Host the client should connect to

    \n
  • \n
  • port: Port the client should connect to

    \n
  • \n
  • socket: Establish secure connection on a given socket rather than\ncreating a new socket. If this option is specified, host and port\nare ignored.

    \n
  • \n
  • path: Creates unix socket connection to path. If this option is\nspecified, host and port are ignored.

    \n
  • \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the client in PFX or PKCS12 format.

    \n
  • \n
  • key: A string or Buffer containing the private key of the client in\nPEM format. (Could be an array of keys).

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the client in\nPEM format. (Could be an array of certs).

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. Uses the same default cipher suite as tls.createServer.

    \n
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails; err.code contains the OpenSSL error code. Default: true.

    \n
  • \n
  • NPNProtocols: An array of strings or Buffers containing supported NPN\nprotocols. Buffers should have following format: 0x05hello0x05world,\nwhere first byte is next protocol name's length. (Passing array should\nusually be much simpler: ['hello', 'world'].)

    \n
  • \n
  • servername: Servername for SNI (Server Name Indication) TLS extension.

    \n
  • \n
  • checkServerIdentity(servername, cert): Provide an override for checking\nserver's hostname against the certificate. Should return an error if verification\nfails. Return undefined if passing.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
  • session: A Buffer instance, containing TLS session.

    \n
  • \n
\n

The callback parameter will be added as a listener for the\n['secureConnect'][] event.\n\n

\n

tls.connect() returns a [tls.TLSSocket][] object.\n\n

\n

Here is an example of a client of echo server as described previously:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  // These are necessary only if using the client certificate authentication\n  key: fs.readFileSync('client-key.pem'),\n  cert: fs.readFileSync('client-cert.pem'),\n\n  // This is necessary only if the server uses the self-signed certificate\n  ca: [ fs.readFileSync('server-cert.pem') ]\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('client.pfx')\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] }, { "params": [ { "name": "options" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "tls.connect(port[, host][, options][, callback])", "type": "method", "name": "connect", "desc": "

Creates a new client connection to the given port and host (old API) or\noptions.port and options.host. (If host is omitted, it defaults to\nlocalhost.) options should be an object which specifies:\n\n

\n
    \n
  • host: Host the client should connect to

    \n
  • \n
  • port: Port the client should connect to

    \n
  • \n
  • socket: Establish secure connection on a given socket rather than\ncreating a new socket. If this option is specified, host and port\nare ignored.

    \n
  • \n
  • path: Creates unix socket connection to path. If this option is\nspecified, host and port are ignored.

    \n
  • \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the client in PFX or PKCS12 format.

    \n
  • \n
  • key: A string or Buffer containing the private key of the client in\nPEM format. (Could be an array of keys).

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the client in\nPEM format. (Could be an array of certs).

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. Uses the same default cipher suite as tls.createServer.

    \n
  • \n
  • rejectUnauthorized: If true, the server certificate is verified against\nthe list of supplied CAs. An 'error' event is emitted if verification\nfails; err.code contains the OpenSSL error code. Default: true.

    \n
  • \n
  • NPNProtocols: An array of strings or Buffers containing supported NPN\nprotocols. Buffers should have following format: 0x05hello0x05world,\nwhere first byte is next protocol name's length. (Passing array should\nusually be much simpler: ['hello', 'world'].)

    \n
  • \n
  • servername: Servername for SNI (Server Name Indication) TLS extension.

    \n
  • \n
  • checkServerIdentity(servername, cert): Provide an override for checking\nserver's hostname against the certificate. Should return an error if verification\nfails. Return undefined if passing.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
  • session: A Buffer instance, containing TLS session.

    \n
  • \n
\n

The callback parameter will be added as a listener for the\n['secureConnect'][] event.\n\n

\n

tls.connect() returns a [tls.TLSSocket][] object.\n\n

\n

Here is an example of a client of echo server as described previously:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  // These are necessary only if using the client certificate authentication\n  key: fs.readFileSync('client-key.pem'),\n  cert: fs.readFileSync('client-cert.pem'),\n\n  // This is necessary only if the server uses the self-signed certificate\n  ca: [ fs.readFileSync('server-cert.pem') ]\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('client.pfx')\n};\n\nvar socket = tls.connect(8000, options, () => {\n  console.log('client connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  process.stdin.pipe(socket);\n  process.stdin.resume();\n});\nsocket.setEncoding('utf8');\nsocket.on('data', (data) => {\n  console.log(data);\n});\nsocket.on('end', () => {\n  server.close();\n});
\n", "signatures": [ { "params": [ { "name": "port" }, { "name": "host", "optional": true }, { "name": "options", "optional": true }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "tls.createSecureContext(details)", "type": "method", "name": "createSecureContext", "desc": "

Creates a credentials object, with the optional details being a\ndictionary with keys:\n\n

\n
    \n
  • pfx : A string or buffer holding the PFX or PKCS12 encoded private\nkey, certificate and CA certificates
  • \n
  • key: A string or Buffer containing the private key of the server in\nPEM format. To support multiple keys using different algorithms, an array\ncan be provided. It can either be a plain array of keys, or an array of\nobjects in the format {pem: key, passphrase: passphrase}. (Required)
  • \n
  • passphrase : A string of passphrase for the private key or pfx
  • \n
  • cert : A string holding the PEM encoded certificate
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs\n(Certificate Revocation List)
  • \n
  • ciphers: A string describing the ciphers to use or exclude.\nConsult\nhttps://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT\nfor details on the format.
  • \n
  • honorCipherOrder : When choosing a cipher, use the server's preferences\ninstead of the client preferences. For further details see tls module\ndocumentation.
  • \n
\n

If no 'ca' details are given, then Node.js will use the default\npublicly trusted list of CAs as given in\n

\n

http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt.\n\n\n

\n", "signatures": [ { "params": [ { "name": "details" } ] } ] }, { "textRaw": "tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])", "type": "method", "name": "createSecurePair", "desc": "

Creates a new secure pair object with two streams, one of which reads/writes\nencrypted data, and one reads/writes cleartext data.\nGenerally the encrypted one is piped to/from an incoming encrypted data stream,\nand the cleartext one is used as a replacement for the initial encrypted stream.\n\n

\n
    \n
  • credentials: A secure context object from tls.createSecureContext( ... )

    \n
  • \n
  • isServer: A boolean indicating whether this tls connection should be\nopened as a server or a client.

    \n
  • \n
  • requestCert: A boolean indicating whether a server should request a\ncertificate from a connecting client. Only applies to server connections.

    \n
  • \n
  • rejectUnauthorized: A boolean indicating whether a server should\nautomatically reject clients with invalid certificates. Only applies to\nservers with requestCert enabled.

    \n
  • \n
\n

tls.createSecurePair() returns a SecurePair object with cleartext and\nencrypted stream properties.\n\n

\n

NOTE: cleartext has the same APIs as [tls.TLSSocket][]\n\n

\n", "signatures": [ { "params": [ { "name": "context", "optional": true }, { "name": "isServer", "optional": true }, { "name": "requestCert", "optional": true }, { "name": "rejectUnauthorized", "optional": true } ] } ] }, { "textRaw": "tls.createServer(options[, secureConnectionListener])", "type": "method", "name": "createServer", "desc": "

Creates a new [tls.Server][]. The connectionListener argument is\nautomatically set as a listener for the ['secureConnection'][] event. The\noptions object has these possibilities:\n\n

\n
    \n
  • pfx: A string or Buffer containing the private key, certificate and\nCA certs of the server in PFX or PKCS12 format. (Mutually exclusive with\nthe key, cert and ca options.)

    \n
  • \n
  • key: A string or Buffer containing the private key of the server in\nPEM format. To support multiple keys using different algorithms, an array\ncan be provided. It can either be a plain array of keys, or an array of\nobjects in the format {pem: key, passphrase: passphrase}. (Required)

    \n
  • \n
  • passphrase: A string of passphrase for the private key or pfx.

    \n
  • \n
  • cert: A string or Buffer containing the certificate key of the server in\nPEM format. (Could be an array of certs). (Required)

    \n
  • \n
  • ca: A string, Buffer or array of strings or Buffers of trusted\ncertificates in PEM format. If this is omitted several well known "root"\nCAs will be used, like VeriSign. These are used to authorize connections.

    \n
  • \n
  • crl : Either a string or list of strings of PEM encoded CRLs (Certificate\nRevocation List)

    \n
  • \n
  • ciphers: A string describing the ciphers to use or exclude, separated by\n:. The default cipher suite is:

    \n
    ECDHE-RSA-AES128-GCM-SHA256:\nECDHE-ECDSA-AES128-GCM-SHA256:\nECDHE-RSA-AES256-GCM-SHA384:\nECDHE-ECDSA-AES256-GCM-SHA384:\nDHE-RSA-AES128-GCM-SHA256:\nECDHE-RSA-AES128-SHA256:\nDHE-RSA-AES128-SHA256:\nECDHE-RSA-AES256-SHA384:\nDHE-RSA-AES256-SHA384:\nECDHE-RSA-AES256-SHA256:\nDHE-RSA-AES256-SHA256:\nHIGH:\n!aNULL:\n!eNULL:\n!EXPORT:\n!DES:\n!RC4:\n!MD5:\n!PSK:\n!SRP:\n!CAMELLIA
    \n

    The default cipher suite prefers GCM ciphers for [Chrome's 'modern\ncryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect\nForward secrecy, while offering some backward compatibiltity.

    \n

    128 bit AES is preferred over 192 and 256 bit AES in light of [specific\nattacks affecting larger AES key sizes].

    \n

    Old clients that rely on insecure and deprecated RC4 or DES-based ciphers\n(like Internet Explorer 6) aren't able to complete the handshake with the default\nconfiguration. If you absolutely must support these clients, the\n[TLS recommendations] may offer a compatible cipher suite. For more details\non the format, see the [OpenSSL cipher list format documentation].

    \n
  • \n
  • ecdhCurve: A string describing a named curve to use for ECDH key agreement\nor false to disable ECDH.

    \n

    Defaults to prime256v1 (NIST P-256). Use [crypto.getCurves()][] to obtain\na list of available curve names. On recent releases,\nopenssl ecparam -list_curves will also display the name and description of\neach available elliptic curve.

    \n
  • \n
  • dhparam: A string or Buffer containing Diffie Hellman parameters,\nrequired for Perfect Forward Secrecy. Use openssl dhparam to create it.\nIts key length should be greater than or equal to 1024 bits, otherwise\nit throws an error. It is strongly recommended to use 2048 bits or\nmore for stronger security. If omitted or invalid, it is silently\ndiscarded and DHE ciphers won't be available.

    \n
  • \n
  • handshakeTimeout: Abort the connection if the SSL/TLS handshake does not\nfinish in this many milliseconds. The default is 120 seconds.

    \n

    A 'clientError' is emitted on the tls.Server object whenever a handshake\ntimes out.

    \n
  • \n
  • honorCipherOrder : When choosing a cipher, use the server's preferences\ninstead of the client preferences. Default: true.

    \n
  • \n
  • requestCert: If true the server will request a certificate from\nclients that connect and attempt to verify that certificate. Default:\nfalse.

    \n
  • \n
  • rejectUnauthorized: If true the server will reject any connection\nwhich is not authorized with the list of supplied CAs. This option only\nhas an effect if requestCert is true. Default: false.

    \n
  • \n
  • NPNProtocols: An array or Buffer of possible NPN protocols. (Protocols\nshould be ordered by their priority).

    \n
  • \n
  • SNICallback(servername, cb): A function that will be called if client\nsupports SNI TLS extension. Two argument will be passed to it: servername,\nand cb. SNICallback should invoke cb(null, ctx), where ctx is a\nSecureContext instance.\n(You can use tls.createSecureContext(...) to get proper\nSecureContext). If SNICallback wasn't provided - default callback with\nhigh-level API will be used (see below).

    \n
  • \n
  • sessionTimeout: An integer specifying the seconds after which TLS\nsession identifiers and TLS session tickets created by the server are\ntimed out. See [SSL_CTX_set_timeout] for more details.

    \n
  • \n
  • ticketKeys: A 48-byte Buffer instance consisting of 16-byte prefix,\n16-byte hmac key, 16-byte AES key. You could use it to accept tls session\ntickets on multiple instances of tls server.

    \n

    NOTE: Automatically shared between cluster module workers.

    \n
  • \n
  • sessionIdContext: A string containing an opaque identifier for session\nresumption. If requestCert is true, the default is MD5 hash value\ngenerated from command-line. (In FIPS mode a truncated SHA1 hash is\nused instead.) Otherwise, the default is not provided.

    \n
  • \n
  • secureProtocol: The SSL method to use, e.g. SSLv3_method to force\nSSL version 3. The possible values depend on your installation of\nOpenSSL and are defined in the constant [SSL_METHODS][].

    \n
  • \n
\n

Here is a simple example echo server:\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  key: fs.readFileSync('server-key.pem'),\n  cert: fs.readFileSync('server-cert.pem'),\n\n  // This is necessary only if using the client certificate authentication.\n  requestCert: true,\n\n  // This is necessary only if the client uses the self-signed certificate.\n  ca: [ fs.readFileSync('client-cert.pem') ]\n};\n\nvar server = tls.createServer(options, (socket) => {\n  console.log('server connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  socket.write('welcome!\\n');\n  socket.setEncoding('utf8');\n  socket.pipe(socket);\n});\nserver.listen(8000, () => {\n  console.log('server bound');\n});
\n

Or\n\n

\n
const tls = require('tls');\nconst fs = require('fs');\n\nconst options = {\n  pfx: fs.readFileSync('server.pfx'),\n\n  // This is necessary only if using the client certificate authentication.\n  requestCert: true,\n\n};\n\nvar server = tls.createServer(options, (socket) => {\n  console.log('server connected',\n              socket.authorized ? 'authorized' : 'unauthorized');\n  socket.write('welcome!\\n');\n  socket.setEncoding('utf8');\n  socket.pipe(socket);\n});\nserver.listen(8000, () => {\n  console.log('server bound');\n});
\n

You can test this server by connecting to it with openssl s_client:\n\n\n

\n
openssl s_client -connect 127.0.0.1:8000
\n", "signatures": [ { "params": [ { "name": "options" }, { "name": "secureConnectionListener", "optional": true } ] } ] }, { "textRaw": "tls.getCiphers()", "type": "method", "name": "getCiphers", "desc": "

Returns an array with the names of the supported SSL ciphers.\n\n

\n

Example:\n\n

\n
var ciphers = tls.getCiphers();\nconsole.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]
\n", "signatures": [ { "params": [] } ] } ], "type": "module", "displayName": "TLS (SSL)" } ] } node-v4.2.6/doc/api/tls.markdown000644 000766 000024 00000101565 12650222326 016642 0ustar00iojsstaff000000 000000 # TLS (SSL) Stability: 2 - Stable Use `require('tls')` to access this module. The `tls` module uses OpenSSL to provide Transport Layer Security and/or Secure Socket Layer: encrypted stream communication. TLS/SSL is a public/private key infrastructure. Each client and each server must have a private key. A private key is created like this: openssl genrsa -out ryans-key.pem 2048 All servers and some clients need to have a certificate. Certificates are public keys signed by a Certificate Authority or self-signed. The first step to getting a certificate is to create a "Certificate Signing Request" (CSR) file. This is done with: openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem To create a self-signed certificate with the CSR, do this: openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem Alternatively you can send the CSR to a Certificate Authority for signing. For Perfect Forward Secrecy, it is required to generate Diffie-Hellman parameters: openssl dhparam -outform PEM -out dhparam.pem 2048 To create .pfx or .p12, do this: openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \ -certfile ca-cert.pem -out agent5.pfx - `in`: certificate - `inkey`: private key - `certfile`: all CA certs concatenated in one file like `cat ca1-cert.pem ca2-cert.pem > ca-cert.pem` ## Client-initiated renegotiation attack mitigation The TLS protocol lets the client renegotiate certain aspects of the TLS session. Unfortunately, session renegotiation requires a disproportional amount of server-side resources, which makes it a potential vector for denial-of-service attacks. To mitigate this, renegotiations are limited to three times every 10 minutes. An error is emitted on the [tls.TLSSocket][] instance when the threshold is exceeded. The limits are configurable: - `tls.CLIENT_RENEG_LIMIT`: renegotiation limit, default is 3. - `tls.CLIENT_RENEG_WINDOW`: renegotiation window in seconds, default is 10 minutes. Don't change the defaults unless you know what you are doing. To test your server, connect to it with `openssl s_client -connect address:port` and tap `R` (that's the letter `R` followed by a carriage return) a few times. ## Modifying the Default TLS Cipher suite Node.js is built with a default suite of enabled and disabled TLS ciphers. Currently, the default cipher suite is: ECDHE-RSA-AES128-GCM-SHA256: ECDHE-ECDSA-AES128-GCM-SHA256: ECDHE-RSA-AES256-GCM-SHA384: ECDHE-ECDSA-AES256-GCM-SHA384: DHE-RSA-AES128-GCM-SHA256: ECDHE-RSA-AES128-SHA256: DHE-RSA-AES128-SHA256: ECDHE-RSA-AES256-SHA384: DHE-RSA-AES256-SHA384: ECDHE-RSA-AES256-SHA256: DHE-RSA-AES256-SHA256: HIGH: !aNULL: !eNULL: !EXPORT: !DES: !RC4: !MD5: !PSK: !SRP: !CAMELLIA This default can be overriden entirely using the `--tls-cipher-list` command line switch. For instance, the following makes `ECDHE-RSA-AES128-GCM-SHA256:!RC4` the default TLS cipher suite: node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" Note that the default cipher suite included within Node.js has been carefully selected to reflect current security best practices and risk mitigation. Changing the default cipher suite can have a significant impact on the security of an application. The `--tls-cipher-list` switch should by used only if absolutely necessary. ## NPN and SNI NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS handshake extensions allowing you: * NPN - to use one TLS server for multiple protocols (HTTP, SPDY) * SNI - to use one TLS server for multiple hostnames with different SSL certificates. ## Perfect Forward Secrecy The term "[Forward Secrecy]" or "Perfect Forward Secrecy" describes a feature of key-agreement (i.e. key-exchange) methods. Practically it means that even if the private key of a (your) server is compromised, communication can only be decrypted by eavesdroppers if they manage to obtain the key-pair specifically generated for each session. This is achieved by randomly generating a key pair for key-agreement on every handshake (in contrary to the same key for all sessions). Methods implementing this technique, thus offering Perfect Forward Secrecy, are called "ephemeral". Currently two methods are commonly used to achieve Perfect Forward Secrecy (note the character "E" appended to the traditional abbreviations): * [DHE] - An ephemeral version of the Diffie Hellman key-agreement protocol. * [ECDHE] - An ephemeral version of the Elliptic Curve Diffie Hellman key-agreement protocol. Ephemeral methods may have some performance drawbacks, because key generation is expensive. ## Class: CryptoStream Stability: 0 - Deprecated: Use [tls.TLSSocket][] instead. This is an encrypted stream. ### cryptoStream.bytesWritten A proxy to the underlying socket's bytesWritten accessor, this will return the total bytes written to the socket, *including the TLS overhead*. ## Class: SecurePair Returned by tls.createSecurePair. ### Event: 'secure' The event is emitted from the SecurePair once the pair has successfully established a secure connection. Similarly to the checking for the server `'secureConnection'` event, pair.cleartext.authorized should be checked to confirm whether the certificate used properly authorized. ## Class: tls.Server This class is a subclass of `net.Server` and has the same methods on it. Instead of accepting just raw TCP connections, this accepts encrypted connections using TLS or SSL. ### Event: 'clientError' `function (exception, tlsSocket) { }` When a client connection emits an `'error'` event before secure connection is established - it will be forwarded here. `tlsSocket` is the [tls.TLSSocket][] that the error originated from. ### Event: 'newSession' `function (sessionId, sessionData, callback) { }` Emitted on creation of TLS session. May be used to store sessions in external storage. `callback` must be invoked eventually, otherwise no data will be sent or received from secure connection. NOTE: adding this event listener will have an effect only on connections established after addition of event listener. ### Event: 'OCSPRequest' `function (certificate, issuer, callback) { }` Emitted when the client sends a certificate status request. You could parse server's current certificate to obtain OCSP url and certificate id, and after obtaining OCSP response invoke `callback(null, resp)`, where `resp` is a `Buffer` instance. Both `certificate` and `issuer` are a `Buffer` DER-representations of the primary and issuer's certificates. They could be used to obtain OCSP certificate id and OCSP endpoint url. Alternatively, `callback(null, null)` could be called, meaning that there is no OCSP response. Calling `callback(err)` will result in a `socket.destroy(err)` call. Typical flow: 1. Client connects to server and sends `'OCSPRequest'` to it (via status info extension in ClientHello.) 2. Server receives request and invokes `'OCSPRequest'` event listener if present 3. Server grabs OCSP url from either `certificate` or `issuer` and performs an [OCSP request] to the CA 4. Server receives `OCSPResponse` from CA and sends it back to client via `callback` argument 5. Client validates the response and either destroys socket or performs a handshake. NOTE: `issuer` could be null, if the certificate is self-signed or if the issuer is not in the root certificates list. (You could provide an issuer via `ca` option.) NOTE: adding this event listener will have an effect only on connections established after addition of event listener. NOTE: you may want to use some npm module like [asn1.js] to parse the certificates. ### Event: 'resumeSession' `function (sessionId, callback) { }` Emitted when client wants to resume previous TLS session. Event listener may perform lookup in external storage using given `sessionId`, and invoke `callback(null, sessionData)` once finished. If session can't be resumed (i.e. doesn't exist in storage) one may call `callback(null, null)`. Calling `callback(err)` will terminate incoming connection and destroy socket. NOTE: adding this event listener will have an effect only on connections established after addition of event listener. Here's an example for using TLS session resumption: var tlsSessionStore = {}; server.on('newSession', (id, data, cb) => { tlsSessionStore[id.toString('hex')] = data; cb(); }); server.on('resumeSession', (id, cb) => { cb(null, tlsSessionStore[id.toString('hex')] || null); }); ### Event: 'secureConnection' `function (tlsSocket) {}` This event is emitted after a new connection has been successfully handshaked. The argument is an instance of [tls.TLSSocket][]. It has all the common stream methods and events. `socket.authorized` is a boolean value which indicates if the client has verified by one of the supplied certificate authorities for the server. If `socket.authorized` is false, then `socket.authorizationError` is set to describe how authorization failed. Implied but worth mentioning: depending on the settings of the TLS server, you unauthorized connections may be accepted. `socket.npnProtocol` is a string containing selected NPN protocol. `socket.servername` is a string containing servername requested with SNI. ### server.addContext(hostname, context) Add secure context that will be used if client request's SNI hostname is matching passed `hostname` (wildcards can be used). `context` can contain `key`, `cert`, `ca` and/or any other properties from `tls.createSecureContext` `options` argument. ### server.address() Returns the bound address, the address family name and port of the server as reported by the operating system. See [net.Server.address()][] for more information. ### server.close([callback]) Stops the server from accepting new connections. This function is asynchronous, the server is finally closed when the server emits a `'close'` event. Optionally, you can pass a callback to listen for the `'close'` event. ### server.connections The number of concurrent connections on the server. ### server.getTicketKeys() Returns `Buffer` instance holding the keys currently used for encryption/decryption of the [TLS Session Tickets][] ### server.listen(port[, hostname][, callback]) Begin accepting connections on the specified `port` and `hostname`. If the `hostname` is omitted, the server will accept connections on any IPv6 address (`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. A port value of zero will assign a random port. This function is asynchronous. The last parameter `callback` will be called when the server has been bound. See `net.Server` for more information. ### server.maxConnections Set this property to reject connections when the server's connection count gets high. ### server.setTicketKeys(keys) Updates the keys for encryption/decryption of the [TLS Session Tickets][]. NOTE: the buffer should be 48 bytes long. See server `ticketKeys` option for more information oh how it is going to be used. NOTE: the change is effective only for the future server connections. Existing or currently pending server connections will use previous keys. ## Class: tls.TLSSocket This is a wrapped version of [`net.Socket`][] that does transparent encryption of written data and all required TLS negotiation. This instance implements a duplex [Stream][] interfaces. It has all the common stream methods and events. Methods that return TLS connection meta data (e.g. [getPeerCertificate][] will only return data while the connection is open. ## new tls.TLSSocket(socket[, options]) Construct a new TLSSocket object from existing TCP socket. `socket` is an instance of [`net.Socket`][] `options` is an optional object that might contain following properties: - `secureContext`: An optional TLS context object from `tls.createSecureContext( ... )` - `isServer`: If `true` - TLS socket will be instantiated in server-mode. Default: `false` - `server`: An optional [`net.Server`][] instance - `requestCert`: Optional, see [tls.createSecurePair][] - `rejectUnauthorized`: Optional, see [tls.createSecurePair][] - `NPNProtocols`: Optional, see [tls.createServer][] - `SNICallback`: Optional, see [tls.createServer][] - `session`: Optional, a `Buffer` instance, containing TLS session - `requestOCSP`: Optional, if `true` - OCSP status request extension would be added to client hello, and `'OCSPResponse'` event will be emitted on socket before establishing secure communication ### Event: 'OCSPResponse' `function (response) { }` This event will be emitted if `requestOCSP` option was set. `response` is a buffer object, containing server's OCSP response. Traditionally, the `response` is a signed object from the server's CA that contains information about server's certificate revocation status. ### Event: 'secureConnect' This event is emitted after a new connection has been successfully handshaked. The listener will be called no matter if the server's certificate was authorized or not. It is up to the user to test `tlsSocket.authorized` to see if the server certificate was signed by one of the specified CAs. If `tlsSocket.authorized === false` then the error can be found in `tlsSocket.authorizationError`. Also if NPN was used - you can check `tlsSocket.npnProtocol` for negotiated protocol. ### tlsSocket.address() Returns the bound address, the address family name and port of the underlying socket as reported by the operating system. Returns an object with three properties, e.g. `{ port: 12346, family: 'IPv4', address: '127.0.0.1' }` ### tlsSocket.authorized A boolean that is `true` if the peer certificate was signed by one of the specified CAs, otherwise `false` ### tlsSocket.authorizationError The reason why the peer's certificate has not been verified. This property becomes available only when `tlsSocket.authorized === false`. ### tlsSocket.encrypted Static boolean value, always `true`. May be used to distinguish TLS sockets from regular ones. ### tlsSocket.getCipher() Returns an object representing the cipher name and the SSL/TLS protocol version of the current connection. Example: { name: 'AES256-SHA', version: 'TLSv1/SSLv3' } See SSL_CIPHER_get_name() and SSL_CIPHER_get_version() in https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_CIPHERS for more information. ### tlsSocket.getPeerCertificate([ detailed ]) Returns an object representing the peer's certificate. The returned object has some properties corresponding to the field of the certificate. If `detailed` argument is `true` - the full chain with `issuer` property will be returned, if `false` - only the top certificate without `issuer` property. Example: { subject: { C: 'UK', ST: 'Acknack Ltd', L: 'Rhys Jones', O: 'node.js', OU: 'Test TLS Certificate', CN: 'localhost' }, issuerInfo: { C: 'UK', ST: 'Acknack Ltd', L: 'Rhys Jones', O: 'node.js', OU: 'Test TLS Certificate', CN: 'localhost' }, issuer: { ... another certificate ... }, raw: < RAW DER buffer >, valid_from: 'Nov 11 09:52:22 2009 GMT', valid_to: 'Nov 6 09:52:22 2029 GMT', fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF', serialNumber: 'B9B0D332A1AA5635' } If the peer does not provide a certificate, it returns `null` or an empty object. ### tlsSocket.getSession() Return ASN.1 encoded TLS session or `undefined` if none was negotiated. Could be used to speed up handshake establishment when reconnecting to the server. ### tlsSocket.getTLSTicket() NOTE: Works only with client TLS sockets. Useful only for debugging, for session reuse provide `session` option to `tls.connect`. Return TLS session ticket or `undefined` if none was negotiated. ### tlsSocket.localPort The numeric representation of the local port. ### tlsSocket.localAddress The string representation of the local IP address. ### tlsSocket.remoteAddress The string representation of the remote IP address. For example, `'74.125.127.100'` or `'2001:4860:a005::68'`. ### tlsSocket.remoteFamily The string representation of the remote IP family. `'IPv4'` or `'IPv6'`. ### tlsSocket.remotePort The numeric representation of the remote port. For example, `443`. ### tlsSocket.renegotiate(options, callback) Initiate TLS renegotiation process. The `options` may contain the following fields: `rejectUnauthorized`, `requestCert` (See [tls.createServer][] for details). `callback(err)` will be executed with `null` as `err`, once the renegotiation is successfully completed. NOTE: Can be used to request peer's certificate after the secure connection has been established. ANOTHER NOTE: When running as the server, socket will be destroyed with an error after `handshakeTimeout` timeout. ### tlsSocket.setMaxSendFragment(size) Set maximum TLS fragment size (default and maximum value is: `16384`, minimum is: `512`). Returns `true` on success, `false` otherwise. Smaller fragment size decreases buffering latency on the client: large fragments are buffered by the TLS layer until the entire fragment is received and its integrity is verified; large fragments can span multiple roundtrips, and their processing can be delayed due to packet loss or reordering. However, smaller fragments add extra TLS framing bytes and CPU overhead, which may decrease overall server throughput. ## tls.connect(options[, callback]) ## tls.connect(port[, host][, options][, callback]) Creates a new client connection to the given `port` and `host` (old API) or `options.port` and `options.host`. (If `host` is omitted, it defaults to `localhost`.) `options` should be an object which specifies: - `host`: Host the client should connect to - `port`: Port the client should connect to - `socket`: Establish secure connection on a given socket rather than creating a new socket. If this option is specified, `host` and `port` are ignored. - `path`: Creates unix socket connection to path. If this option is specified, `host` and `port` are ignored. - `pfx`: A string or `Buffer` containing the private key, certificate and CA certs of the client in PFX or PKCS12 format. - `key`: A string or `Buffer` containing the private key of the client in PEM format. (Could be an array of keys). - `passphrase`: A string of passphrase for the private key or pfx. - `cert`: A string or `Buffer` containing the certificate key of the client in PEM format. (Could be an array of certs). - `ca`: A string, `Buffer` or array of strings or `Buffer`s of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections. - `ciphers`: A string describing the ciphers to use or exclude, separated by `:`. Uses the same default cipher suite as `tls.createServer`. - `rejectUnauthorized`: If `true`, the server certificate is verified against the list of supplied CAs. An `'error'` event is emitted if verification fails; `err.code` contains the OpenSSL error code. Default: `true`. - `NPNProtocols`: An array of strings or `Buffer`s containing supported NPN protocols. `Buffer`s should have following format: `0x05hello0x05world`, where first byte is next protocol name's length. (Passing array should usually be much simpler: `['hello', 'world']`.) - `servername`: Servername for SNI (Server Name Indication) TLS extension. - `checkServerIdentity(servername, cert)`: Provide an override for checking server's hostname against the certificate. Should return an error if verification fails. Return `undefined` if passing. - `secureProtocol`: The SSL method to use, e.g. `SSLv3_method` to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant [SSL_METHODS][]. - `session`: A `Buffer` instance, containing TLS session. The `callback` parameter will be added as a listener for the [`'secureConnect'`][] event. `tls.connect()` returns a [tls.TLSSocket][] object. Here is an example of a client of echo server as described previously: const tls = require('tls'); const fs = require('fs'); const options = { // These are necessary only if using the client certificate authentication key: fs.readFileSync('client-key.pem'), cert: fs.readFileSync('client-cert.pem'), // This is necessary only if the server uses the self-signed certificate ca: [ fs.readFileSync('server-cert.pem') ] }; var socket = tls.connect(8000, options, () => { console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); process.stdin.pipe(socket); process.stdin.resume(); }); socket.setEncoding('utf8'); socket.on('data', (data) => { console.log(data); }); socket.on('end', () => { server.close(); }); Or const tls = require('tls'); const fs = require('fs'); const options = { pfx: fs.readFileSync('client.pfx') }; var socket = tls.connect(8000, options, () => { console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized'); process.stdin.pipe(socket); process.stdin.resume(); }); socket.setEncoding('utf8'); socket.on('data', (data) => { console.log(data); }); socket.on('end', () => { server.close(); }); ## tls.createSecureContext(details) Creates a credentials object, with the optional details being a dictionary with keys: * `pfx` : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates * `key`: A string or `Buffer` containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format `{pem: key, passphrase: passphrase}`. (Required) * `passphrase` : A string of passphrase for the private key or pfx * `cert` : A string holding the PEM encoded certificate * `ca`: A string, `Buffer` or array of strings or `Buffer`s of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections. * `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List) * `ciphers`: A string describing the ciphers to use or exclude. Consult for details on the format. * `honorCipherOrder` : When choosing a cipher, use the server's preferences instead of the client preferences. For further details see `tls` module documentation. If no 'ca' details are given, then Node.js will use the default publicly trusted list of CAs as given in . ## tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized]) Creates a new secure pair object with two streams, one of which reads/writes encrypted data, and one reads/writes cleartext data. Generally the encrypted one is piped to/from an incoming encrypted data stream, and the cleartext one is used as a replacement for the initial encrypted stream. - `credentials`: A secure context object from tls.createSecureContext( ... ) - `isServer`: A boolean indicating whether this tls connection should be opened as a server or a client. - `requestCert`: A boolean indicating whether a server should request a certificate from a connecting client. Only applies to server connections. - `rejectUnauthorized`: A boolean indicating whether a server should automatically reject clients with invalid certificates. Only applies to servers with `requestCert` enabled. `tls.createSecurePair()` returns a SecurePair object with `cleartext` and `encrypted` stream properties. NOTE: `cleartext` has the same APIs as [tls.TLSSocket][] ## tls.createServer(options[, secureConnectionListener]) Creates a new [tls.Server][]. The `connectionListener` argument is automatically set as a listener for the [`'secureConnection'`][] event. The `options` object has these possibilities: - `pfx`: A string or `Buffer` containing the private key, certificate and CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with the `key`, `cert` and `ca` options.) - `key`: A string or `Buffer` containing the private key of the server in PEM format. To support multiple keys using different algorithms, an array can be provided. It can either be a plain array of keys, or an array of objects in the format `{pem: key, passphrase: passphrase}`. (Required) - `passphrase`: A string of passphrase for the private key or pfx. - `cert`: A string or `Buffer` containing the certificate key of the server in PEM format. (Could be an array of certs). (Required) - `ca`: A string, `Buffer` or array of strings or `Buffer`s of trusted certificates in PEM format. If this is omitted several well known "root" CAs will be used, like VeriSign. These are used to authorize connections. - `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List) - `ciphers`: A string describing the ciphers to use or exclude, separated by `:`. The default cipher suite is: ECDHE-RSA-AES128-GCM-SHA256: ECDHE-ECDSA-AES128-GCM-SHA256: ECDHE-RSA-AES256-GCM-SHA384: ECDHE-ECDSA-AES256-GCM-SHA384: DHE-RSA-AES128-GCM-SHA256: ECDHE-RSA-AES128-SHA256: DHE-RSA-AES128-SHA256: ECDHE-RSA-AES256-SHA384: DHE-RSA-AES256-SHA384: ECDHE-RSA-AES256-SHA256: DHE-RSA-AES256-SHA256: HIGH: !aNULL: !eNULL: !EXPORT: !DES: !RC4: !MD5: !PSK: !SRP: !CAMELLIA The default cipher suite prefers GCM ciphers for [Chrome's 'modern cryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect Forward secrecy, while offering *some* backward compatibiltity. 128 bit AES is preferred over 192 and 256 bit AES in light of [specific attacks affecting larger AES key sizes]. Old clients that rely on insecure and deprecated RC4 or DES-based ciphers (like Internet Explorer 6) aren't able to complete the handshake with the default configuration. If you absolutely must support these clients, the [TLS recommendations] may offer a compatible cipher suite. For more details on the format, see the [OpenSSL cipher list format documentation]. - `ecdhCurve`: A string describing a named curve to use for ECDH key agreement or false to disable ECDH. Defaults to `prime256v1` (NIST P-256). Use [crypto.getCurves()][] to obtain a list of available curve names. On recent releases, `openssl ecparam -list_curves` will also display the name and description of each available elliptic curve. - `dhparam`: A string or `Buffer` containing Diffie Hellman parameters, required for Perfect Forward Secrecy. Use `openssl dhparam` to create it. Its key length should be greater than or equal to 1024 bits, otherwise it throws an error. It is strongly recommended to use 2048 bits or more for stronger security. If omitted or invalid, it is silently discarded and DHE ciphers won't be available. - `handshakeTimeout`: Abort the connection if the SSL/TLS handshake does not finish in this many milliseconds. The default is 120 seconds. A `'clientError'` is emitted on the `tls.Server` object whenever a handshake times out. - `honorCipherOrder` : When choosing a cipher, use the server's preferences instead of the client preferences. Default: `true`. - `requestCert`: If `true` the server will request a certificate from clients that connect and attempt to verify that certificate. Default: `false`. - `rejectUnauthorized`: If `true` the server will reject any connection which is not authorized with the list of supplied CAs. This option only has an effect if `requestCert` is `true`. Default: `false`. - `NPNProtocols`: An array or `Buffer` of possible NPN protocols. (Protocols should be ordered by their priority). - `SNICallback(servername, cb)`: A function that will be called if client supports SNI TLS extension. Two argument will be passed to it: `servername`, and `cb`. `SNICallback` should invoke `cb(null, ctx)`, where `ctx` is a SecureContext instance. (You can use `tls.createSecureContext(...)` to get proper SecureContext). If `SNICallback` wasn't provided - default callback with high-level API will be used (see below). - `sessionTimeout`: An integer specifying the seconds after which TLS session identifiers and TLS session tickets created by the server are timed out. See [SSL_CTX_set_timeout] for more details. - `ticketKeys`: A 48-byte `Buffer` instance consisting of 16-byte prefix, 16-byte hmac key, 16-byte AES key. You could use it to accept tls session tickets on multiple instances of tls server. NOTE: Automatically shared between `cluster` module workers. - `sessionIdContext`: A string containing an opaque identifier for session resumption. If `requestCert` is `true`, the default is MD5 hash value generated from command-line. (In FIPS mode a truncated SHA1 hash is used instead.) Otherwise, the default is not provided. - `secureProtocol`: The SSL method to use, e.g. `SSLv3_method` to force SSL version 3. The possible values depend on your installation of OpenSSL and are defined in the constant [SSL_METHODS][]. Here is a simple example echo server: const tls = require('tls'); const fs = require('fs'); const options = { key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem'), // This is necessary only if using the client certificate authentication. requestCert: true, // This is necessary only if the client uses the self-signed certificate. ca: [ fs.readFileSync('client-cert.pem') ] }; var server = tls.createServer(options, (socket) => { console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized'); socket.write('welcome!\n'); socket.setEncoding('utf8'); socket.pipe(socket); }); server.listen(8000, () => { console.log('server bound'); }); Or const tls = require('tls'); const fs = require('fs'); const options = { pfx: fs.readFileSync('server.pfx'), // This is necessary only if using the client certificate authentication. requestCert: true, }; var server = tls.createServer(options, (socket) => { console.log('server connected', socket.authorized ? 'authorized' : 'unauthorized'); socket.write('welcome!\n'); socket.setEncoding('utf8'); socket.pipe(socket); }); server.listen(8000, () => { console.log('server bound'); }); You can test this server by connecting to it with `openssl s_client`: openssl s_client -connect 127.0.0.1:8000 ## tls.getCiphers() Returns an array with the names of the supported SSL ciphers. Example: var ciphers = tls.getCiphers(); console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...] [OpenSSL cipher list format documentation]: https://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT [Chrome's 'modern cryptography' setting]: https://www.chromium.org/Home/chromium-security/education/tls#TOC-Deprecation-of-TLS-Features-Algorithms-in-Chrome [specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html [BEAST attacks]: https://blog.ivanristic.com/2011/10/mitigating-the-beast-attack-on-tls.html [crypto.getCurves()]: crypto.html#crypto_crypto_getcurves [tls.createServer]: #tls_tls_createserver_options_secureconnectionlistener [tls.createSecurePair]: #tls_tls_createsecurepair_context_isserver_requestcert_rejectunauthorized_options [tls.TLSSocket]: #tls_class_tls_tlssocket [`net.Server`]: net.html#net_class_net_server [`net.Socket`]: net.html#net_class_net_socket [net.Server.address()]: net.html#net_server_address [`'secureConnect'`]: #tls_event_secureconnect [`'secureConnection'`]: #tls_event_secureconnection [Stream]: stream.html#stream_stream [SSL_METHODS]: https://www.openssl.org/docs/ssl/ssl.html#DEALING_WITH_PROTOCOL_METHODS [tls.Server]: #tls_class_tls_server [SSL_CTX_set_timeout]: https://www.openssl.org/docs/ssl/SSL_CTX_set_timeout.html [RFC 4492]: https://www.rfc-editor.org/rfc/rfc4492.txt [Forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy [DHE]: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange [ECDHE]: https://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman [asn1.js]: https://npmjs.org/package/asn1.js [OCSP request]: https://en.wikipedia.org/wiki/OCSP_stapling [TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS [TLS Session Tickets]: https://www.ietf.org/rfc/rfc5077.txt [getPeerCertificate]: #tls_tlssocket_getpeercertificate_detailed node-v4.2.6/doc/api/tty.html000644 000766 000024 00000017545 12650222331 016002 0ustar00iojsstaff000000 000000 TTY Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


TTY#

Stability: 2 - Stable

The tty module houses the tty.ReadStream and tty.WriteStream classes. In most cases, you will not need to use this module directly.

When Node.js detects that it is being run inside a TTY context, then process.stdin will be a tty.ReadStream instance and process.stdout will be a tty.WriteStream instance. The preferred way to check if Node.js is being run in a TTY context is to check process.stdout.isTTY:

$ node -p -e "Boolean(process.stdout.isTTY)"
true
$ node -p -e "Boolean(process.stdout.isTTY)" | cat
false

Class: ReadStream#

A net.Socket subclass that represents the readable portion of a tty. In normal circumstances, process.stdin will be the only tty.ReadStream instance in any Node.js program (only when isatty(0) is true).

rs.isRaw#

A Boolean that is initialized to false. It represents the current "raw" state of the tty.ReadStream instance.

rs.setRawMode(mode)#

mode should be true or false. This sets the properties of the tty.ReadStream to act either as a raw device or default. isRaw will be set to the resulting mode.

Class: WriteStream#

A net.Socket subclass that represents the writable portion of a tty. In normal circumstances, process.stdout will be the only tty.WriteStream instance ever created (and only when isatty(1) is true).

Event: 'resize'#

function () {}

Emitted by refreshSize() when either of the columns or rows properties has changed.

process.stdout.on('resize', () => {
  console.log('screen size has changed!');
  console.log(`${process.stdout.columns}x${process.stdout.rows}`);
});

ws.columns#

A Number that gives the number of columns the TTY currently has. This property gets updated on 'resize' events.

ws.rows#

A Number that gives the number of rows the TTY currently has. This property gets updated on 'resize' events.

tty.isatty(fd)#

Returns true or false depending on if the fd is associated with a terminal.

tty.setRawMode(mode)#

Stability: 0 - Deprecated: Use tty.ReadStream#setRawMode (i.e. process.stdin.setRawMode) instead.
node-v4.2.6/doc/api/tty.json000644 000766 000024 00000011421 12650222331 015772 0ustar00iojsstaff000000 000000 { "source": "doc/api/tty.markdown", "modules": [ { "textRaw": "TTY", "name": "tty", "stability": 2, "stabilityText": "Stable", "desc": "

The tty module houses the tty.ReadStream and tty.WriteStream classes. In\nmost cases, you will not need to use this module directly.\n\n

\n

When Node.js detects that it is being run inside a TTY context, then process.stdin\nwill be a tty.ReadStream instance and process.stdout will be\na tty.WriteStream instance. The preferred way to check if Node.js is being run\nin a TTY context is to check process.stdout.isTTY:\n\n

\n
$ node -p -e "Boolean(process.stdout.isTTY)"\ntrue\n$ node -p -e "Boolean(process.stdout.isTTY)" | cat\nfalse
\n", "classes": [ { "textRaw": "Class: ReadStream", "type": "class", "name": "ReadStream", "desc": "

A net.Socket subclass that represents the readable portion of a tty. In normal\ncircumstances, process.stdin will be the only tty.ReadStream instance in any\nNode.js program (only when isatty(0) is true).\n\n

\n", "properties": [ { "textRaw": "rs.isRaw", "name": "isRaw", "desc": "

A Boolean that is initialized to false. It represents the current "raw" state\nof the tty.ReadStream instance.\n\n

\n" } ], "methods": [ { "textRaw": "rs.setRawMode(mode)", "type": "method", "name": "setRawMode", "desc": "

mode should be true or false. This sets the properties of the\ntty.ReadStream to act either as a raw device or default. isRaw will be set\nto the resulting mode.\n\n

\n", "signatures": [ { "params": [ { "name": "mode" } ] } ] } ] }, { "textRaw": "Class: WriteStream", "type": "class", "name": "WriteStream", "desc": "

A net.Socket subclass that represents the writable portion of a tty. In normal\ncircumstances, process.stdout will be the only tty.WriteStream instance\never created (and only when isatty(1) is true).\n\n

\n", "events": [ { "textRaw": "Event: 'resize'", "type": "event", "name": "resize", "desc": "

function () {}\n\n

\n

Emitted by refreshSize() when either of the columns or rows properties\nhas changed.\n\n

\n
process.stdout.on('resize', () => {\n  console.log('screen size has changed!');\n  console.log(`${process.stdout.columns}x${process.stdout.rows}`);\n});
\n", "params": [] } ], "properties": [ { "textRaw": "ws.columns", "name": "columns", "desc": "

A Number that gives the number of columns the TTY currently has. This property\ngets updated on 'resize' events.\n\n

\n" }, { "textRaw": "ws.rows", "name": "rows", "desc": "

A Number that gives the number of rows the TTY currently has. This property\ngets updated on 'resize' events.\n\n

\n" } ] } ], "methods": [ { "textRaw": "tty.isatty(fd)", "type": "method", "name": "isatty", "desc": "

Returns true or false depending on if the fd is associated with a\nterminal.\n\n

\n", "signatures": [ { "params": [ { "name": "fd" } ] } ] }, { "textRaw": "tty.setRawMode(mode)", "type": "method", "name": "setRawMode", "stability": 0, "stabilityText": "Deprecated: Use [tty.ReadStream#setRawMode][] (i.e. process.stdin.setRawMode) instead.", "signatures": [ { "params": [ { "name": "mode" } ] } ] } ], "type": "module", "displayName": "TTY" } ] } node-v4.2.6/doc/api/tty.markdown000644 000766 000024 00000004252 12650222326 016653 0ustar00iojsstaff000000 000000 # TTY Stability: 2 - Stable The `tty` module houses the `tty.ReadStream` and `tty.WriteStream` classes. In most cases, you will not need to use this module directly. When Node.js detects that it is being run inside a TTY context, then `process.stdin` will be a `tty.ReadStream` instance and `process.stdout` will be a `tty.WriteStream` instance. The preferred way to check if Node.js is being run in a TTY context is to check `process.stdout.isTTY`: $ node -p -e "Boolean(process.stdout.isTTY)" true $ node -p -e "Boolean(process.stdout.isTTY)" | cat false ## Class: ReadStream A `net.Socket` subclass that represents the readable portion of a tty. In normal circumstances, `process.stdin` will be the only `tty.ReadStream` instance in any Node.js program (only when `isatty(0)` is true). ### rs.isRaw A `Boolean` that is initialized to `false`. It represents the current "raw" state of the `tty.ReadStream` instance. ### rs.setRawMode(mode) `mode` should be `true` or `false`. This sets the properties of the `tty.ReadStream` to act either as a raw device or default. `isRaw` will be set to the resulting mode. ## Class: WriteStream A `net.Socket` subclass that represents the writable portion of a tty. In normal circumstances, `process.stdout` will be the only `tty.WriteStream` instance ever created (and only when `isatty(1)` is true). ### Event: 'resize' `function () {}` Emitted by `refreshSize()` when either of the `columns` or `rows` properties has changed. process.stdout.on('resize', () => { console.log('screen size has changed!'); console.log(`${process.stdout.columns}x${process.stdout.rows}`); }); ### ws.columns A `Number` that gives the number of columns the TTY currently has. This property gets updated on `'resize'` events. ### ws.rows A `Number` that gives the number of rows the TTY currently has. This property gets updated on `'resize'` events. ## tty.isatty(fd) Returns `true` or `false` depending on if the `fd` is associated with a terminal. ## tty.setRawMode(mode) Stability: 0 - Deprecated: Use [tty.ReadStream#setRawMode][] (i.e. process.stdin.setRawMode) instead. [tty.ReadStream#setRawMode]: #tty_rs_setrawmode_mode node-v4.2.6/doc/api/url.html000644 000766 000024 00000025046 12650222331 015757 0ustar00iojsstaff000000 000000 URL Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


URL#

Stability: 2 - Stable

This module has utilities for URL resolution and parsing. Call require('url') to use it.

URL Parsing#

Parsed URL objects have some or all of the following fields, depending on whether or not they exist in the URL string. Any parts that are not in the URL string will not be in the parsed object. Examples are shown for the URL

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • href: The full URL that was originally parsed. Both the protocol and host are lowercased.

    Example: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

  • protocol: The request protocol, lowercased.

    Example: 'http:'

  • slashes: The protocol requires slashes after the colon.

    Example: true or false

  • host: The full lowercased host portion of the URL, including port information.

    Example: 'host.com:8080'

  • auth: The authentication information portion of a URL.

    Example: 'user:pass'

  • hostname: Just the lowercased hostname portion of the host.

    Example: 'host.com'

  • port: The port number portion of the host.

    Example: '8080'

  • pathname: The path section of the URL, that comes after the host and before the query, including the initial slash if present. No decoding is performed.

    Example: '/p/a/t/h'

  • search: The 'query string' portion of the URL, including the leading question mark.

    Example: '?query=string'

  • path: Concatenation of pathname and search. No decoding is performed.

    Example: '/p/a/t/h?query=string'

  • query: Either the 'params' portion of the query string, or a querystring-parsed object.

    Example: 'query=string' or {'query':'string'}

  • hash: The 'fragment' portion of the URL including the pound-sign.

    Example: '#hash'

Escaped Characters#

Spaces (' ') and the following characters will be automatically escaped in the properties of URL objects:

< > " ` \r \n \t { } | \ ^ '

The following methods are provided by the URL module:

url.format(urlObj)#

Take a parsed URL object, and return a formatted URL string.

Here's how the formatting process works:

  • href will be ignored.
  • path will be ignored.
  • protocol is treated the same with or without the trailing : (colon).
    • The protocols http, https, ftp, gopher, file will be postfixed with :// (colon-slash-slash) as long as host/hostname are present.
    • All other protocols mailto, xmpp, aim, sftp, foo, etc will be postfixed with : (colon).
  • slashes set to true if the protocol requires :// (colon-slash-slash)
    • Only needs to be set for protocols not previously listed as requiring slashes, such as mongodb://localhost:8000/, or if host/hostname are absent.
  • auth will be used if present.
  • hostname will only be used if host is absent.
  • port will only be used if host is absent.
  • host will be used in place of hostname and port.
  • pathname is treated the same with or without the leading / (slash).
  • query (object; see querystring) will only be used if search is absent.
  • search will be used in place of query.
    • It is treated the same with or without the leading ? (question mark).
  • hash is treated the same with or without the leading # (pound sign, anchor).

url.parse(urlStr[, parseQueryString][, slashesDenoteHost])#

Take a URL string, and return an object.

Pass true as the second argument to also parse the query string using the querystring module. If true then the query property will always be assigned an object, and the search property will always be a (possibly empty) string. If false then the query property will not be parsed or decoded. Defaults to false.

Pass true as the third argument to treat //foo/bar as { host: 'foo', pathname: '/bar' } rather than { pathname: '//foo/bar' }. Defaults to false.

url.resolve(from, to)#

Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. Examples:

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'
node-v4.2.6/doc/api/url.json000644 000766 000024 00000017360 12650222331 015764 0ustar00iojsstaff000000 000000 { "source": "doc/api/url.markdown", "modules": [ { "textRaw": "URL", "name": "url", "stability": 2, "stabilityText": "Stable", "desc": "

This module has utilities for URL resolution and parsing.\nCall require('url') to use it.\n\n

\n", "modules": [ { "textRaw": "URL Parsing", "name": "url_parsing", "desc": "

Parsed URL objects have some or all of the following fields, depending on\nwhether or not they exist in the URL string. Any parts that are not in the URL\nstring will not be in the parsed object. Examples are shown for the URL\n\n

\n

'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'\n\n

\n
    \n
  • href: The full URL that was originally parsed. Both the protocol and host are lowercased.

    \n

    Example: 'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'

    \n
  • \n
  • protocol: The request protocol, lowercased.

    \n

    Example: 'http:'

    \n
  • \n
  • slashes: The protocol requires slashes after the colon.

    \n

    Example: true or false

    \n
  • \n
  • host: The full lowercased host portion of the URL, including port\ninformation.

    \n

    Example: 'host.com:8080'

    \n
  • \n
  • auth: The authentication information portion of a URL.

    \n

    Example: 'user:pass'

    \n
  • \n
  • hostname: Just the lowercased hostname portion of the host.

    \n

    Example: 'host.com'

    \n
  • \n
  • port: The port number portion of the host.

    \n

    Example: '8080'

    \n
  • \n
  • pathname: The path section of the URL, that comes after the host and\nbefore the query, including the initial slash if present. No decoding is\nperformed.

    \n

    Example: '/p/a/t/h'

    \n
  • \n
  • search: The 'query string' portion of the URL, including the leading\nquestion mark.

    \n

    Example: '?query=string'

    \n
  • \n
  • path: Concatenation of pathname and search. No decoding is performed.

    \n

    Example: '/p/a/t/h?query=string'

    \n
  • \n
  • query: Either the 'params' portion of the query string, or a\nquerystring-parsed object.

    \n

    Example: 'query=string' or {'query':'string'}

    \n
  • \n
  • hash: The 'fragment' portion of the URL including the pound-sign.

    \n

    Example: '#hash'

    \n
  • \n
\n", "modules": [ { "textRaw": "Escaped Characters", "name": "escaped_characters", "desc": "

Spaces (' ') and the following characters will be automatically escaped in the\nproperties of URL objects:\n\n

\n
< > " ` \\r \\n \\t { } | \\ ^ '
\n
\n

The following methods are provided by the URL module:\n\n

\n", "type": "module", "displayName": "Escaped Characters" } ], "type": "module", "displayName": "URL Parsing" } ], "methods": [ { "textRaw": "url.format(urlObj)", "type": "method", "name": "format", "desc": "

Take a parsed URL object, and return a formatted URL string.\n\n

\n

Here's how the formatting process works:\n\n

\n
    \n
  • href will be ignored.
  • \n
  • path will be ignored.
  • \n
  • protocol is treated the same with or without the trailing : (colon).
      \n
    • The protocols http, https, ftp, gopher, file will be\npostfixed with :// (colon-slash-slash) as long as host/hostname are present.
    • \n
    • All other protocols mailto, xmpp, aim, sftp, foo, etc will\nbe postfixed with : (colon).
    • \n
    \n
  • \n
  • slashes set to true if the protocol requires :// (colon-slash-slash)
      \n
    • Only needs to be set for protocols not previously listed as requiring\nslashes, such as mongodb://localhost:8000/, or if host/hostname are absent.
    • \n
    \n
  • \n
  • auth will be used if present.
  • \n
  • hostname will only be used if host is absent.
  • \n
  • port will only be used if host is absent.
  • \n
  • host will be used in place of hostname and port.
  • \n
  • pathname is treated the same with or without the leading / (slash).
  • \n
  • query (object; see querystring) will only be used if search is absent.
  • \n
  • search will be used in place of query.
      \n
    • It is treated the same with or without the leading ? (question mark).
    • \n
    \n
  • \n
  • hash is treated the same with or without the leading # (pound sign, anchor).
  • \n
\n", "signatures": [ { "params": [ { "name": "urlObj" } ] } ] }, { "textRaw": "url.parse(urlStr[, parseQueryString][, slashesDenoteHost])", "type": "method", "name": "parse", "desc": "

Take a URL string, and return an object.\n\n

\n

Pass true as the second argument to also parse the query string using the\nquerystring module. If true then the query property will always be\nassigned an object, and the search property will always be a (possibly\nempty) string. If false then the query property will not be parsed or\ndecoded. Defaults to false.\n\n

\n

Pass true as the third argument to treat //foo/bar as\n{ host: 'foo', pathname: '/bar' } rather than\n{ pathname: '//foo/bar' }. Defaults to false.\n\n

\n", "signatures": [ { "params": [ { "name": "urlStr" }, { "name": "parseQueryString", "optional": true }, { "name": "slashesDenoteHost", "optional": true } ] } ] }, { "textRaw": "url.resolve(from, to)", "type": "method", "name": "resolve", "desc": "

Take a base URL, and a href URL, and resolve them as a browser would for\nan anchor tag. Examples:\n\n

\n
url.resolve('/one/two/three', 'four')         // '/one/two/four'\nurl.resolve('http://example.com/', '/one')    // 'http://example.com/one'\nurl.resolve('http://example.com/one', '/two') // 'http://example.com/two'
\n", "signatures": [ { "params": [ { "name": "from" }, { "name": "to" } ] } ] } ], "type": "module", "displayName": "URL" } ] } node-v4.2.6/doc/api/url.markdown000644 000766 000024 00000010264 12650222326 016635 0ustar00iojsstaff000000 000000 # URL Stability: 2 - Stable This module has utilities for URL resolution and parsing. Call `require('url')` to use it. ## URL Parsing Parsed URL objects have some or all of the following fields, depending on whether or not they exist in the URL string. Any parts that are not in the URL string will not be in the parsed object. Examples are shown for the URL `'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'` * `href`: The full URL that was originally parsed. Both the protocol and host are lowercased. Example: `'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'` * `protocol`: The request protocol, lowercased. Example: `'http:'` * `slashes`: The protocol requires slashes after the colon. Example: true or false * `host`: The full lowercased host portion of the URL, including port information. Example: `'host.com:8080'` * `auth`: The authentication information portion of a URL. Example: `'user:pass'` * `hostname`: Just the lowercased hostname portion of the host. Example: `'host.com'` * `port`: The port number portion of the host. Example: `'8080'` * `pathname`: The path section of the URL, that comes after the host and before the query, including the initial slash if present. No decoding is performed. Example: `'/p/a/t/h'` * `search`: The 'query string' portion of the URL, including the leading question mark. Example: `'?query=string'` * `path`: Concatenation of `pathname` and `search`. No decoding is performed. Example: `'/p/a/t/h?query=string'` * `query`: Either the 'params' portion of the query string, or a querystring-parsed object. Example: `'query=string'` or `{'query':'string'}` * `hash`: The 'fragment' portion of the URL including the pound-sign. Example: `'#hash'` ### Escaped Characters Spaces (`' '`) and the following characters will be automatically escaped in the properties of URL objects: < > " ` \r \n \t { } | \ ^ ' --- The following methods are provided by the URL module: ## url.format(urlObj) Take a parsed URL object, and return a formatted URL string. Here's how the formatting process works: * `href` will be ignored. * `path` will be ignored. * `protocol` is treated the same with or without the trailing `:` (colon). * The protocols `http`, `https`, `ftp`, `gopher`, `file` will be postfixed with `://` (colon-slash-slash) as long as `host`/`hostname` are present. * All other protocols `mailto`, `xmpp`, `aim`, `sftp`, `foo`, etc will be postfixed with `:` (colon). * `slashes` set to `true` if the protocol requires `://` (colon-slash-slash) * Only needs to be set for protocols not previously listed as requiring slashes, such as `mongodb://localhost:8000/`, or if `host`/`hostname` are absent. * `auth` will be used if present. * `hostname` will only be used if `host` is absent. * `port` will only be used if `host` is absent. * `host` will be used in place of `hostname` and `port`. * `pathname` is treated the same with or without the leading `/` (slash). * `query` (object; see `querystring`) will only be used if `search` is absent. * `search` will be used in place of `query`. * It is treated the same with or without the leading `?` (question mark). * `hash` is treated the same with or without the leading `#` (pound sign, anchor). ## url.parse(urlStr[, parseQueryString][, slashesDenoteHost]) Take a URL string, and return an object. Pass `true` as the second argument to also parse the query string using the `querystring` module. If `true` then the `query` property will always be assigned an object, and the `search` property will always be a (possibly empty) string. If `false` then the `query` property will not be parsed or decoded. Defaults to `false`. Pass `true` as the third argument to treat `//foo/bar` as `{ host: 'foo', pathname: '/bar' }` rather than `{ pathname: '//foo/bar' }`. Defaults to `false`. ## url.resolve(from, to) Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. Examples: url.resolve('/one/two/three', 'four') // '/one/two/four' url.resolve('http://example.com/', '/one') // 'http://example.com/one' url.resolve('http://example.com/one', '/two') // 'http://example.com/two' node-v4.2.6/doc/api/util.html000644 000766 000024 00000062375 12650222331 016140 0ustar00iojsstaff000000 000000 util Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


util#

Stability: 2 - Stable

These functions are in the module 'util'. Use require('util') to access them.

The util module is primarily designed to support the needs of Node.js's internal APIs. Many of these utilities are useful for your own programs. If you find that these functions are lacking for your purposes, however, you are encouraged to write your own utilities. We are not interested in any future additions to the util module that are unnecessary for Node.js's internal functionality.

util.debug(string)#

Stability: 0 - Deprecated: use console.error() instead.

Deprecated predecessor of console.error.

util.debuglog(section)#

  • section String The section of the program to be debugged
  • Returns: Function The logging function

This is used to create a function which conditionally writes to stderr based on the existence of a NODE_DEBUG environment variable. If the section name appears in that environment variable, then the returned function will be similar to console.error(). If not, then the returned function is a no-op.

For example:

var debuglog = util.debuglog('foo');

var bar = 123;
debuglog('hello from foo [%d]', bar);

If this program is run with NODE_DEBUG=foo in the environment, then it will output something like:

FOO 3245: hello from foo [123]

where 3245 is the process id. If it is not run with that environment variable set, then it will not print anything.

You may separate multiple NODE_DEBUG environment variables with a comma. For example, NODE_DEBUG=fs,net,tls.

util.deprecate(function, string)#

Marks that a method should not be used any more.

const util = require('util');

exports.puts = util.deprecate(function() {
  for (var i = 0, len = arguments.length; i < len; ++i) {
    process.stdout.write(arguments[i] + '\n');
  }
}, 'util.puts: Use console.log instead');

It returns a modified function which warns once by default.

If --no-deprecation is set then this function is a NO-OP. Configurable at run-time through the process.noDeprecation boolean (only effective when set before a module is loaded.)

If --trace-deprecation is set, a warning and a stack trace are logged to the console the first time the deprecated API is used. Configurable at run-time through the process.traceDeprecation boolean.

If --throw-deprecation is set then the application throws an exception when the deprecated API is used. Configurable at run-time through the process.throwDeprecation boolean.

process.throwDeprecation takes precedence over process.traceDeprecation.

util.error([...])#

Stability: 0 - Deprecated: Use console.error() instead.

Deprecated predecessor of console.error.

util.format(format[, ...])#

Returns a formatted string using the first argument as a printf-like format.

The first argument is a string that contains zero or more placeholders. Each placeholder is replaced with the converted value from its corresponding argument. Supported placeholders are:

  • %s - String.
  • %d - Number (both integer and float).
  • %j - JSON. Replaced with the string '[Circular]' if the argument contains circular references.
  • %% - single percent sign ('%'). This does not consume an argument.

If the placeholder does not have a corresponding argument, the placeholder is not replaced.

util.format('%s:%s', 'foo'); // 'foo:%s'

If there are more arguments than placeholders, the extra arguments are coerced to strings (for objects and symbols, util.inspect() is used) and then concatenated, delimited by a space.

util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'

If the first argument is not a format string then util.format() returns a string that is the concatenation of all its arguments separated by spaces. Each argument is converted to a string with util.inspect().

util.format(1, 2, 3); // '1 2 3'

util.inherits(constructor, superConstructor)#

Inherit the prototype methods from one constructor into another. The prototype of constructor will be set to a new object created from superConstructor.

As an additional convenience, superConstructor will be accessible through the constructor.super_ property.

const util = require('util');
const EventEmitter = require('events');

function MyStream() {
    EventEmitter.call(this);
}

util.inherits(MyStream, EventEmitter);

MyStream.prototype.write = function(data) {
    this.emit('data', data);
}

var stream = new MyStream();

console.log(stream instanceof EventEmitter); // true
console.log(MyStream.super_ === EventEmitter); // true

stream.on('data', (data) => {
  console.log(`Received data: "${data}"`);
})
stream.write('It works!'); // Received data: "It works!"

util.inspect(object[, options])#

Return a string representation of object, which is useful for debugging.

An optional options object may be passed that alters certain aspects of the formatted string:

  • showHidden - if true then the object's non-enumerable and symbol properties will be shown too. Defaults to false.

  • depth - tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely pass null.

  • colors - if true, then the output will be styled with ANSI color codes. Defaults to false. Colors are customizable, see below.

  • customInspect - if false, then custom inspect(depth, opts) functions defined on the objects being inspected won't be called. Defaults to true.

Example of inspecting all properties of the util object:

const util = require('util');

console.log(util.inspect(util, { showHidden: true, depth: null }));

Values may supply their own custom inspect(depth, opts) functions, when called they receive the current depth in the recursive inspection, as well as the options object passed to util.inspect().

Customizing util.inspect colors#

Color output (if enabled) of util.inspect is customizable globally via util.inspect.styles and util.inspect.colors objects.

util.inspect.styles is a map assigning each style a color from util.inspect.colors. Highlighted styles and their default values are: number (yellow) boolean (yellow) string (green) date (magenta) regexp (red) null (bold) undefined (grey) special - only function at this time (cyan) * name (intentionally no styling)

Predefined color codes are: white, grey, black, blue, cyan, green, magenta, red and yellow. There are also bold, italic, underline and inverse codes.

Custom inspect() function on Objects#

Objects also may define their own inspect(depth) function which util.inspect() will invoke and use the result of when inspecting the object:

const util = require('util');

var obj = { name: 'nate' };
obj.inspect = function(depth) {
  return `{${this.name}}`;
};

util.inspect(obj);
  // "{nate}"

You may also return another Object entirely, and the returned String will be formatted according to the returned Object. This is similar to how JSON.stringify() works:

var obj = { foo: 'this will not show up in the inspect() output' };
obj.inspect = function(depth) {
  return { bar: 'baz' };
};

util.inspect(obj);
  // "{ bar: 'baz' }"

util.isArray(object)#

Stability: 0 - Deprecated

Internal alias for Array.isArray.

Returns true if the given "object" is an Array. false otherwise.

const util = require('util');

util.isArray([])
  // true
util.isArray(new Array)
  // true
util.isArray({})
  // false

util.isBoolean(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Boolean. false otherwise.

const util = require('util');

util.isBoolean(1)
  // false
util.isBoolean(0)
  // false
util.isBoolean(false)
  // true

util.isBuffer(object)#

Stability: 0 - Deprecated

Use Buffer.isBuffer() instead.

Returns true if the given "object" is a Buffer. false otherwise.

const util = require('util');

util.isBuffer({ length: 0 })
  // false
util.isBuffer([])
  // false
util.isBuffer(new Buffer('hello world'))
  // true

util.isDate(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Date. false otherwise.

const util = require('util');

util.isDate(new Date())
  // true
util.isDate(Date())
  // false (without 'new' returns a String)
util.isDate({})
  // false

util.isError(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is an Error. false otherwise.

const util = require('util');

util.isError(new Error())
  // true
util.isError(new TypeError())
  // true
util.isError({ name: 'Error', message: 'an error occurred' })
  // false

util.isFunction(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Function. false otherwise.

const util = require('util');

function Foo() {}
var Bar = function() {};

util.isFunction({})
  // false
util.isFunction(Foo)
  // true
util.isFunction(Bar)
  // true

util.isNull(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is strictly null. false otherwise.

const util = require('util');

util.isNull(0)
  // false
util.isNull(undefined)
  // false
util.isNull(null)
  // true

util.isNullOrUndefined(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is null or undefined. false otherwise.

const util = require('util');

util.isNullOrUndefined(0)
  // false
util.isNullOrUndefined(undefined)
  // true
util.isNullOrUndefined(null)
  // true

util.isNumber(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Number. false otherwise.

const util = require('util');

util.isNumber(false)
  // false
util.isNumber(Infinity)
  // true
util.isNumber(0)
  // true
util.isNumber(NaN)
  // true

util.isObject(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is strictly an Object and not a Function. false otherwise.

const util = require('util');

util.isObject(5)
  // false
util.isObject(null)
  // false
util.isObject({})
  // true
util.isObject(function(){})
  // false

util.isPrimitive(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a primitive type. false otherwise.

const util = require('util');

util.isPrimitive(5)
  // true
util.isPrimitive('foo')
  // true
util.isPrimitive(false)
  // true
util.isPrimitive(null)
  // true
util.isPrimitive(undefined)
  // true
util.isPrimitive({})
  // false
util.isPrimitive(function() {})
  // false
util.isPrimitive(/^$/)
  // false
util.isPrimitive(new Date())
  // false

util.isRegExp(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a RegExp. false otherwise.

const util = require('util');

util.isRegExp(/some regexp/)
  // true
util.isRegExp(new RegExp('another regexp'))
  // true
util.isRegExp({})
  // false

util.isString(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a String. false otherwise.

const util = require('util');

util.isString('')
  // true
util.isString('foo')
  // true
util.isString(String('foo'))
  // true
util.isString(5)
  // false

util.isSymbol(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is a Symbol. false otherwise.

const util = require('util');

util.isSymbol(5)
  // false
util.isSymbol('foo')
  // false
util.isSymbol(Symbol('foo'))
  // true

util.isUndefined(object)#

Stability: 0 - Deprecated

Returns true if the given "object" is undefined. false otherwise.

const util = require('util');

var foo;
util.isUndefined(5)
  // false
util.isUndefined(foo)
  // true
util.isUndefined(null)
  // false

util.log(string)#

Output with timestamp on stdout.

require('util').log('Timestamped message.');

util.print([...])#

Stability: 0 - Deprecated: Use console.log instead.

Deprecated predecessor of console.log.

util.pump(readableStream, writableStream[, callback])#

Stability: 0 - Deprecated: Use readableStream.pipe(writableStream)

Deprecated predecessor of stream.pipe().

util.puts([...])#

Stability: 0 - Deprecated: Use console.log() instead.

Deprecated predecessor of console.log.

node-v4.2.6/doc/api/util.json000644 000766 000024 00000063365 12650222331 016145 0ustar00iojsstaff000000 000000 { "source": "doc/api/util.markdown", "modules": [ { "textRaw": "util", "name": "util", "stability": 2, "stabilityText": "Stable", "desc": "

These functions are in the module 'util'. Use require('util') to\naccess them.\n\n

\n

The util module is primarily designed to support the needs of Node.js's\ninternal APIs. Many of these utilities are useful for your own\nprograms. If you find that these functions are lacking for your\npurposes, however, you are encouraged to write your own utilities. We\nare not interested in any future additions to the util module that\nare unnecessary for Node.js's internal functionality.\n\n

\n", "methods": [ { "textRaw": "util.debug(string)", "type": "method", "name": "debug", "stability": 0, "stabilityText": "Deprecated: use console.error() instead.", "desc": "

Deprecated predecessor of console.error.\n\n

\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "util.debuglog(section)", "type": "method", "name": "debuglog", "signatures": [ { "return": { "textRaw": "Returns: {Function} The logging function ", "name": "return", "type": "Function", "desc": "The logging function" }, "params": [ { "textRaw": "`section` {String} The section of the program to be debugged ", "name": "section", "type": "String", "desc": "The section of the program to be debugged" } ] }, { "params": [ { "name": "section" } ] } ], "desc": "

This is used to create a function which conditionally writes to stderr\nbased on the existence of a NODE_DEBUG environment variable. If the\nsection name appears in that environment variable, then the returned\nfunction will be similar to console.error(). If not, then the\nreturned function is a no-op.\n\n

\n

For example:\n\n

\n
var debuglog = util.debuglog('foo');\n\nvar bar = 123;\ndebuglog('hello from foo [%d]', bar);
\n

If this program is run with NODE_DEBUG=foo in the environment, then\nit will output something like:\n\n

\n
FOO 3245: hello from foo [123]
\n

where 3245 is the process id. If it is not run with that\nenvironment variable set, then it will not print anything.\n\n

\n

You may separate multiple NODE_DEBUG environment variables with a\ncomma. For example, NODE_DEBUG=fs,net,tls.\n\n

\n" }, { "textRaw": "util.deprecate(function, string)", "type": "method", "name": "deprecate", "desc": "

Marks that a method should not be used any more.\n\n

\n
const util = require('util');\n\nexports.puts = util.deprecate(function() {\n  for (var i = 0, len = arguments.length; i < len; ++i) {\n    process.stdout.write(arguments[i] + '\\n');\n  }\n}, 'util.puts: Use console.log instead');
\n

It returns a modified function which warns once by default.\n\n

\n

If --no-deprecation is set then this function is a NO-OP. Configurable\nat run-time through the process.noDeprecation boolean (only effective\nwhen set before a module is loaded.)\n\n

\n

If --trace-deprecation is set, a warning and a stack trace are logged\nto the console the first time the deprecated API is used. Configurable\nat run-time through the process.traceDeprecation boolean.\n\n

\n

If --throw-deprecation is set then the application throws an exception\nwhen the deprecated API is used. Configurable at run-time through the\nprocess.throwDeprecation boolean.\n\n

\n

process.throwDeprecation takes precedence over process.traceDeprecation.\n\n

\n", "signatures": [ { "params": [ { "name": "function" }, { "name": "string" } ] } ] }, { "textRaw": "util.error([...])", "type": "method", "name": "error", "stability": 0, "stabilityText": "Deprecated: Use console.error() instead.", "desc": "

Deprecated predecessor of console.error.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.format(format[, ...])", "type": "method", "name": "format", "desc": "

Returns a formatted string using the first argument as a printf-like format.\n\n

\n

The first argument is a string that contains zero or more placeholders.\nEach placeholder is replaced with the converted value from its corresponding\nargument. Supported placeholders are:\n\n

\n
    \n
  • %s - String.
  • \n
  • %d - Number (both integer and float).
  • \n
  • %j - JSON. Replaced with the string '[Circular]' if the argument\ncontains circular references.
  • \n
  • %% - single percent sign ('%'). This does not consume an argument.
  • \n
\n

If the placeholder does not have a corresponding argument, the placeholder is\nnot replaced.\n\n

\n
util.format('%s:%s', 'foo'); // 'foo:%s'
\n

If there are more arguments than placeholders, the extra arguments are\ncoerced to strings (for objects and symbols, util.inspect() is used)\nand then concatenated, delimited by a space.\n\n

\n
util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz'
\n

If the first argument is not a format string then util.format() returns\na string that is the concatenation of all its arguments separated by spaces.\nEach argument is converted to a string with util.inspect().\n\n

\n
util.format(1, 2, 3); // '1 2 3'
\n", "signatures": [ { "params": [ { "name": "format" }, { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.inherits(constructor, superConstructor)", "type": "method", "name": "inherits", "desc": "

Inherit the prototype methods from one [constructor][] into another. The\nprototype of constructor will be set to a new object created from\nsuperConstructor.\n\n

\n

As an additional convenience, superConstructor will be accessible\nthrough the constructor.super_ property.\n\n

\n
const util = require('util');\nconst EventEmitter = require('events');\n\nfunction MyStream() {\n    EventEmitter.call(this);\n}\n\nutil.inherits(MyStream, EventEmitter);\n\nMyStream.prototype.write = function(data) {\n    this.emit('data', data);\n}\n\nvar stream = new MyStream();\n\nconsole.log(stream instanceof EventEmitter); // true\nconsole.log(MyStream.super_ === EventEmitter); // true\n\nstream.on('data', (data) => {\n  console.log(`Received data: "${data}"`);\n})\nstream.write('It works!'); // Received data: "It works!"
\n", "signatures": [ { "params": [ { "name": "constructor" }, { "name": "superConstructor" } ] } ] }, { "textRaw": "util.inspect(object[, options])", "type": "method", "name": "inspect", "desc": "

Return a string representation of object, which is useful for debugging.\n\n

\n

An optional options object may be passed that alters certain aspects of the\nformatted string:\n\n

\n
    \n
  • showHidden - if true then the object's non-enumerable and symbol\nproperties will be shown too. Defaults to false.

    \n
  • \n
  • depth - tells inspect how many times to recurse while formatting the\nobject. This is useful for inspecting large complicated objects. Defaults to\n2. To make it recurse indefinitely pass null.

    \n
  • \n
  • colors - if true, then the output will be styled with ANSI color codes.\nDefaults to false. Colors are customizable, see below.

    \n
  • \n
  • customInspect - if false, then custom inspect(depth, opts) functions\ndefined on the objects being inspected won't be called. Defaults to true.

    \n
  • \n
\n

Example of inspecting all properties of the util object:\n\n

\n
const util = require('util');\n\nconsole.log(util.inspect(util, { showHidden: true, depth: null }));
\n

Values may supply their own custom inspect(depth, opts) functions, when\ncalled they receive the current depth in the recursive inspection, as well as\nthe options object passed to util.inspect().\n\n

\n", "miscs": [ { "textRaw": "Customizing `util.inspect` colors", "name": "Customizing `util.inspect` colors", "type": "misc", "desc": "

Color output (if enabled) of util.inspect is customizable globally\nvia util.inspect.styles and util.inspect.colors objects.\n\n

\n

util.inspect.styles is a map assigning each style a color\nfrom util.inspect.colors.\nHighlighted styles and their default values are:\n number (yellow)\n boolean (yellow)\n string (green)\n date (magenta)\n regexp (red)\n null (bold)\n undefined (grey)\n special - only function at this time (cyan)\n * name (intentionally no styling)\n\n

\n

Predefined color codes are: white, grey, black, blue, cyan,\ngreen, magenta, red and yellow.\nThere are also bold, italic, underline and inverse codes.\n\n

\n" }, { "textRaw": "Custom `inspect()` function on Objects", "name": "Custom `inspect()` function on Objects", "type": "misc", "desc": "

Objects also may define their own inspect(depth) function which util.inspect()\nwill invoke and use the result of when inspecting the object:\n\n

\n
const util = require('util');\n\nvar obj = { name: 'nate' };\nobj.inspect = function(depth) {\n  return `{${this.name}}`;\n};\n\nutil.inspect(obj);\n  // "{nate}"
\n

You may also return another Object entirely, and the returned String will be\nformatted according to the returned Object. This is similar to how\nJSON.stringify() works:\n\n

\n
var obj = { foo: 'this will not show up in the inspect() output' };\nobj.inspect = function(depth) {\n  return { bar: 'baz' };\n};\n\nutil.inspect(obj);\n  // "{ bar: 'baz' }"
\n" } ], "signatures": [ { "params": [ { "name": "object" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "util.isArray(object)", "type": "method", "name": "isArray", "stability": 0, "stabilityText": "Deprecated", "desc": "

Internal alias for [Array.isArray][].\n\n

\n

Returns true if the given "object" is an Array. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isArray([])\n  // true\nutil.isArray(new Array)\n  // true\nutil.isArray({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isBoolean(object)", "type": "method", "name": "isBoolean", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Boolean. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isBoolean(1)\n  // false\nutil.isBoolean(0)\n  // false\nutil.isBoolean(false)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isBuffer(object)", "type": "method", "name": "isBuffer", "stability": 0, "stabilityText": "Deprecated", "desc": "

Use Buffer.isBuffer() instead.\n\n

\n

Returns true if the given "object" is a Buffer. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isBuffer({ length: 0 })\n  // false\nutil.isBuffer([])\n  // false\nutil.isBuffer(new Buffer('hello world'))\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isDate(object)", "type": "method", "name": "isDate", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Date. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isDate(new Date())\n  // true\nutil.isDate(Date())\n  // false (without 'new' returns a String)\nutil.isDate({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isError(object)", "type": "method", "name": "isError", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is an [Error][]. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isError(new Error())\n  // true\nutil.isError(new TypeError())\n  // true\nutil.isError({ name: 'Error', message: 'an error occurred' })\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isFunction(object)", "type": "method", "name": "isFunction", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Function. false otherwise.\n\n

\n
const util = require('util');\n\nfunction Foo() {}\nvar Bar = function() {};\n\nutil.isFunction({})\n  // false\nutil.isFunction(Foo)\n  // true\nutil.isFunction(Bar)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNull(object)", "type": "method", "name": "isNull", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is strictly null. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNull(0)\n  // false\nutil.isNull(undefined)\n  // false\nutil.isNull(null)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNullOrUndefined(object)", "type": "method", "name": "isNullOrUndefined", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is null or undefined. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNullOrUndefined(0)\n  // false\nutil.isNullOrUndefined(undefined)\n  // true\nutil.isNullOrUndefined(null)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isNumber(object)", "type": "method", "name": "isNumber", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Number. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isNumber(false)\n  // false\nutil.isNumber(Infinity)\n  // true\nutil.isNumber(0)\n  // true\nutil.isNumber(NaN)\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isObject(object)", "type": "method", "name": "isObject", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is strictly an Object and not a\nFunction. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isObject(5)\n  // false\nutil.isObject(null)\n  // false\nutil.isObject({})\n  // true\nutil.isObject(function(){})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isPrimitive(object)", "type": "method", "name": "isPrimitive", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a primitive type. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isPrimitive(5)\n  // true\nutil.isPrimitive('foo')\n  // true\nutil.isPrimitive(false)\n  // true\nutil.isPrimitive(null)\n  // true\nutil.isPrimitive(undefined)\n  // true\nutil.isPrimitive({})\n  // false\nutil.isPrimitive(function() {})\n  // false\nutil.isPrimitive(/^$/)\n  // false\nutil.isPrimitive(new Date())\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isRegExp(object)", "type": "method", "name": "isRegExp", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a RegExp. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isRegExp(/some regexp/)\n  // true\nutil.isRegExp(new RegExp('another regexp'))\n  // true\nutil.isRegExp({})\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isString(object)", "type": "method", "name": "isString", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a String. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isString('')\n  // true\nutil.isString('foo')\n  // true\nutil.isString(String('foo'))\n  // true\nutil.isString(5)\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isSymbol(object)", "type": "method", "name": "isSymbol", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is a Symbol. false otherwise.\n\n

\n
const util = require('util');\n\nutil.isSymbol(5)\n  // false\nutil.isSymbol('foo')\n  // false\nutil.isSymbol(Symbol('foo'))\n  // true
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.isUndefined(object)", "type": "method", "name": "isUndefined", "stability": 0, "stabilityText": "Deprecated", "desc": "

Returns true if the given "object" is undefined. false otherwise.\n\n

\n
const util = require('util');\n\nvar foo;\nutil.isUndefined(5)\n  // false\nutil.isUndefined(foo)\n  // true\nutil.isUndefined(null)\n  // false
\n", "signatures": [ { "params": [ { "name": "object" } ] } ] }, { "textRaw": "util.log(string)", "type": "method", "name": "log", "desc": "

Output with timestamp on stdout.\n\n

\n
require('util').log('Timestamped message.');
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] }, { "textRaw": "util.print([...])", "type": "method", "name": "print", "stability": 0, "stabilityText": "Deprecated: Use `console.log` instead.", "desc": "

Deprecated predecessor of console.log.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] }, { "textRaw": "util.pump(readableStream, writableStream[, callback])", "type": "method", "name": "pump", "stability": 0, "stabilityText": "Deprecated: Use readableStream.pipe(writableStream)", "desc": "

Deprecated predecessor of stream.pipe().\n\n

\n", "signatures": [ { "params": [ { "name": "readableStream" }, { "name": "writableStream" }, { "name": "callback", "optional": true } ] } ] }, { "textRaw": "util.puts([...])", "type": "method", "name": "puts", "stability": 0, "stabilityText": "Deprecated: Use console.log() instead.", "desc": "

Deprecated predecessor of console.log.\n\n

\n", "signatures": [ { "params": [ { "name": "...", "optional": true } ] } ] } ], "type": "module", "displayName": "util" } ] } node-v4.2.6/doc/api/util.markdown000644 000766 000024 00000032025 12650222326 017007 0ustar00iojsstaff000000 000000 # util Stability: 2 - Stable These functions are in the module `'util'`. Use `require('util')` to access them. The `util` module is primarily designed to support the needs of Node.js's internal APIs. Many of these utilities are useful for your own programs. If you find that these functions are lacking for your purposes, however, you are encouraged to write your own utilities. We are not interested in any future additions to the `util` module that are unnecessary for Node.js's internal functionality. ## util.debug(string) Stability: 0 - Deprecated: use console.error() instead. Deprecated predecessor of `console.error`. ## util.debuglog(section) * `section` {String} The section of the program to be debugged * Returns: {Function} The logging function This is used to create a function which conditionally writes to stderr based on the existence of a `NODE_DEBUG` environment variable. If the `section` name appears in that environment variable, then the returned function will be similar to `console.error()`. If not, then the returned function is a no-op. For example: ```javascript var debuglog = util.debuglog('foo'); var bar = 123; debuglog('hello from foo [%d]', bar); ``` If this program is run with `NODE_DEBUG=foo` in the environment, then it will output something like: FOO 3245: hello from foo [123] where `3245` is the process id. If it is not run with that environment variable set, then it will not print anything. You may separate multiple `NODE_DEBUG` environment variables with a comma. For example, `NODE_DEBUG=fs,net,tls`. ## util.deprecate(function, string) Marks that a method should not be used any more. const util = require('util'); exports.puts = util.deprecate(function() { for (var i = 0, len = arguments.length; i < len; ++i) { process.stdout.write(arguments[i] + '\n'); } }, 'util.puts: Use console.log instead'); It returns a modified function which warns once by default. If `--no-deprecation` is set then this function is a NO-OP. Configurable at run-time through the `process.noDeprecation` boolean (only effective when set before a module is loaded.) If `--trace-deprecation` is set, a warning and a stack trace are logged to the console the first time the deprecated API is used. Configurable at run-time through the `process.traceDeprecation` boolean. If `--throw-deprecation` is set then the application throws an exception when the deprecated API is used. Configurable at run-time through the `process.throwDeprecation` boolean. `process.throwDeprecation` takes precedence over `process.traceDeprecation`. ## util.error([...]) Stability: 0 - Deprecated: Use console.error() instead. Deprecated predecessor of `console.error`. ## util.format(format[, ...]) Returns a formatted string using the first argument as a `printf`-like format. The first argument is a string that contains zero or more *placeholders*. Each placeholder is replaced with the converted value from its corresponding argument. Supported placeholders are: * `%s` - String. * `%d` - Number (both integer and float). * `%j` - JSON. Replaced with the string `'[Circular]'` if the argument contains circular references. * `%%` - single percent sign (`'%'`). This does not consume an argument. If the placeholder does not have a corresponding argument, the placeholder is not replaced. util.format('%s:%s', 'foo'); // 'foo:%s' If there are more arguments than placeholders, the extra arguments are coerced to strings (for objects and symbols, `util.inspect()` is used) and then concatenated, delimited by a space. util.format('%s:%s', 'foo', 'bar', 'baz'); // 'foo:bar baz' If the first argument is not a format string then `util.format()` returns a string that is the concatenation of all its arguments separated by spaces. Each argument is converted to a string with `util.inspect()`. util.format(1, 2, 3); // '1 2 3' ## util.inherits(constructor, superConstructor) Inherit the prototype methods from one [constructor][] into another. The prototype of `constructor` will be set to a new object created from `superConstructor`. As an additional convenience, `superConstructor` will be accessible through the `constructor.super_` property. const util = require('util'); const EventEmitter = require('events'); function MyStream() { EventEmitter.call(this); } util.inherits(MyStream, EventEmitter); MyStream.prototype.write = function(data) { this.emit('data', data); } var stream = new MyStream(); console.log(stream instanceof EventEmitter); // true console.log(MyStream.super_ === EventEmitter); // true stream.on('data', (data) => { console.log(`Received data: "${data}"`); }) stream.write('It works!'); // Received data: "It works!" ## util.inspect(object[, options]) Return a string representation of `object`, which is useful for debugging. An optional *options* object may be passed that alters certain aspects of the formatted string: - `showHidden` - if `true` then the object's non-enumerable and symbol properties will be shown too. Defaults to `false`. - `depth` - tells `inspect` how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to `2`. To make it recurse indefinitely pass `null`. - `colors` - if `true`, then the output will be styled with ANSI color codes. Defaults to `false`. Colors are customizable, see below. - `customInspect` - if `false`, then custom `inspect(depth, opts)` functions defined on the objects being inspected won't be called. Defaults to `true`. Example of inspecting all properties of the `util` object: const util = require('util'); console.log(util.inspect(util, { showHidden: true, depth: null })); Values may supply their own custom `inspect(depth, opts)` functions, when called they receive the current depth in the recursive inspection, as well as the options object passed to `util.inspect()`. ### Customizing `util.inspect` colors Color output (if enabled) of `util.inspect` is customizable globally via `util.inspect.styles` and `util.inspect.colors` objects. `util.inspect.styles` is a map assigning each style a color from `util.inspect.colors`. Highlighted styles and their default values are: * `number` (yellow) * `boolean` (yellow) * `string` (green) * `date` (magenta) * `regexp` (red) * `null` (bold) * `undefined` (grey) * `special` - only function at this time (cyan) * `name` (intentionally no styling) Predefined color codes are: `white`, `grey`, `black`, `blue`, `cyan`, `green`, `magenta`, `red` and `yellow`. There are also `bold`, `italic`, `underline` and `inverse` codes. ### Custom `inspect()` function on Objects Objects also may define their own `inspect(depth)` function which `util.inspect()` will invoke and use the result of when inspecting the object: const util = require('util'); var obj = { name: 'nate' }; obj.inspect = function(depth) { return `{${this.name}}`; }; util.inspect(obj); // "{nate}" You may also return another Object entirely, and the returned String will be formatted according to the returned Object. This is similar to how `JSON.stringify()` works: var obj = { foo: 'this will not show up in the inspect() output' }; obj.inspect = function(depth) { return { bar: 'baz' }; }; util.inspect(obj); // "{ bar: 'baz' }" ## util.isArray(object) Stability: 0 - Deprecated Internal alias for [`Array.isArray`][]. Returns `true` if the given "object" is an `Array`. `false` otherwise. const util = require('util'); util.isArray([]) // true util.isArray(new Array) // true util.isArray({}) // false ## util.isBoolean(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `Boolean`. `false` otherwise. const util = require('util'); util.isBoolean(1) // false util.isBoolean(0) // false util.isBoolean(false) // true ## util.isBuffer(object) Stability: 0 - Deprecated Use `Buffer.isBuffer()` instead. Returns `true` if the given "object" is a `Buffer`. `false` otherwise. const util = require('util'); util.isBuffer({ length: 0 }) // false util.isBuffer([]) // false util.isBuffer(new Buffer('hello world')) // true ## util.isDate(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `Date`. `false` otherwise. const util = require('util'); util.isDate(new Date()) // true util.isDate(Date()) // false (without 'new' returns a String) util.isDate({}) // false ## util.isError(object) Stability: 0 - Deprecated Returns `true` if the given "object" is an [`Error`][]. `false` otherwise. const util = require('util'); util.isError(new Error()) // true util.isError(new TypeError()) // true util.isError({ name: 'Error', message: 'an error occurred' }) // false ## util.isFunction(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `Function`. `false` otherwise. const util = require('util'); function Foo() {} var Bar = function() {}; util.isFunction({}) // false util.isFunction(Foo) // true util.isFunction(Bar) // true ## util.isNull(object) Stability: 0 - Deprecated Returns `true` if the given "object" is strictly `null`. `false` otherwise. const util = require('util'); util.isNull(0) // false util.isNull(undefined) // false util.isNull(null) // true ## util.isNullOrUndefined(object) Stability: 0 - Deprecated Returns `true` if the given "object" is `null` or `undefined`. `false` otherwise. const util = require('util'); util.isNullOrUndefined(0) // false util.isNullOrUndefined(undefined) // true util.isNullOrUndefined(null) // true ## util.isNumber(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `Number`. `false` otherwise. const util = require('util'); util.isNumber(false) // false util.isNumber(Infinity) // true util.isNumber(0) // true util.isNumber(NaN) // true ## util.isObject(object) Stability: 0 - Deprecated Returns `true` if the given "object" is strictly an `Object` __and__ not a `Function`. `false` otherwise. const util = require('util'); util.isObject(5) // false util.isObject(null) // false util.isObject({}) // true util.isObject(function(){}) // false ## util.isPrimitive(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a primitive type. `false` otherwise. const util = require('util'); util.isPrimitive(5) // true util.isPrimitive('foo') // true util.isPrimitive(false) // true util.isPrimitive(null) // true util.isPrimitive(undefined) // true util.isPrimitive({}) // false util.isPrimitive(function() {}) // false util.isPrimitive(/^$/) // false util.isPrimitive(new Date()) // false ## util.isRegExp(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `RegExp`. `false` otherwise. const util = require('util'); util.isRegExp(/some regexp/) // true util.isRegExp(new RegExp('another regexp')) // true util.isRegExp({}) // false ## util.isString(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `String`. `false` otherwise. const util = require('util'); util.isString('') // true util.isString('foo') // true util.isString(String('foo')) // true util.isString(5) // false ## util.isSymbol(object) Stability: 0 - Deprecated Returns `true` if the given "object" is a `Symbol`. `false` otherwise. const util = require('util'); util.isSymbol(5) // false util.isSymbol('foo') // false util.isSymbol(Symbol('foo')) // true ## util.isUndefined(object) Stability: 0 - Deprecated Returns `true` if the given "object" is `undefined`. `false` otherwise. const util = require('util'); var foo; util.isUndefined(5) // false util.isUndefined(foo) // true util.isUndefined(null) // false ## util.log(string) Output with timestamp on `stdout`. require('util').log('Timestamped message.'); ## util.print([...]) Stability: 0 - Deprecated: Use `console.log` instead. Deprecated predecessor of `console.log`. ## util.pump(readableStream, writableStream[, callback]) Stability: 0 - Deprecated: Use readableStream.pipe(writableStream) Deprecated predecessor of `stream.pipe()`. ## util.puts([...]) Stability: 0 - Deprecated: Use console.log() instead. Deprecated predecessor of `console.log`. [`Array.isArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray [constructor]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor [`Error`]: errors.html#errors_class_error node-v4.2.6/doc/api/v8.html000644 000766 000024 00000012740 12650222331 015507 0ustar00iojsstaff000000 000000 V8 Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


V8#

Stability: 2 - Stable

This module exposes events and interfaces specific to the version of V8 built with Node.js. These interfaces are subject to change by upstream and are therefore not covered under the stability index.

getHeapStatistics()#

Returns an object with the following properties

{
  total_heap_size: 7326976,
  total_heap_size_executable: 4194304,
  total_physical_size: 7326976,
  total_available_size: 1152656,
  used_heap_size: 3476208,
  heap_size_limit: 1535115264
}

setFlagsFromString(string)#

Set additional V8 command line flags. Use with care; changing settings after the VM has started may result in unpredictable behavior, including crashes and data loss. Or it may simply do nothing.

The V8 options available for a version of Node.js may be determined by running node --v8-options. An unofficial, community-maintained list of options and their effects is available here.

Usage:

// Print GC events to stdout for one minute.
const v8 = require('v8');
v8.setFlagsFromString('--trace_gc');
setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
node-v4.2.6/doc/api/v8.json000644 000766 000024 00000003766 12650222331 015524 0ustar00iojsstaff000000 000000 { "source": "doc/api/v8.markdown", "modules": [ { "textRaw": "V8", "name": "v8", "stability": 2, "stabilityText": "Stable", "desc": "

This module exposes events and interfaces specific to the version of [V8][]\nbuilt with Node.js. These interfaces are subject to change by upstream and are\ntherefore not covered under the stability index.\n\n

\n", "methods": [ { "textRaw": "getHeapStatistics()", "type": "method", "name": "getHeapStatistics", "desc": "

Returns an object with the following properties\n\n

\n
{\n  total_heap_size: 7326976,\n  total_heap_size_executable: 4194304,\n  total_physical_size: 7326976,\n  total_available_size: 1152656,\n  used_heap_size: 3476208,\n  heap_size_limit: 1535115264\n}
\n", "signatures": [ { "params": [] } ] }, { "textRaw": "setFlagsFromString(string)", "type": "method", "name": "setFlagsFromString", "desc": "

Set additional V8 command line flags. Use with care; changing settings\nafter the VM has started may result in unpredictable behavior, including\ncrashes and data loss. Or it may simply do nothing.\n\n

\n

The V8 options available for a version of Node.js may be determined by running\nnode --v8-options. An unofficial, community-maintained list of options\nand their effects is available [here][].\n\n

\n

Usage:\n\n

\n
// Print GC events to stdout for one minute.\nconst v8 = require('v8');\nv8.setFlagsFromString('--trace_gc');\nsetTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
\n", "signatures": [ { "params": [ { "name": "string" } ] } ] } ], "type": "module", "displayName": "V8" } ] } node-v4.2.6/doc/api/v8.markdown000644 000766 000024 00000002334 12650222326 016367 0ustar00iojsstaff000000 000000 # V8 Stability: 2 - Stable This module exposes events and interfaces specific to the version of [V8][] built with Node.js. These interfaces are subject to change by upstream and are therefore not covered under the stability index. ## getHeapStatistics() Returns an object with the following properties ``` { total_heap_size: 7326976, total_heap_size_executable: 4194304, total_physical_size: 7326976, total_available_size: 1152656, used_heap_size: 3476208, heap_size_limit: 1535115264 } ``` ## setFlagsFromString(string) Set additional V8 command line flags. Use with care; changing settings after the VM has started may result in unpredictable behavior, including crashes and data loss. Or it may simply do nothing. The V8 options available for a version of Node.js may be determined by running `node --v8-options`. An unofficial, community-maintained list of options and their effects is available [here][]. Usage: ``` // Print GC events to stdout for one minute. const v8 = require('v8'); v8.setFlagsFromString('--trace_gc'); setTimeout(function() { v8.setFlagsFromString('--notrace_gc'); }, 60e3); ``` [V8]: https://code.google.com/p/v8/ [here]: https://github.com/thlorenz/v8-flags/blob/master/flags-0.11.md node-v4.2.6/doc/api/vm.html000644 000766 000024 00000044210 12650222331 015571 0ustar00iojsstaff000000 000000 Executing JavaScript Node.js v4.2.6 Manual & Documentation

Node.js v4.2.6 Documentation


Executing JavaScript#

Stability: 2 - Stable

You can access this module with:

const vm = require('vm');

JavaScript code can be compiled and run immediately or compiled, saved, and run later.

Class: Script#

A class for holding precompiled scripts, and running them in specific sandboxes.

new vm.Script(code, options)#

Creating a new Script compiles code but does not run it. Instead, the created vm.Script object represents this compiled code. This script can be run later many times using methods below. The returned script is not bound to any global object. It is bound before each run, just for that run.

The options when creating a script are:

  • filename: allows you to control the filename that shows up in any stack traces produced from this script.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to syntax errors compiling the code; errors while running the code are controlled by the options to the script's methods.
  • timeout: a number of milliseconds to execute code before terminating execution. If execution is terminated, an Error will be thrown.

script.runInContext(contextifiedSandbox[, options])#

Similar to vm.runInContext but a method of a precompiled Script object. script.runInContext runs script's compiled code in contextifiedSandbox and returns the result. Running code does not have access to local scope.

script.runInContext takes the same options as script.runInThisContext.

Example: compile code that increments a global variable and sets one, then execute the code multiple times. These globals are contained in the sandbox.

const util = require('util');
const vm = require('vm');

var sandbox = {
  animal: 'cat',
  count: 2
};

var context = new vm.createContext(sandbox);
var script = new vm.Script('count += 1; name = "kitty"');

for (var i = 0; i < 10; ++i) {
  script.runInContext(context);
}

console.log(util.inspect(sandbox));

// { animal: 'cat', count: 12, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. script.runInContext is quite useful, but safely running untrusted code requires a separate process.

script.runInNewContext([sandbox][, options])#

Similar to vm.runInNewContext but a method of a precompiled Script object. script.runInNewContext contextifies sandbox if passed or creates a new contextified sandbox if it's omitted, and then runs script's compiled code with the sandbox as the global object and returns the result. Running code does not have access to local scope.

script.runInNewContext takes the same options as script.runInThisContext.

Example: compile code that sets a global variable, then execute the code multiple times in different contexts. These globals are set on and contained in the sandboxes.

const util = require('util');
const vm = require('vm');

const sandboxes = [{}, {}, {}];

const script = new vm.Script('globalVar = "set"');

sandboxes.forEach((sandbox) => {
  script.runInNewContext(sandbox);
});

console.log(util.inspect(sandboxes));

// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]

Note that running untrusted code is a tricky business requiring great care. script.runInNewContext is quite useful, but safely running untrusted code requires a separate process.

script.runInThisContext([options])#

Similar to vm.runInThisContext but a method of a precompiled Script object. script.runInThisContext runs script's compiled code and returns the result. Running code does not have access to local scope, but does have access to the current global object.

Example of using script.runInThisContext to compile code once and run it multiple times:

const vm = require('vm');

global.globalVar = 0;

const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });

for (var i = 0; i < 1000; ++i) {
  script.runInThisContext();
}

console.log(globalVar);

// 1000

The options for running a script are:

  • filename: allows you to control the filename that shows up in any stack traces produced.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to runtime errors executing the code; it is impossible to create a Script instance with syntax errors, as the constructor will throw.
  • timeout: a number of milliseconds to execute the script before terminating execution. If execution is terminated, an Error will be thrown.

vm.createContext([sandbox])#

If given a sandbox object, will "contextify" that sandbox so that it can be used in calls to vm.runInContext or script.runInContext. Inside scripts run as such, sandbox will be the global object, retaining all its existing properties but also having the built-in objects and functions any standard global object has. Outside of scripts run by the vm module, sandbox will be unchanged.

If not given a sandbox object, returns a new, empty contextified sandbox object you can use.

This function is useful for creating a sandbox that can be used to run multiple scripts, e.g. if you were emulating a web browser it could be used to create a single sandbox representing a window's global object, then run all <script> tags together inside that sandbox.

vm.isContext(sandbox)#

Returns whether or not a sandbox object has been contextified by calling vm.createContext on it.

vm.runInContext(code, contextifiedSandbox[, options])#

vm.runInContext compiles code, then runs it in contextifiedSandbox and returns the result. Running code does not have access to local scope. The contextifiedSandbox object must have been previously contextified via vm.createContext; it will be used as the global object for code.

vm.runInContext takes the same options as vm.runInThisContext.

Example: compile and execute different scripts in a single existing context.

const util = require('util');
const vm = require('vm');

const sandbox = { globalVar: 1 };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));

// { globalVar: 1024 }

Note that running untrusted code is a tricky business requiring great care. vm.runInContext is quite useful, but safely running untrusted code requires a separate process.

vm.runInDebugContext(code)#

vm.runInDebugContext compiles and executes code inside the V8 debug context. The primary use case is to get access to the V8 debug object:

const Debug = vm.runInDebugContext('Debug');
Debug.scripts().forEach(function(script) { console.log(script.name); });

Note that the debug context and object are intrinsically tied to V8's debugger implementation and may change (or even get removed) without prior warning.

The debug object can also be exposed with the --expose_debug_as= switch.

vm.runInNewContext(code[, sandbox][, options])#

vm.runInNewContext compiles code, contextifies sandbox if passed or creates a new contextified sandbox if it's omitted, and then runs the code with the sandbox as the global object and returns the result.

vm.runInNewContext takes the same options as vm.runInThisContext.

Example: compile and execute code that increments a global variable and sets a new one. These globals are contained in the sandbox.

const util = require('util');
const vm = require('vm');

const sandbox = {
  animal: 'cat',
  count: 2
};

vm.runInNewContext('count += 1; name = "kitty"', sandbox);
console.log(util.inspect(sandbox));

// { animal: 'cat', count: 3, name: 'kitty' }

Note that running untrusted code is a tricky business requiring great care. vm.runInNewContext is quite useful, but safely running untrusted code requires a separate process.

vm.runInThisContext(code[, options])#

vm.runInThisContext() compiles code, runs it and returns the result. Running code does not have access to local scope, but does have access to the current global object.

Example of using vm.runInThisContext and eval to run the same code:

const vm = require('vm');
var localVar = 'initial value';

const vmResult = vm.runInThisContext('localVar = "vm";');
console.log('vmResult: ', vmResult);
console.log('localVar: ', localVar);

const evalResult = eval('localVar = "eval";');
console.log('evalResult: ', evalResult);
console.log('localVar: ', localVar);

// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'

vm.runInThisContext does not have access to the local scope, so localVar is unchanged. eval does have access to the local scope, so localVar is changed.

In this way vm.runInThisContext is much like an indirect eval call, e.g. (0,eval)('code'). However, it also has the following additional options:

  • filename: allows you to control the filename that shows up in any stack traces produced.
  • lineOffset: allows you to add an offset to the line number that is displayed in stack traces
  • columnOffset: allows you to add an offset to the column number that is displayed in stack traces
  • displayErrors: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Will capture both syntax errors from compiling code and runtime errors thrown by executing the compiled code. Defaults to true.
  • timeout: a number of milliseconds to execute code before terminating execution. If execution is terminated, an Error will be thrown.
node-v4.2.6/doc/api/vm.json000644 000766 000024 00000041036 12650222331 015601 0ustar00iojsstaff000000 000000 { "source": "doc/api/vm.markdown", "modules": [ { "textRaw": "Executing JavaScript", "name": "vm", "stability": 2, "stabilityText": "Stable", "desc": "

You can access this module with:\n\n

\n
const vm = require('vm');
\n

JavaScript code can be compiled and run immediately or compiled, saved, and run\nlater.\n\n

\n", "classes": [ { "textRaw": "Class: Script", "type": "class", "name": "Script", "desc": "

A class for holding precompiled scripts, and running them in specific sandboxes.\n\n

\n", "methods": [ { "textRaw": "new vm.Script(code, options)", "type": "method", "name": "Script", "desc": "

Creating a new Script compiles code but does not run it. Instead, the\ncreated vm.Script object represents this compiled code. This script can be run\nlater many times using methods below. The returned script is not bound to any\nglobal object. It is bound before each run, just for that run.\n\n

\n

The options when creating a script are:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced from this script.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nApplies only to syntax errors compiling the code; errors while running the\ncode are controlled by the options to the script's methods.
  • \n
  • timeout: a number of milliseconds to execute code before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "options" } ] } ] }, { "textRaw": "script.runInContext(contextifiedSandbox[, options])", "type": "method", "name": "runInContext", "desc": "

Similar to vm.runInContext but a method of a precompiled Script object.\nscript.runInContext runs script's compiled code in contextifiedSandbox\nand returns the result. Running code does not have access to local scope.\n\n

\n

script.runInContext takes the same options as script.runInThisContext.\n\n

\n

Example: compile code that increments a global variable and sets one, then\nexecute the code multiple times. These globals are contained in the sandbox.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nvar sandbox = {\n  animal: 'cat',\n  count: 2\n};\n\nvar context = new vm.createContext(sandbox);\nvar script = new vm.Script('count += 1; name = "kitty"');\n\nfor (var i = 0; i < 10; ++i) {\n  script.runInContext(context);\n}\n\nconsole.log(util.inspect(sandbox));\n\n// { animal: 'cat', count: 12, name: 'kitty' }
\n

Note that running untrusted code is a tricky business requiring great care.\nscript.runInContext is quite useful, but safely running untrusted code\nrequires a separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "contextifiedSandbox" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "script.runInNewContext([sandbox][, options])", "type": "method", "name": "runInNewContext", "desc": "

Similar to vm.runInNewContext but a method of a precompiled Script object.\nscript.runInNewContext contextifies sandbox if passed or creates a new\ncontextified sandbox if it's omitted, and then runs script's compiled code\nwith the sandbox as the global object and returns the result. Running code does\nnot have access to local scope.\n\n

\n

script.runInNewContext takes the same options as script.runInThisContext.\n\n

\n

Example: compile code that sets a global variable, then execute the code\nmultiple times in different contexts. These globals are set on and contained in\nthe sandboxes.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandboxes = [{}, {}, {}];\n\nconst script = new vm.Script('globalVar = "set"');\n\nsandboxes.forEach((sandbox) => {\n  script.runInNewContext(sandbox);\n});\n\nconsole.log(util.inspect(sandboxes));\n\n// [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
\n

Note that running untrusted code is a tricky business requiring great care.\nscript.runInNewContext is quite useful, but safely running untrusted code\nrequires a separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "script.runInThisContext([options])", "type": "method", "name": "runInThisContext", "desc": "

Similar to vm.runInThisContext but a method of a precompiled Script object.\nscript.runInThisContext runs script's compiled code and returns the result.\nRunning code does not have access to local scope, but does have access to the\ncurrent global object.\n\n

\n

Example of using script.runInThisContext to compile code once and run it\nmultiple times:\n\n

\n
const vm = require('vm');\n\nglobal.globalVar = 0;\n\nconst script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });\n\nfor (var i = 0; i < 1000; ++i) {\n  script.runInThisContext();\n}\n\nconsole.log(globalVar);\n\n// 1000
\n

The options for running a script are:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nApplies only to runtime errors executing the code; it is impossible to create\na Script instance with syntax errors, as the constructor will throw.
  • \n
  • timeout: a number of milliseconds to execute the script before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] } ] } ], "methods": [ { "textRaw": "vm.createContext([sandbox])", "type": "method", "name": "createContext", "desc": "

If given a sandbox object, will "contextify" that sandbox so that it can be\nused in calls to vm.runInContext or script.runInContext. Inside scripts run\nas such, sandbox will be the global object, retaining all its existing\nproperties but also having the built-in objects and functions any standard\n[global object][] has. Outside of scripts run by the vm module, sandbox will\nbe unchanged.\n\n

\n

If not given a sandbox object, returns a new, empty contextified sandbox object\nyou can use.\n\n

\n

This function is useful for creating a sandbox that can be used to run multiple\nscripts, e.g. if you were emulating a web browser it could be used to create a\nsingle sandbox representing a window's global object, then run all <script>\ntags together inside that sandbox.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox", "optional": true } ] } ] }, { "textRaw": "vm.isContext(sandbox)", "type": "method", "name": "isContext", "desc": "

Returns whether or not a sandbox object has been contextified by calling\nvm.createContext on it.\n\n

\n", "signatures": [ { "params": [ { "name": "sandbox" } ] } ] }, { "textRaw": "vm.runInContext(code, contextifiedSandbox[, options])", "type": "method", "name": "runInContext", "desc": "

vm.runInContext compiles code, then runs it in contextifiedSandbox and\nreturns the result. Running code does not have access to local scope. The\ncontextifiedSandbox object must have been previously contextified via\nvm.createContext; it will be used as the global object for code.\n\n

\n

vm.runInContext takes the same options as vm.runInThisContext.\n\n

\n

Example: compile and execute different scripts in a single existing context.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandbox = { globalVar: 1 };\nvm.createContext(sandbox);\n\nfor (var i = 0; i < 10; ++i) {\n    vm.runInContext('globalVar *= 2;', sandbox);\n}\nconsole.log(util.inspect(sandbox));\n\n// { globalVar: 1024 }
\n

Note that running untrusted code is a tricky business requiring great care.\nvm.runInContext is quite useful, but safely running untrusted code requires a\nseparate process.\n\n

\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "contextifiedSandbox" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "vm.runInDebugContext(code)", "type": "method", "name": "runInDebugContext", "desc": "

vm.runInDebugContext compiles and executes code inside the V8 debug context.\nThe primary use case is to get access to the V8 debug object:\n\n

\n
const Debug = vm.runInDebugContext('Debug');\nDebug.scripts().forEach(function(script) { console.log(script.name); });
\n

Note that the debug context and object are intrinsically tied to V8's debugger\nimplementation and may change (or even get removed) without prior warning.\n\n

\n

The debug object can also be exposed with the --expose_debug_as= switch.\n\n

\n", "signatures": [ { "params": [ { "name": "code" } ] } ] }, { "textRaw": "vm.runInNewContext(code[, sandbox][, options])", "type": "method", "name": "runInNewContext", "desc": "

vm.runInNewContext compiles code, contextifies sandbox if passed or\ncreates a new contextified sandbox if it's omitted, and then runs the code with\nthe sandbox as the global object and returns the result.\n\n

\n

vm.runInNewContext takes the same options as vm.runInThisContext.\n\n

\n

Example: compile and execute code that increments a global variable and sets a\nnew one. These globals are contained in the sandbox.\n\n

\n
const util = require('util');\nconst vm = require('vm');\n\nconst sandbox = {\n  animal: 'cat',\n  count: 2\n};\n\nvm.runInNewContext('count += 1; name = "kitty"', sandbox);\nconsole.log(util.inspect(sandbox));\n\n// { animal: 'cat', count: 3, name: 'kitty' }
\n

Note that running untrusted code is a tricky business requiring great care.\nvm.runInNewContext is quite useful, but safely running untrusted code requires\na separate process.\n\n

\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "sandbox", "optional": true }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "vm.runInThisContext(code[, options])", "type": "method", "name": "runInThisContext", "desc": "

vm.runInThisContext() compiles code, runs it and returns the result. Running\ncode does not have access to local scope, but does have access to the current\nglobal object.\n\n

\n

Example of using vm.runInThisContext and eval to run the same code:\n\n

\n
const vm = require('vm');\nvar localVar = 'initial value';\n\nconst vmResult = vm.runInThisContext('localVar = "vm";');\nconsole.log('vmResult: ', vmResult);\nconsole.log('localVar: ', localVar);\n\nconst evalResult = eval('localVar = "eval";');\nconsole.log('evalResult: ', evalResult);\nconsole.log('localVar: ', localVar);\n\n// vmResult: 'vm', localVar: 'initial value'\n// evalResult: 'eval', localVar: 'eval'
\n

vm.runInThisContext does not have access to the local scope, so localVar is\nunchanged. eval does have access to the local scope, so localVar is changed.\n\n

\n

In this way vm.runInThisContext is much like an [indirect eval call][],\ne.g. (0,eval)('code'). However, it also has the following additional options:\n\n

\n
    \n
  • filename: allows you to control the filename that shows up in any stack\ntraces produced.
  • \n
  • lineOffset: allows you to add an offset to the line number that is\ndisplayed in stack traces
  • \n
  • columnOffset: allows you to add an offset to the column number that is\ndisplayed in stack traces
  • \n
  • displayErrors: whether or not to print any errors to stderr, with the\nline of code that caused them highlighted, before throwing an exception.\nWill capture both syntax errors from compiling code and runtime errors\nthrown by executing the compiled code. Defaults to true.
  • \n
  • timeout: a number of milliseconds to execute code before terminating\nexecution. If execution is terminated, an [Error][] will be thrown.
  • \n
\n", "signatures": [ { "params": [ { "name": "code" }, { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "vm" } ] } node-v4.2.6/doc/api/vm.markdown000644 000766 000024 00000024335 12650222326 016461 0ustar00iojsstaff000000 000000 # Executing JavaScript Stability: 2 - Stable You can access this module with: const vm = require('vm'); JavaScript code can be compiled and run immediately or compiled, saved, and run later. ## Class: Script A class for holding precompiled scripts, and running them in specific sandboxes. ### new vm.Script(code, options) Creating a new `Script` compiles `code` but does not run it. Instead, the created `vm.Script` object represents this compiled code. This script can be run later many times using methods below. The returned script is not bound to any global object. It is bound before each run, just for that run. The options when creating a script are: - `filename`: allows you to control the filename that shows up in any stack traces produced from this script. - `lineOffset`: allows you to add an offset to the line number that is displayed in stack traces - `columnOffset`: allows you to add an offset to the column number that is displayed in stack traces - `displayErrors`: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to syntax errors compiling the code; errors while running the code are controlled by the options to the script's methods. - `timeout`: a number of milliseconds to execute `code` before terminating execution. If execution is terminated, an [`Error`][] will be thrown. ### script.runInContext(contextifiedSandbox[, options]) Similar to `vm.runInContext` but a method of a precompiled `Script` object. `script.runInContext` runs `script`'s compiled code in `contextifiedSandbox` and returns the result. Running code does not have access to local scope. `script.runInContext` takes the same options as `script.runInThisContext`. Example: compile code that increments a global variable and sets one, then execute the code multiple times. These globals are contained in the sandbox. const util = require('util'); const vm = require('vm'); var sandbox = { animal: 'cat', count: 2 }; var context = new vm.createContext(sandbox); var script = new vm.Script('count += 1; name = "kitty"'); for (var i = 0; i < 10; ++i) { script.runInContext(context); } console.log(util.inspect(sandbox)); // { animal: 'cat', count: 12, name: 'kitty' } Note that running untrusted code is a tricky business requiring great care. `script.runInContext` is quite useful, but safely running untrusted code requires a separate process. ### script.runInNewContext([sandbox][, options]) Similar to `vm.runInNewContext` but a method of a precompiled `Script` object. `script.runInNewContext` contextifies `sandbox` if passed or creates a new contextified sandbox if it's omitted, and then runs `script`'s compiled code with the sandbox as the global object and returns the result. Running code does not have access to local scope. `script.runInNewContext` takes the same options as `script.runInThisContext`. Example: compile code that sets a global variable, then execute the code multiple times in different contexts. These globals are set on and contained in the sandboxes. const util = require('util'); const vm = require('vm'); const sandboxes = [{}, {}, {}]; const script = new vm.Script('globalVar = "set"'); sandboxes.forEach((sandbox) => { script.runInNewContext(sandbox); }); console.log(util.inspect(sandboxes)); // [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] Note that running untrusted code is a tricky business requiring great care. `script.runInNewContext` is quite useful, but safely running untrusted code requires a separate process. ### script.runInThisContext([options]) Similar to `vm.runInThisContext` but a method of a precompiled `Script` object. `script.runInThisContext` runs `script`'s compiled code and returns the result. Running code does not have access to local scope, but does have access to the current `global` object. Example of using `script.runInThisContext` to compile code once and run it multiple times: const vm = require('vm'); global.globalVar = 0; const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); for (var i = 0; i < 1000; ++i) { script.runInThisContext(); } console.log(globalVar); // 1000 The options for running a script are: - `filename`: allows you to control the filename that shows up in any stack traces produced. - `lineOffset`: allows you to add an offset to the line number that is displayed in stack traces - `columnOffset`: allows you to add an offset to the column number that is displayed in stack traces - `displayErrors`: whether or not to print any errors to stderr, with the line of code that caused them highlighted, before throwing an exception. Applies only to runtime errors executing the code; it is impossible to create a `Script` instance with syntax errors, as the constructor will throw. - `timeout`: a number of milliseconds to execute the script before terminating execution. If execution is terminated, an [`Error`][] will be thrown. ## vm.createContext([sandbox]) If given a `sandbox` object, will "contextify" that sandbox so that it can be used in calls to `vm.runInContext` or `script.runInContext`. Inside scripts run as such, `sandbox` will be the global object, retaining all its existing properties but also having the built-in objects and functions any standard [global object][] has. Outside of scripts run by the vm module, `sandbox` will be unchanged. If not given a sandbox object, returns a new, empty contextified sandbox object you can use. This function is useful for creating a sandbox that can be used to run multiple scripts, e.g. if you were emulating a web browser it could be used to create a single sandbox representing a window's global object, then run all ` node-v4.2.6/doc/api/zlib.json000644 000766 000024 00000062663 12650222331 016130 0ustar00iojsstaff000000 000000 { "source": "doc/api/zlib.markdown", "modules": [ { "textRaw": "Zlib", "name": "zlib", "stability": 2, "stabilityText": "Stable", "desc": "

You can access this module with:\n\n

\n
const zlib = require('zlib');
\n

This provides bindings to Gzip/Gunzip, Deflate/Inflate, and\nDeflateRaw/InflateRaw classes. Each class takes the same options, and\nis a readable/writable Stream.\n\n

\n

Examples

\n

Compressing or decompressing a file can be done by piping an\nfs.ReadStream into a zlib stream, then into an fs.WriteStream.\n\n

\n
const gzip = zlib.createGzip();\nconst fs = require('fs');\nconst inp = fs.createReadStream('input.txt');\nconst out = fs.createWriteStream('input.txt.gz');\n\ninp.pipe(gzip).pipe(out);
\n

Compressing or decompressing data in one step can be done by using\nthe convenience methods.\n\n

\n
const input = '.................................';\nzlib.deflate(input, function(err, buffer) {\n  if (!err) {\n    console.log(buffer.toString('base64'));\n  }\n});\n\nconst buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64');\nzlib.unzip(buffer, function(err, buffer) {\n  if (!err) {\n    console.log(buffer.toString());\n  }\n});
\n

To use this module in an HTTP client or server, use the [accept-encoding][]\non requests, and the [content-encoding][] header on responses.\n\n

\n

Note: these examples are drastically simplified to show\nthe basic concept. Zlib encoding can be expensive, and the results\nought to be cached. See [Memory Usage Tuning][] below for more information\non the speed/memory/compression tradeoffs involved in zlib usage.\n\n

\n
// client request example\nconst zlib = require('zlib');\nconst http = require('http');\nconst fs = require('fs');\nconst request = http.get({ host: 'izs.me',\n                         path: '/',\n                         port: 80,\n                         headers: { 'accept-encoding': 'gzip,deflate' } });\nrequest.on('response', (response) => {\n  var output = fs.createWriteStream('izs.me_index.html');\n\n  switch (response.headers['content-encoding']) {\n    // or, just use zlib.createUnzip() to handle both cases\n    case 'gzip':\n      response.pipe(zlib.createGunzip()).pipe(output);\n      break;\n    case 'deflate':\n      response.pipe(zlib.createInflate()).pipe(output);\n      break;\n    default:\n      response.pipe(output);\n      break;\n  }\n});\n\n// server example\n// Running a gzip operation on every request is quite expensive.\n// It would be much more efficient to cache the compressed buffer.\nconst zlib = require('zlib');\nconst http = require('http');\nconst fs = require('fs');\nhttp.createServer((request, response) => {\n  var raw = fs.createReadStream('index.html');\n  var acceptEncoding = request.headers['accept-encoding'];\n  if (!acceptEncoding) {\n    acceptEncoding = '';\n  }\n\n  // Note: this is not a conformant accept-encoding parser.\n  // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3\n  if (acceptEncoding.match(/\\bdeflate\\b/)) {\n    response.writeHead(200, { 'content-encoding': 'deflate' });\n    raw.pipe(zlib.createDeflate()).pipe(response);\n  } else if (acceptEncoding.match(/\\bgzip\\b/)) {\n    response.writeHead(200, { 'content-encoding': 'gzip' });\n    raw.pipe(zlib.createGzip()).pipe(response);\n  } else {\n    response.writeHead(200, {});\n    raw.pipe(response);\n  }\n}).listen(1337);
\n", "miscs": [ { "textRaw": "Memory Usage Tuning", "name": "Memory Usage Tuning", "type": "misc", "desc": "

From zlib/zconf.h, modified to node.js's usage:\n\n

\n

The memory requirements for deflate are (in bytes):\n\n

\n
(1 << (windowBits+2)) +  (1 << (memLevel+9))
\n

that is: 128K for windowBits=15 + 128K for memLevel = 8\n(default values) plus a few kilobytes for small objects.\n\n

\n

For example, if you want to reduce\nthe default memory requirements from 256K to 128K, set the options to:\n\n

\n
{ windowBits: 14, memLevel: 7 }
\n

Of course this will generally degrade compression (there's no free lunch).\n\n

\n

The memory requirements for inflate are (in bytes)\n\n

\n
1 << windowBits
\n

that is, 32K for windowBits=15 (default value) plus a few kilobytes\nfor small objects.\n\n

\n

This is in addition to a single internal output slab buffer of size\nchunkSize, which defaults to 16K.\n\n

\n

The speed of zlib compression is affected most dramatically by the\nlevel setting. A higher level will result in better compression, but\nwill take longer to complete. A lower level will result in less\ncompression, but will be much faster.\n\n

\n

In general, greater memory usage options will mean that node.js has to make\nfewer calls to zlib, since it'll be able to process more data in a\nsingle write operation. So, this is another factor that affects the\nspeed, at the cost of memory usage.\n\n

\n" }, { "textRaw": "Constants", "name": "Constants", "type": "misc", "desc": "

All of the constants defined in zlib.h are also defined on\nrequire('zlib').\nIn the normal course of operations, you will not need to ever set any of\nthese. They are documented here so that their presence is not\nsurprising. This section is taken almost directly from the\n[zlib documentation][]. See http://zlib.net/manual.html#Constants for more\ndetails.\n\n

\n

Allowed flush values.\n\n

\n
    \n
  • zlib.Z_NO_FLUSH
  • \n
  • zlib.Z_PARTIAL_FLUSH
  • \n
  • zlib.Z_SYNC_FLUSH
  • \n
  • zlib.Z_FULL_FLUSH
  • \n
  • zlib.Z_FINISH
  • \n
  • zlib.Z_BLOCK
  • \n
  • zlib.Z_TREES
  • \n
\n

Return codes for the compression/decompression functions. Negative\nvalues are errors, positive values are used for special but normal\nevents.\n\n

\n
    \n
  • zlib.Z_OK
  • \n
  • zlib.Z_STREAM_END
  • \n
  • zlib.Z_NEED_DICT
  • \n
  • zlib.Z_ERRNO
  • \n
  • zlib.Z_STREAM_ERROR
  • \n
  • zlib.Z_DATA_ERROR
  • \n
  • zlib.Z_MEM_ERROR
  • \n
  • zlib.Z_BUF_ERROR
  • \n
  • zlib.Z_VERSION_ERROR
  • \n
\n

Compression levels.\n\n

\n
    \n
  • zlib.Z_NO_COMPRESSION
  • \n
  • zlib.Z_BEST_SPEED
  • \n
  • zlib.Z_BEST_COMPRESSION
  • \n
  • zlib.Z_DEFAULT_COMPRESSION
  • \n
\n

Compression strategy.\n\n

\n
    \n
  • zlib.Z_FILTERED
  • \n
  • zlib.Z_HUFFMAN_ONLY
  • \n
  • zlib.Z_RLE
  • \n
  • zlib.Z_FIXED
  • \n
  • zlib.Z_DEFAULT_STRATEGY
  • \n
\n

Possible values of the data_type field.\n\n

\n
    \n
  • zlib.Z_BINARY
  • \n
  • zlib.Z_TEXT
  • \n
  • zlib.Z_ASCII
  • \n
  • zlib.Z_UNKNOWN
  • \n
\n

The deflate compression method (the only one supported in this version).\n\n

\n
    \n
  • zlib.Z_DEFLATED
  • \n
\n

For initializing zalloc, zfree, opaque.\n\n

\n
    \n
  • zlib.Z_NULL
  • \n
\n" }, { "textRaw": "Class Options", "name": "Class Options", "type": "misc", "desc": "

Each class takes an options object. All options are optional.\n\n

\n

Note that some options are only relevant when compressing, and are\nignored by the decompression classes.\n\n

\n
    \n
  • flush (default: zlib.Z_NO_FLUSH)
  • \n
  • chunkSize (default: 16*1024)
  • \n
  • windowBits
  • \n
  • level (compression only)
  • \n
  • memLevel (compression only)
  • \n
  • strategy (compression only)
  • \n
  • dictionary (deflate/inflate only, empty dictionary by default)
  • \n
\n

See the description of deflateInit2 and inflateInit2 at\n

\n

http://zlib.net/manual.html#Advanced for more information on these.\n\n

\n" }, { "textRaw": "Convenience Methods", "name": "Convenience Methods", "type": "misc", "desc": "

All of these take a string or buffer as the first argument, an optional second\nargument to supply options to the zlib classes and will call the supplied\ncallback with callback(error, result).\n\n

\n

Every method has a *Sync counterpart, which accept the same arguments, but\nwithout a callback.\n\n

\n", "methods": [ { "textRaw": "zlib.deflate(buf[, options], callback)", "type": "method", "name": "deflate", "desc": "

Compress a string with Deflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.deflateRaw(buf[, options], callback)", "type": "method", "name": "deflateRaw", "desc": "

Compress a string with DeflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.deflateRawSync(buf[, options])", "type": "method", "name": "deflateRawSync", "desc": "

Compress a string with DeflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.deflateSync(buf[, options])", "type": "method", "name": "deflateSync", "desc": "

Compress a string with Deflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.gunzip(buf[, options], callback)", "type": "method", "name": "gunzip", "desc": "

Decompress a raw Buffer with Gunzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.gunzipSync(buf[, options])", "type": "method", "name": "gunzipSync", "desc": "

Decompress a raw Buffer with Gunzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.gzip(buf[, options], callback)", "type": "method", "name": "gzip", "desc": "

Compress a string with Gzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.gzipSync(buf[, options])", "type": "method", "name": "gzipSync", "desc": "

Compress a string with Gzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.inflate(buf[, options], callback)", "type": "method", "name": "inflate", "desc": "

Decompress a raw Buffer with Inflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.inflateRaw(buf[, options], callback)", "type": "method", "name": "inflateRaw", "desc": "

Decompress a raw Buffer with InflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.inflateRawSync(buf[, options])", "type": "method", "name": "inflateRawSync", "desc": "

Decompress a raw Buffer with InflateRaw.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.inflateSync(buf[, options])", "type": "method", "name": "inflateSync", "desc": "

Decompress a raw Buffer with Inflate.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.unzip(buf[, options], callback)", "type": "method", "name": "unzip", "desc": "

Decompress a raw Buffer with Unzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] }, { "params": [ { "name": "buf" }, { "name": "options", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.unzipSync(buf[, options])", "type": "method", "name": "unzipSync", "desc": "

Decompress a raw Buffer with Unzip.\n\n

\n", "signatures": [ { "params": [ { "name": "buf" }, { "name": "options", "optional": true } ] } ] } ] } ], "classes": [ { "textRaw": "Class: zlib.Deflate", "type": "class", "name": "zlib.Deflate", "desc": "

Compress data using deflate.\n\n

\n" }, { "textRaw": "Class: zlib.DeflateRaw", "type": "class", "name": "zlib.DeflateRaw", "desc": "

Compress data using deflate, and do not append a zlib header.\n\n

\n" }, { "textRaw": "Class: zlib.Gunzip", "type": "class", "name": "zlib.Gunzip", "desc": "

Decompress a gzip stream.\n\n

\n" }, { "textRaw": "Class: zlib.Gzip", "type": "class", "name": "zlib.Gzip", "desc": "

Compress data using gzip.\n\n

\n" }, { "textRaw": "Class: zlib.Inflate", "type": "class", "name": "zlib.Inflate", "desc": "

Decompress a deflate stream.\n\n

\n" }, { "textRaw": "Class: zlib.InflateRaw", "type": "class", "name": "zlib.InflateRaw", "desc": "

Decompress a raw deflate stream.\n\n

\n" }, { "textRaw": "Class: zlib.Unzip", "type": "class", "name": "zlib.Unzip", "desc": "

Decompress either a Gzip- or Deflate-compressed stream by auto-detecting\nthe header.\n\n

\n" }, { "textRaw": "Class: zlib.Zlib", "type": "class", "name": "zlib.Zlib", "desc": "

Not exported by the zlib module. It is documented here because it is the base\nclass of the compressor/decompressor classes.\n\n

\n", "methods": [ { "textRaw": "zlib.flush([kind], callback)", "type": "method", "name": "flush", "desc": "

kind defaults to zlib.Z_FULL_FLUSH.\n\n

\n

Flush pending data. Don't call this frivolously, premature flushes negatively\nimpact the effectiveness of the compression algorithm.\n\n

\n", "signatures": [ { "params": [ { "name": "kind", "optional": true }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.params(level, strategy, callback)", "type": "method", "name": "params", "desc": "

Dynamically update the compression level and compression strategy.\nOnly applicable to deflate algorithm.\n\n

\n", "signatures": [ { "params": [ { "name": "level" }, { "name": "strategy" }, { "name": "callback" } ] } ] }, { "textRaw": "zlib.reset()", "type": "method", "name": "reset", "desc": "

Reset the compressor/decompressor to factory defaults. Only applicable to\nthe inflate and deflate algorithms.\n\n

\n", "signatures": [ { "params": [] } ] } ] } ], "methods": [ { "textRaw": "zlib.createDeflate([options])", "type": "method", "name": "createDeflate", "desc": "

Returns a new [Deflate][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createDeflateRaw([options])", "type": "method", "name": "createDeflateRaw", "desc": "

Returns a new [DeflateRaw][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createGunzip([options])", "type": "method", "name": "createGunzip", "desc": "

Returns a new [Gunzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createGzip([options])", "type": "method", "name": "createGzip", "desc": "

Returns a new [Gzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createInflate([options])", "type": "method", "name": "createInflate", "desc": "

Returns a new [Inflate][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createInflateRaw([options])", "type": "method", "name": "createInflateRaw", "desc": "

Returns a new [InflateRaw][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] }, { "textRaw": "zlib.createUnzip([options])", "type": "method", "name": "createUnzip", "desc": "

Returns a new [Unzip][] object with an [options][].\n\n

\n", "signatures": [ { "params": [ { "name": "options", "optional": true } ] } ] } ], "type": "module", "displayName": "Zlib" } ] } node-v4.2.6/doc/api/zlib.markdown000644 000766 000024 00000023716 12650222326 017001 0ustar00iojsstaff000000 000000 # Zlib Stability: 2 - Stable You can access this module with: const zlib = require('zlib'); This provides bindings to Gzip/Gunzip, Deflate/Inflate, and DeflateRaw/InflateRaw classes. Each class takes the same options, and is a readable/writable Stream. ## Examples Compressing or decompressing a file can be done by piping an fs.ReadStream into a zlib stream, then into an fs.WriteStream. const gzip = zlib.createGzip(); const fs = require('fs'); const inp = fs.createReadStream('input.txt'); const out = fs.createWriteStream('input.txt.gz'); inp.pipe(gzip).pipe(out); Compressing or decompressing data in one step can be done by using the convenience methods. const input = '.................................'; zlib.deflate(input, function(err, buffer) { if (!err) { console.log(buffer.toString('base64')); } }); const buffer = new Buffer('eJzT0yMAAGTvBe8=', 'base64'); zlib.unzip(buffer, function(err, buffer) { if (!err) { console.log(buffer.toString()); } }); To use this module in an HTTP client or server, use the [accept-encoding][] on requests, and the [content-encoding][] header on responses. **Note: these examples are drastically simplified to show the basic concept.** Zlib encoding can be expensive, and the results ought to be cached. See [Memory Usage Tuning][] below for more information on the speed/memory/compression tradeoffs involved in zlib usage. // client request example const zlib = require('zlib'); const http = require('http'); const fs = require('fs'); const request = http.get({ host: 'izs.me', path: '/', port: 80, headers: { 'accept-encoding': 'gzip,deflate' } }); request.on('response', (response) => { var output = fs.createWriteStream('izs.me_index.html'); switch (response.headers['content-encoding']) { // or, just use zlib.createUnzip() to handle both cases case 'gzip': response.pipe(zlib.createGunzip()).pipe(output); break; case 'deflate': response.pipe(zlib.createInflate()).pipe(output); break; default: response.pipe(output); break; } }); // server example // Running a gzip operation on every request is quite expensive. // It would be much more efficient to cache the compressed buffer. const zlib = require('zlib'); const http = require('http'); const fs = require('fs'); http.createServer((request, response) => { var raw = fs.createReadStream('index.html'); var acceptEncoding = request.headers['accept-encoding']; if (!acceptEncoding) { acceptEncoding = ''; } // Note: this is not a conformant accept-encoding parser. // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 if (acceptEncoding.match(/\bdeflate\b/)) { response.writeHead(200, { 'content-encoding': 'deflate' }); raw.pipe(zlib.createDeflate()).pipe(response); } else if (acceptEncoding.match(/\bgzip\b/)) { response.writeHead(200, { 'content-encoding': 'gzip' }); raw.pipe(zlib.createGzip()).pipe(response); } else { response.writeHead(200, {}); raw.pipe(response); } }).listen(1337); ## Memory Usage Tuning From `zlib/zconf.h`, modified to node.js's usage: The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, set the options to: { windowBits: 14, memLevel: 7 } Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. This is in addition to a single internal output slab buffer of size `chunkSize`, which defaults to 16K. The speed of zlib compression is affected most dramatically by the `level` setting. A higher level will result in better compression, but will take longer to complete. A lower level will result in less compression, but will be much faster. In general, greater memory usage options will mean that node.js has to make fewer calls to zlib, since it'll be able to process more data in a single `write` operation. So, this is another factor that affects the speed, at the cost of memory usage. ## Constants All of the constants defined in zlib.h are also defined on `require('zlib')`. In the normal course of operations, you will not need to ever set any of these. They are documented here so that their presence is not surprising. This section is taken almost directly from the [zlib documentation][]. See for more details. Allowed flush values. * `zlib.Z_NO_FLUSH` * `zlib.Z_PARTIAL_FLUSH` * `zlib.Z_SYNC_FLUSH` * `zlib.Z_FULL_FLUSH` * `zlib.Z_FINISH` * `zlib.Z_BLOCK` * `zlib.Z_TREES` Return codes for the compression/decompression functions. Negative values are errors, positive values are used for special but normal events. * `zlib.Z_OK` * `zlib.Z_STREAM_END` * `zlib.Z_NEED_DICT` * `zlib.Z_ERRNO` * `zlib.Z_STREAM_ERROR` * `zlib.Z_DATA_ERROR` * `zlib.Z_MEM_ERROR` * `zlib.Z_BUF_ERROR` * `zlib.Z_VERSION_ERROR` Compression levels. * `zlib.Z_NO_COMPRESSION` * `zlib.Z_BEST_SPEED` * `zlib.Z_BEST_COMPRESSION` * `zlib.Z_DEFAULT_COMPRESSION` Compression strategy. * `zlib.Z_FILTERED` * `zlib.Z_HUFFMAN_ONLY` * `zlib.Z_RLE` * `zlib.Z_FIXED` * `zlib.Z_DEFAULT_STRATEGY` Possible values of the data_type field. * `zlib.Z_BINARY` * `zlib.Z_TEXT` * `zlib.Z_ASCII` * `zlib.Z_UNKNOWN` The deflate compression method (the only one supported in this version). * `zlib.Z_DEFLATED` For initializing zalloc, zfree, opaque. * `zlib.Z_NULL` ## Class Options Each class takes an options object. All options are optional. Note that some options are only relevant when compressing, and are ignored by the decompression classes. * flush (default: `zlib.Z_NO_FLUSH`) * chunkSize (default: 16*1024) * windowBits * level (compression only) * memLevel (compression only) * strategy (compression only) * dictionary (deflate/inflate only, empty dictionary by default) See the description of `deflateInit2` and `inflateInit2` at for more information on these. ## Class: zlib.Deflate Compress data using deflate. ## Class: zlib.DeflateRaw Compress data using deflate, and do not append a zlib header. ## Class: zlib.Gunzip Decompress a gzip stream. ## Class: zlib.Gzip Compress data using gzip. ## Class: zlib.Inflate Decompress a deflate stream. ## Class: zlib.InflateRaw Decompress a raw deflate stream. ## Class: zlib.Unzip Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header. ## Class: zlib.Zlib Not exported by the `zlib` module. It is documented here because it is the base class of the compressor/decompressor classes. ### zlib.flush([kind], callback) `kind` defaults to `zlib.Z_FULL_FLUSH`. Flush pending data. Don't call this frivolously, premature flushes negatively impact the effectiveness of the compression algorithm. ### zlib.params(level, strategy, callback) Dynamically update the compression level and compression strategy. Only applicable to deflate algorithm. ### zlib.reset() Reset the compressor/decompressor to factory defaults. Only applicable to the inflate and deflate algorithms. ## zlib.createDeflate([options]) Returns a new [Deflate][] object with an [options][]. ## zlib.createDeflateRaw([options]) Returns a new [DeflateRaw][] object with an [options][]. ## zlib.createGunzip([options]) Returns a new [Gunzip][] object with an [options][]. ## zlib.createGzip([options]) Returns a new [Gzip][] object with an [options][]. ## zlib.createInflate([options]) Returns a new [Inflate][] object with an [options][]. ## zlib.createInflateRaw([options]) Returns a new [InflateRaw][] object with an [options][]. ## zlib.createUnzip([options]) Returns a new [Unzip][] object with an [options][]. ## Convenience Methods All of these take a string or buffer as the first argument, an optional second argument to supply options to the zlib classes and will call the supplied callback with `callback(error, result)`. Every method has a `*Sync` counterpart, which accept the same arguments, but without a callback. ### zlib.deflate(buf[, options], callback) Compress a string with Deflate. ### zlib.deflateRaw(buf[, options], callback) ### zlib.deflateRawSync(buf[, options]) Compress a string with DeflateRaw. ### zlib.deflateSync(buf[, options]) Compress a string with Deflate. ### zlib.gunzip(buf[, options], callback) ### zlib.gunzipSync(buf[, options]) Decompress a raw Buffer with Gunzip. ### zlib.gzip(buf[, options], callback) ### zlib.gzipSync(buf[, options]) Compress a string with Gzip. ### zlib.inflate(buf[, options], callback) Decompress a raw Buffer with Inflate. ### zlib.inflateRaw(buf[, options], callback) ### zlib.inflateRawSync(buf[, options]) Decompress a raw Buffer with InflateRaw. ### zlib.inflateSync(buf[, options]) Decompress a raw Buffer with Inflate. ### zlib.unzip(buf[, options], callback) ### zlib.unzipSync(buf[, options]) Decompress a raw Buffer with Unzip. [accept-encoding]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 [content-encoding]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11 [Memory Usage Tuning]: #zlib_memory_usage_tuning [zlib documentation]: http://zlib.net/manual.html#Constants [options]: #zlib_class_options [Deflate]: #zlib_class_zlib_deflate [DeflateRaw]: #zlib_class_zlib_deflateraw [Gunzip]: #zlib_class_zlib_gunzip [Gzip]: #zlib_class_zlib_gzip [Inflate]: #zlib_class_zlib_inflate [InflateRaw]: #zlib_class_zlib_inflateraw [Unzip]: #zlib_class_zlib_unzip node-v4.2.6/doc/api/assets/sh.css000644 000766 000024 00000000610 12650222331 016703 0ustar00iojsstaff000000 000000 .sh_sourceCode { font-weight: normal; font-style: normal; } .sh_sourceCode .sh_symbol, .sh_sourceCode .sh_cbracket { color: #333; } .sh_sourceCode .sh_keyword { color: #338; } .sh_sourceCode .sh_string, .sh_sourceCode .sh_regexp, .sh_sourceCode .sh_number, .sh_sourceCode .sh_specialchar { color: #E54305; } .sh_sourceCode .sh_comment { color: #666; font-weight: lighter; } node-v4.2.6/doc/api/assets/sh_main.js000644 000766 000024 00000035702 12650222331 017545 0ustar00iojsstaff000000 000000 /* SHJS - Syntax Highlighting in JavaScript Copyright (C) 2007, 2008 gnombat@users.sourceforge.net License: http://shjs.sourceforge.net/doc/gplv3.html */ if (! this.sh_languages) { this.sh_languages = {}; } var sh_requests = {}; function sh_isEmailAddress(url) { if (/^mailto:/.test(url)) { return false; } return url.indexOf('@') !== -1; } function sh_setHref(tags, numTags, inputString) { var url = inputString.substring(tags[numTags - 2].pos, tags[numTags - 1].pos); if (url.length >= 2 && url.charAt(0) === '<' && url.charAt(url.length - 1) === '>') { url = url.substr(1, url.length - 2); } if (sh_isEmailAddress(url)) { url = 'mailto:' + url; } tags[numTags - 2].node.href = url; } /* Konqueror has a bug where the regular expression /$/g will not match at the end of a line more than once: var regex = /$/g; var match; var line = '1234567890'; regex.lastIndex = 10; match = regex.exec(line); var line2 = 'abcde'; regex.lastIndex = 5; match = regex.exec(line2); // fails */ function sh_konquerorExec(s) { var result = ['']; result.index = s.length; result.input = s; return result; } /** Highlights all elements containing source code in a text string. The return value is an array of objects, each representing an HTML start or end tag. Each object has a property named pos, which is an integer representing the text offset of the tag. Every start tag also has a property named node, which is the DOM element started by the tag. End tags do not have this property. @param inputString a text string @param language a language definition object @return an array of tag objects */ function sh_highlightString(inputString, language) { if (/Konqueror/.test(navigator.userAgent)) { if (! language.konquered) { for (var s = 0; s < language.length; s++) { for (var p = 0; p < language[s].length; p++) { var r = language[s][p][0]; if (r.source === '$') { r.exec = sh_konquerorExec; } } } language.konquered = true; } } var a = document.createElement('a'); var span = document.createElement('span'); // the result var tags = []; var numTags = 0; // each element is a pattern object from language var patternStack = []; // the current position within inputString var pos = 0; // the name of the current style, or null if there is no current style var currentStyle = null; var output = function(s, style) { var length = s.length; // this is more than just an optimization - we don't want to output empty elements if (length === 0) { return; } if (! style) { var stackLength = patternStack.length; if (stackLength !== 0) { var pattern = patternStack[stackLength - 1]; // check whether this is a state or an environment if (! pattern[3]) { // it's not a state - it's an environment; use the style for this environment style = pattern[1]; } } } if (currentStyle !== style) { if (currentStyle) { tags[numTags++] = {pos: pos}; if (currentStyle === 'sh_url') { sh_setHref(tags, numTags, inputString); } } if (style) { var clone; if (style === 'sh_url') { clone = a.cloneNode(false); } else { clone = span.cloneNode(false); } clone.className = style; tags[numTags++] = {node: clone, pos: pos}; } } pos += length; currentStyle = style; }; var endOfLinePattern = /\r\n|\r|\n/g; endOfLinePattern.lastIndex = 0; var inputStringLength = inputString.length; while (pos < inputStringLength) { var start = pos; var end; var startOfNextLine; var endOfLineMatch = endOfLinePattern.exec(inputString); if (endOfLineMatch === null) { end = inputStringLength; startOfNextLine = inputStringLength; } else { end = endOfLineMatch.index; startOfNextLine = endOfLinePattern.lastIndex; } var line = inputString.substring(start, end); var matchCache = []; for (;;) { var posWithinLine = pos - start; var stateIndex; var stackLength = patternStack.length; if (stackLength === 0) { stateIndex = 0; } else { // get the next state stateIndex = patternStack[stackLength - 1][2]; } var state = language[stateIndex]; var numPatterns = state.length; var mc = matchCache[stateIndex]; if (! mc) { mc = matchCache[stateIndex] = []; } var bestMatch = null; var bestPatternIndex = -1; for (var i = 0; i < numPatterns; i++) { var match; if (i < mc.length && (mc[i] === null || posWithinLine <= mc[i].index)) { match = mc[i]; } else { var regex = state[i][0]; regex.lastIndex = posWithinLine; match = regex.exec(line); mc[i] = match; } if (match !== null && (bestMatch === null || match.index < bestMatch.index)) { bestMatch = match; bestPatternIndex = i; if (match.index === posWithinLine) { break; } } } if (bestMatch === null) { output(line.substring(posWithinLine), null); break; } else { // got a match if (bestMatch.index > posWithinLine) { output(line.substring(posWithinLine, bestMatch.index), null); } var pattern = state[bestPatternIndex]; var newStyle = pattern[1]; var matchedString; if (newStyle instanceof Array) { for (var subexpression = 0; subexpression < newStyle.length; subexpression++) { matchedString = bestMatch[subexpression + 1]; output(matchedString, newStyle[subexpression]); } } else { matchedString = bestMatch[0]; output(matchedString, newStyle); } switch (pattern[2]) { case -1: // do nothing break; case -2: // exit patternStack.pop(); break; case -3: // exitall patternStack.length = 0; break; default: // this was the start of a delimited pattern or a state/environment patternStack.push(pattern); break; } } } // end of the line if (currentStyle) { tags[numTags++] = {pos: pos}; if (currentStyle === 'sh_url') { sh_setHref(tags, numTags, inputString); } currentStyle = null; } pos = startOfNextLine; } return tags; } //////////////////////////////////////////////////////////////////////////////// // DOM-dependent functions function sh_getClasses(element) { var result = []; var htmlClass = element.className; if (htmlClass && htmlClass.length > 0) { var htmlClasses = htmlClass.split(' '); for (var i = 0; i < htmlClasses.length; i++) { if (htmlClasses[i].length > 0) { result.push(htmlClasses[i]); } } } return result; } function sh_addClass(element, name) { var htmlClasses = sh_getClasses(element); for (var i = 0; i < htmlClasses.length; i++) { if (name.toLowerCase() === htmlClasses[i].toLowerCase()) { return; } } htmlClasses.push(name); element.className = htmlClasses.join(' '); } /** Extracts the tags from an HTML DOM NodeList. @param nodeList a DOM NodeList @param result an object with text, tags and pos properties */ function sh_extractTagsFromNodeList(nodeList, result) { var length = nodeList.length; for (var i = 0; i < length; i++) { var node = nodeList.item(i); switch (node.nodeType) { case 1: if (node.nodeName.toLowerCase() === 'br') { var terminator; if (/MSIE/.test(navigator.userAgent)) { terminator = '\r'; } else { terminator = '\n'; } result.text.push(terminator); result.pos++; } else { result.tags.push({node: node.cloneNode(false), pos: result.pos}); sh_extractTagsFromNodeList(node.childNodes, result); result.tags.push({pos: result.pos}); } break; case 3: case 4: result.text.push(node.data); result.pos += node.length; break; } } } /** Extracts the tags from the text of an HTML element. The extracted tags will be returned as an array of tag objects. See sh_highlightString for the format of the tag objects. @param element a DOM element @param tags an empty array; the extracted tag objects will be returned in it @return the text of the element @see sh_highlightString */ function sh_extractTags(element, tags) { var result = {}; result.text = []; result.tags = tags; result.pos = 0; sh_extractTagsFromNodeList(element.childNodes, result); return result.text.join(''); } /** Merges the original tags from an element with the tags produced by highlighting. @param originalTags an array containing the original tags @param highlightTags an array containing the highlighting tags - these must not overlap @result an array containing the merged tags */ function sh_mergeTags(originalTags, highlightTags) { var numOriginalTags = originalTags.length; if (numOriginalTags === 0) { return highlightTags; } var numHighlightTags = highlightTags.length; if (numHighlightTags === 0) { return originalTags; } var result = []; var originalIndex = 0; var highlightIndex = 0; while (originalIndex < numOriginalTags && highlightIndex < numHighlightTags) { var originalTag = originalTags[originalIndex]; var highlightTag = highlightTags[highlightIndex]; if (originalTag.pos <= highlightTag.pos) { result.push(originalTag); originalIndex++; } else { result.push(highlightTag); if (highlightTags[highlightIndex + 1].pos <= originalTag.pos) { highlightIndex++; result.push(highlightTags[highlightIndex]); highlightIndex++; } else { // new end tag result.push({pos: originalTag.pos}); // new start tag highlightTags[highlightIndex] = {node: highlightTag.node.cloneNode(false), pos: originalTag.pos}; } } } while (originalIndex < numOriginalTags) { result.push(originalTags[originalIndex]); originalIndex++; } while (highlightIndex < numHighlightTags) { result.push(highlightTags[highlightIndex]); highlightIndex++; } return result; } /** Inserts tags into text. @param tags an array of tag objects @param text a string representing the text @return a DOM DocumentFragment representing the resulting HTML */ function sh_insertTags(tags, text) { var doc = document; var result = document.createDocumentFragment(); var tagIndex = 0; var numTags = tags.length; var textPos = 0; var textLength = text.length; var currentNode = result; // output one tag or text node every iteration while (textPos < textLength || tagIndex < numTags) { var tag; var tagPos; if (tagIndex < numTags) { tag = tags[tagIndex]; tagPos = tag.pos; } else { tagPos = textLength; } if (tagPos <= textPos) { // output the tag if (tag.node) { // start tag var newNode = tag.node; currentNode.appendChild(newNode); currentNode = newNode; } else { // end tag currentNode = currentNode.parentNode; } tagIndex++; } else { // output text currentNode.appendChild(doc.createTextNode(text.substring(textPos, tagPos))); textPos = tagPos; } } return result; } /** Highlights an element containing source code. Upon completion of this function, the element will have been placed in the "sh_sourceCode" class. @param element a DOM
 element containing the source code to be highlighted
@param  language  a language definition object
*/
function sh_highlightElement(element, language) {
  sh_addClass(element, 'sh_sourceCode');
  var originalTags = [];
  var inputString = sh_extractTags(element, originalTags);
  var highlightTags = sh_highlightString(inputString, language);
  var tags = sh_mergeTags(originalTags, highlightTags);
  var documentFragment = sh_insertTags(tags, inputString);
  while (element.hasChildNodes()) {
    element.removeChild(element.firstChild);
  }
  element.appendChild(documentFragment);
}

function sh_getXMLHttpRequest() {
  if (window.ActiveXObject) {
    return new ActiveXObject('Msxml2.XMLHTTP');
  }
  else if (window.XMLHttpRequest) {
    return new XMLHttpRequest();
  }
  throw 'No XMLHttpRequest implementation available';
}

function sh_load(language, element, prefix, suffix) {
  if (language in sh_requests) {
    sh_requests[language].push(element);
    return;
  }
  sh_requests[language] = [element];
  var request = sh_getXMLHttpRequest();
  var url = prefix + 'sh_' + language + suffix;
  request.open('GET', url, true);
  request.onreadystatechange = function () {
    if (request.readyState === 4) {
      try {
        if (! request.status || request.status === 200) {
          eval(request.responseText);
          var elements = sh_requests[language];
          for (var i = 0; i < elements.length; i++) {
            sh_highlightElement(elements[i], sh_languages[language]);
          }
        }
        else {
          throw 'HTTP error: status ' + request.status;
        }
      }
      finally {
        request = null;
      }
    }
  };
  request.send(null);
}

/**
Highlights all elements containing source code on the current page. Elements
containing source code must be "pre" elements with a "class" attribute of
"sh_LANGUAGE", where LANGUAGE is a valid language identifier; e.g., "sh_java"
identifies the element as containing "java" language source code.
*/
function highlight(prefix, suffix, tag) {
  var nodeList = document.getElementsByTagName(tag);
  for (var i = 0; i < nodeList.length; i++) {
    var element = nodeList.item(i);
    var htmlClasses = sh_getClasses(element);
    var highlighted = false;
    var donthighlight = false;
    for (var j = 0; j < htmlClasses.length; j++) {
      var htmlClass = htmlClasses[j].toLowerCase();
      if (htmlClass === 'sh_none') {
        donthighlight = true
        continue;
      }
      if (htmlClass.substr(0, 3) === 'sh_') {
        var language = htmlClass.substring(3);
        if (language in sh_languages) {
          sh_highlightElement(element, sh_languages[language]);
          highlighted = true;
        }
        else if (typeof(prefix) === 'string' && typeof(suffix) === 'string') {
          sh_load(language, element, prefix, suffix);
        }
        else {
          throw 'Found <' + tag + '> element with class="' + htmlClass + '", but no such language exists';
        }
        break;
      }
    }
    if (highlighted === false && donthighlight == false) {
      sh_highlightElement(element, sh_languages["javascript"]);
    }
  }
}



function sh_highlightDocument(prefix, suffix) {
  highlight(prefix, suffix, 'tt');
  highlight(prefix, suffix, 'code');
  highlight(prefix, suffix, 'pre');
}
node-v4.2.6/doc/api/assets/style.css000644 000766 000024 00000015306 12650222331 017441 0ustar00iojsstaff000000 000000 /*--------------------- Layout and Typography ----------------------------*/
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-variant-ligatures: none;
          font-variant-ligatures: none;
}

body {
  font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
  font-size: 62.5%;
  margin: 0;
  padding: 0;
  color: #333;
  background: #fff;
}

#content {
  font-size: 1.8em;
}

a,
a:link,
a:active {
  color: #80bd01;
  text-decoration: none;
  border-radius: 2px;
  padding: .1em .2em;
  margin: -.1em 0;
}

a:hover,
a:focus {
  color: #fff;
  background-color: #80bd01;
}

strong {
  font-weight: 700;
}

code a:hover {
  background: none;
}

#changelog #gtoc {
  display: none;
}

#gtoc {
  font-size: 0.8em;
}

#gtoc p {
}

#gtoc a {
}

#gtoc a:hover {
}

.api_stability_0,
.api_stability_1,
.api_stability_2,
.api_stability_3,
.api_stability_4,
.api_stability_5 {
  color: white !important;
  margin: 0em 0 1.0em 0;
  font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;
  font-weight: 700;
}

.api_stability_0 *,
.api_stability_1 *,
.api_stability_2 *,
.api_stability_3 *,
.api_stability_4 *,
.api_stability_5 * {
  color: white !important;
}

.api_stability_0 a,
.api_stability_1 a,
.api_stability_2 a,
.api_stability_3 a,
.api_stability_4 a,
.api_stability_5 a {
  text-decoration: underline;
}

.api_stability_0 {
  background-color: #D60027;
}

.api_stability_1 {
  background-color: #EC5315;
}

.api_stability_2 {
  background-color: #4EBA0F;
}

.api_stability_3 {
  background-color: #0084B6;
}

ul.plain {
  list-style: none;
}

abbr {
  border-bottom: 1px dotted #454545;
}

p {
  position: relative;
  text-rendering: optimizeLegibility;
  margin: 0 0 1em 0;
  line-height: 1.5em;
}

#apicontent > *:last-child {
  margin-bottom: 0;
  padding-bottom: 2.0em;
}

table {
  border-collapse: collapse;
  margin: 0 0 1.5em 0;
}

th, td {
  border: 1px solid #aaa;
}

table p {
}

th {
  text-align:left;
}

ol, ul, dl {
  margin: 0 0 0.6em 0;
  padding: 0;
}

ol ul, ol ol, ol dl,
ul ul, ul ol, ul dl,
dl ul, dl ol, dl dl {
  margin-bottom: 0;
}

ul, ol {
  margin-left: 2em;
}

dl dt {
  position: relative;
  margin: 1.5em 0 0;
}

dl dd {
  position: relative;
  margin: 0 1em 0;
}

dd + dt.pre {
  margin-top: 1.6em;
}

h1, h2, h3, h4, h5, h6 {
  text-rendering: optimizeLegibility;
  font-weight: 700;
  position: relative;
  margin-bottom: 0.5em;
}

header h1 {
  line-height: 2.0em;
  margin: 0;
}

#apicontent {
  padding-top: 1.0em;
}

#toc + h1 {
  margin-top: 1em;
  padding-top: 0;
}

h2 {
  font-size: 1.5em;
  margin: 1.0em 0 0.5em;
}

h2 + h2 {
  margin: 0 0 0.5em;
}

h3 {
  font-size: 1.0em;
  margin: 1.5em 0 0.5em;
}

h3 + h3 {
  margin: 0 0 0.5em;
}

h2, h3, h4 {
  position: relative;
  padding-right: 40px;
}

h1 span, h2 span, h3 span, h4 span {
  position: absolute;
  display: block;
  top: 0;
  right: 0;
}

h1 span:hover, h2 span:hover, h3 span:hover, h4 span:hover {
  opacity: 1;
}

h1 span a, h2 span a, h3 span a, h4 span a {
  font-size: 0.8em;
  color: #000;
  text-decoration: none;
  font-weight: bold;
}

h5 {
  font-size: 1.125em;
  line-height: 1.4em;
}

h6 {
  font-size: 1em;
  line-height: 1.4667em;
}

pre, tt, code {
  line-height: 1.5em;
  font-family: Monaco, Consolas, "Lucida Console", monospace;
  margin: 0; padding: 0;
}

.pre {
  font-family: Monaco, Consolas, "Lucida Console", monospace;
  line-height: 1.5em;
  font-size: 1.2em;
}

pre {
  padding: 1.0em 1.5em;
  vertical-align: top;
  background: #f2f5f0;
  margin: 0.166666em -4.0em 1.0em 0em;
  overflow-x: auto;
}

pre > code {
  font-size: 0.8em;
}

pre + h3 {
  margin-top: 2.225em;
}

code.pre {
  white-space: pre;
}

#intro {
  margin-top: 1.25em;
  margin-left: 1.0em;
}

#intro a {
  color: #ddd;
  font-size: 1.25em;
  font-weight: bold;
}

hr {
  background: none;
  border: medium none;
  border-bottom: 1px solid #7a7a7a;
  margin: 0em 0em 1em 0;
}

#toc {
}

#toc h2 {
  margin-top: 0;
  font-size: 1.0em;
  line-height: 0;
  margin: 1.5em 0;
}

#toc ul {
  font-size: 0.8125em;
}

#toc ul ul { font-size: 1.0em; }

#toc ul a {
  text-decoration:none;
}

#toc ul li {
  margin-bottom: 0.6666em;
  list-style: square outside;
}

#toc li > ul {
  margin-top: 0.6666em;
}

#toc ul a:hover,
#toc ul a:focus {
}

#apicontent li {
  margin-bottom: 0.5em;
}

#apicontent li:last-child {
  margin-bottom: 0;
}

p tt,
p code,
li code {
  font-size: 0.9em;
  color: #040404;
  background-color: #f0f0f0;
  padding: .1em .2em;
  border-radius: 2px;
}

a code {
  color: inherit;
  background: inherit;
}

span.type {
  color: #222;
}

#content {
  margin: 0 auto;
  overflow: visible;
  clear: both;
  display: block;
}

#column1.interior {
  width: 702px;
  margin-left: 234px;
  padding-left: 2.0em;
}

#column2.interior {
  width: 234px;
  background: #333;
  position: fixed;
  height: 100%;
  overflow-y: scroll;
}

#column2.interior:after {
  content: '';
  position: fixed;
  bottom: 0;
  left: 0;
  width: 234px;
  height: 4em;
  background: linear-gradient(rgba(242,245,240, 0), rgba(51, 51, 51, 1));
  pointer-events: none;
}

#column2 ul {
  list-style: none;
  margin-left: 0em;
  margin-top: 1.25em;
  background: #333;
  margin-bottom: 0;
  padding-bottom: 3em;
}

#column2 ul li {
  padding-left: 1.4em;
  margin-bottom: 0.5em;
  padding-bottom: 0.5em;
  font-size: 0.8em;
}

#column2 ul li:last-child {
  margin-bottom: 0;
}

#column2 ul li a {
  color: #ccc;
  border-radius: 0;
}

#column2 ul li a.active,
#column2 ul li a.active:hover,
#column2 ul li a.active:focus {
  color: #80bd01;
  border-radius: 0;
  border-bottom: 1px solid #80bd01;
  background: none;
}

#intro a:hover,
#column2 ul li a:hover,
#column2 ul li a:focus {
  color: #fff;
  background: none;
}

span > .mark,
span > .mark:visited {
  font-size: 18px;
  color: #707070;
  position: absolute;
  top: 0px;
  right: 0px;
}

span > .mark:hover {
  color: #FE7110;
}

th, td {
  padding: 0.75em 1.0em 0.75em 1.0em;
  vertical-align: top;
}

th > *:last-child,
td > *:last-child {
  margin-bottom: 0;
}

/* simpler clearfix */
.clearfix:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

@media only screen and (max-width: 1024px) {
  #content {
    font-size: 2.1em;
  }
  #column1.interior {
    margin-left: 0;
    padding-left: 0.5em;
    padding-right: 0.5em;
    width: auto;
  }
  pre {
    margin-right: 0;
  }
  #column2 {
    display: none;
  }
}

@media only screen and (max-width: 1024px) and (orientation: portrait) {
  #content {
    font-size: 2.4em;
  }
  #column1.interior {
    margin-left: 0;
    padding-left: 0.5em;
    padding-right: 0.5em;
    width: auto;
  }
  pre {
    margin-right: 0;
  }
  #column2 {
    display: none;
  }
}
node-v4.2.6/deps/cares/000755 000766 000024 00000000000 12650222322 014772 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/gtest/000755 000766 000024 00000000000 12650222322 015023 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/http_parser/000755 000766 000024 00000000000 12650222322 016230 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/000755 000766 000024 00000000000 12650222331 014232 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/.clang-format000644 000766 000024 00000000241 12650222324 016604 0ustar00iojsstaff000000 000000 # Defines the Google C++ style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Google
MaxEmptyLinesToKeep: 2
node-v4.2.6/deps/v8/.gitignore000644 000766 000024 00000002525 12650222324 016230 0ustar00iojsstaff000000 000000 *.a
*.exe
*.idb
*.lib
*.log
*.map
*.mk
*.ncb
*.pdb
*.pyc
*.scons*
*.sdf
*.sln
*.so
*.suo
*.user
*.vcproj
*.vcxproj
*.vcxproj.filters
*.xcodeproj
#*#
*~
.cpplint-cache
.cproject
.d8_history
.gclient_entries
.landmines
.project
.pydevproject
.settings
.*.sw?
bsuite
compile_commands.json
d8
d8_g
gccauses
gcsuspects
shell
shell_g
/_*
/build/Debug
/build/gyp
/build/ipch/
/build/Release
/buildtools
/hydrogen.cfg
/obj
/out
/perf.data
/perf.data.old
/test/benchmarks/CHECKED_OUT_*
/test/benchmarks/downloaded_*
/test/benchmarks/kraken
/test/benchmarks/octane
/test/benchmarks/sunspider
/test/mozilla/CHECKED_OUT_VERSION
/test/mozilla/data
/test/mozilla/data.old
/test/mozilla/downloaded_*
/test/promises-aplus/promises-tests
/test/promises-aplus/promises-tests.tar.gz
/test/promises-aplus/sinon
/test/simdjs/ecmascript_simd*
/test/simdjs/data*
/test/test262/data
/test/test262/data.old
/test/test262/tc39-test262-*
/test/test262-es6/data
/test/test262-es6/data.old
/test/test262-es6/tc39-test262-*
/testing/gmock
/testing/gtest
/third_party
/third_party/icu
/third_party/llvm
/third_party/llvm-build
/tools/clang
/tools/jsfunfuzz
/tools/jsfunfuzz.zip
/tools/oom_dump/oom_dump
/tools/oom_dump/oom_dump.o
/tools/visual_studio/Debug
/tools/visual_studio/Release
/v8.log.ll
/xcodebuild
TAGS
*.Makefile
GTAGS
GRTAGS
GSYMS
GPATH
gtags.files
turbo*.cfg
turbo*.dot
turbo*.json
node-v4.2.6/deps/v8/.ycm_extra_conf.py000644 000766 000024 00000013353 12650222324 017671 0ustar00iojsstaff000000 000000 # Copyright 2015 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Autocompletion config for YouCompleteMe in V8.
#
# USAGE:
#
#   1. Install YCM [https://github.com/Valloric/YouCompleteMe]
#          (Googlers should check out [go/ycm])
#
#   2. Profit
#
#
# Usage notes:
#
#   * You must use ninja & clang to build V8.
#
#   * You must have run gyp_v8 and built V8 recently.
#
#
# Hacking notes:
#
#   * The purpose of this script is to construct an accurate enough command line
#     for YCM to pass to clang so it can build and extract the symbols.
#
#   * Right now, we only pull the -I and -D flags. That seems to be sufficient
#     for everything I've used it for.
#
#   * That whole ninja & clang thing? We could support other configs if someone
#     were willing to write the correct commands and a parser.
#
#   * This has only been tested on gTrusty.


import os
import os.path
import subprocess
import sys


# Flags from YCM's default config.
flags = [
'-DUSE_CLANG_COMPLETER',
'-std=gnu++0x',
'-x',
'c++',
]


def PathExists(*args):
  return os.path.exists(os.path.join(*args))


def FindV8SrcFromFilename(filename):
  """Searches for the root of the V8 checkout.

  Simply checks parent directories until it finds .gclient and v8/.

  Args:
    filename: (String) Path to source file being edited.

  Returns:
    (String) Path of 'v8/', or None if unable to find.
  """
  curdir = os.path.normpath(os.path.dirname(filename))
  while not (PathExists(curdir, 'v8') and PathExists(curdir, 'v8', 'DEPS')
             and (PathExists(curdir, '.gclient')
                  or PathExists(curdir, 'v8', '.git'))):
    nextdir = os.path.normpath(os.path.join(curdir, '..'))
    if nextdir == curdir:
      return None
    curdir = nextdir
  return os.path.join(curdir, 'v8')


def GetClangCommandFromNinjaForFilename(v8_root, filename):
  """Returns the command line to build |filename|.

  Asks ninja how it would build the source file. If the specified file is a
  header, tries to find its companion source file first.

  Args:
    v8_root: (String) Path to v8/.
    filename: (String) Path to source file being edited.

  Returns:
    (List of Strings) Command line arguments for clang.
  """
  if not v8_root:
    return []

  # Generally, everyone benefits from including V8's root, because all of
  # V8's includes are relative to that.
  v8_flags = ['-I' + os.path.join(v8_root)]

  # Version of Clang used to compile V8 can be newer then version of
  # libclang that YCM uses for completion. So it's possible that YCM's libclang
  # doesn't know about some used warning options, which causes compilation
  # warnings (and errors, because of '-Werror');
  v8_flags.append('-Wno-unknown-warning-option')

  # Header files can't be built. Instead, try to match a header file to its
  # corresponding source file.
  if filename.endswith('.h'):
    alternates = ['.cc', '.cpp']
    for alt_extension in alternates:
      alt_name = filename[:-2] + alt_extension
      if os.path.exists(alt_name):
        filename = alt_name
        break
    else:
      if filename.endswith('-inl.h'):
        for alt_extension in alternates:
          alt_name = filename[:-6] + alt_extension
          if os.path.exists(alt_name):
            filename = alt_name
            break;
        else:
          # If this is a standalone -inl.h file with no source, the best we can
          # do is try to use the default flags.
          return v8_flags
      else:
        # If this is a standalone .h file with no source, the best we can do is
        # try to use the default flags.
        return v8_flags

  sys.path.append(os.path.join(v8_root, 'tools', 'ninja'))
  from ninja_output import GetNinjaOutputDirectory
  out_dir = os.path.realpath(GetNinjaOutputDirectory(v8_root))

  # Ninja needs the path to the source file relative to the output build
  # directory.
  rel_filename = os.path.relpath(os.path.realpath(filename), out_dir)

  # Ask ninja how it would build our source file.
  p = subprocess.Popen(['ninja', '-v', '-C', out_dir, '-t',
                        'commands', rel_filename + '^'],
                       stdout=subprocess.PIPE)
  stdout, stderr = p.communicate()
  if p.returncode:
    return v8_flags

  # Ninja might execute several commands to build something. We want the last
  # clang command.
  clang_line = None
  for line in reversed(stdout.split('\n')):
    if 'clang' in line:
      clang_line = line
      break
  else:
    return v8_flags

  # Parse flags that are important for YCM's purposes.
  for flag in clang_line.split(' '):
    if flag.startswith('-I'):
      # Relative paths need to be resolved, because they're relative to the
      # output dir, not the source.
      if flag[2] == '/':
        v8_flags.append(flag)
      else:
        abs_path = os.path.normpath(os.path.join(out_dir, flag[2:]))
        v8_flags.append('-I' + abs_path)
    elif flag.startswith('-std'):
      v8_flags.append(flag)
    elif flag.startswith('-') and flag[1] in 'DWFfmO':
      if flag == '-Wno-deprecated-register' or flag == '-Wno-header-guard':
        # These flags causes libclang (3.3) to crash. Remove it until things
        # are fixed.
        continue
      v8_flags.append(flag)

  return v8_flags


def FlagsForFile(filename):
  """This is the main entry point for YCM. Its interface is fixed.

  Args:
    filename: (String) Path to source file being edited.

  Returns:
    (Dictionary)
      'flags': (List of Strings) Command line flags.
      'do_cache': (Boolean) True if the result should be cached.
  """
  v8_root = FindV8SrcFromFilename(filename)
  v8_flags = GetClangCommandFromNinjaForFilename(v8_root, filename)
  final_flags = flags + v8_flags
  return {
    'flags': final_flags,
    'do_cache': True
  }
node-v4.2.6/deps/v8/AUTHORS000644 000766 000024 00000007046 12650222324 015313 0ustar00iojsstaff000000 000000 # Below is a list of people and organizations that have contributed
# to the V8 project.  Names should be added to the list like so:
#
#   Name/Organization 

Google Inc. <*@google.com>
The Chromium Authors <*@chromium.org>
Sigma Designs Inc. <*@sdesigns.com>
ARM Ltd. <*@arm.com>
Hewlett-Packard Development Company, LP <*@palm.com>
Igalia, S.L. <*@igalia.com>
Joyent, Inc. <*@joyent.com>
Bloomberg Finance L.P. <*@bloomberg.net>
NVIDIA Corporation <*@nvidia.com>
BlackBerry Limited <*@blackberry.com>
Opera Software ASA <*@opera.com>
Intel Corporation <*@intel.com>
MIPS Technologies, Inc. <*@mips.com>
Imagination Technologies, LLC <*@imgtec.com>
Loongson Technology Corporation Limited <*@loongson.cn>
Code Aurora Forum <*@codeaurora.org>
Home Jinni Inc. <*@homejinni.com>
IBM Inc. <*@*.ibm.com>
Samsung <*@*.samsung.com>
Joyent, Inc <*@joyent.com>
RT-RK Computer Based System <*@rt-rk.com>
Amazon, Inc <*@amazon.com>
ST Microelectronics <*@st.com>
Yandex LLC <*@yandex-team.ru>
StrongLoop, Inc. <*@strongloop.com>

Aaron Bieber 
Abdulla Kamar 
Akinori MUSHA 
Alexander Botero-Lowry 
Alexander Karpinsky 
Alexandre Vassalotti 
Alexis Campailla 
Andreas Anyuru 
Andrew Paprocki 
Andrei Kashcha 
Ben Noordhuis 
Bert Belder 
Burcu Dogan 
Caitlin Potter 
Craig Schlenter 
Christopher A. Taylor 
Daniel Andersson 
Daniel James 
Douglas Crosher 
Erich Ocean 
Fedor Indutny 
Felix Geisendörfer 
Filipe David Manana 
Geoffrey Garside 
Han Choongwoo 
Hirofumi Mako 
Ioseb Dzmanashvili 
Isiah Meadows 
Jan de Mooij 
Jay Freeman 
James Pike 
Jianghua Yang 
Joel Stanley 
Johan Bergström 
Jonathan Liu 
JunHo Seo 
Kang-Hao (Kenny) Lu 
Luis Reis 
Luke Zarko 
Maciej Małecki 
Marcin Cieślak 
Mathias Bynens 
Matt Hanselman 
Matthew Sporleder 
Maxim Mossienko 
Michael Lutz 
Michael Smith 
Mike Gilbert 
Mike Pennisi 
Nicolas Antonius Ernst Leopold Maria Kaiser 
Paolo Giarrusso 
Patrick Gansterer 
Peter Varga 
Paul Lind 
Rafal Krypa 
Refael Ackermann 
Rene Rebe 
Robert Mustacchi 
Robert Nagy 
Ryan Dahl 
Sandro Santilli 
Sanjoy Das 
Seo Sanghyeon 
Tobias Burnus 
Victor Costan 
Vlad Burlik 
Vladimir Shutoff 
Yu Yin 
Zhongping Wang 
柳荣一 
node-v4.2.6/deps/v8/benchmarks/000755 000766 000024 00000000000 12650222324 016351 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/build/000755 000766 000024 00000000000 12650222324 015333 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/BUILD.gn000644 000766 000024 00000141503 12650222324 015425 0ustar00iojsstaff000000 000000 # Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/android/config.gni")
import("//build/config/arm.gni")
import("//build/config/mips.gni")

# Because standalone V8 builds are not supported, assume this is part of a
# Chromium build.
import("//build/module_args/v8.gni")

# TODO(jochen): These will need to be user-settable to support standalone V8
# builds.
v8_deprecation_warnings = false
v8_enable_disassembler = false
v8_enable_gdbjit = false
v8_enable_handle_zapping = true
v8_enable_i18n_support = true
v8_enable_verify_heap = false
v8_interpreted_regexp = false
v8_object_print = false
v8_postmortem_support = false
v8_use_snapshot = true
v8_target_arch = target_cpu
v8_random_seed = "314159265"
v8_toolset_for_d8 = "host"

# The snapshot needs to be compiled for the host, but compiled with
# a toolchain that matches the bit-width of the target.
#
# TODO(GYP): For now we only support 32-bit little-endian target builds from an
# x64 Linux host. Eventually we need to support all of the host/target
# configurations v8 runs on.
if (host_cpu == "x64" && host_os == "linux") {
  if (target_cpu == "arm" || target_cpu == "mipsel" || target_cpu == "x86") {
    snapshot_toolchain = "//build/toolchain/linux:clang_x86"
  } else if (target_cpu == "x64") {
    snapshot_toolchain = "//build/toolchain/linux:clang_x64"
  } else {
    assert(false, "Need environment for this arch")
  }
} else {
  snapshot_toolchain = default_toolchain
}

###############################################################################
# Configurations
#
config("internal_config") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  include_dirs = [ "." ]

  if (is_component_build) {
    defines = [
      "V8_SHARED",
      "BUILDING_V8_SHARED",
    ]
  }
}

config("internal_config_base") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  include_dirs = [ "." ]
}

# This config should only be applied to code using V8 and not any V8 code
# itself.
config("external_config") {
  if (is_component_build) {
    defines = [
      "V8_SHARED",
      "USING_V8_SHARED",
    ]
  }
  include_dirs = [ "include" ]
}

config("features") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  defines = []

  if (v8_enable_disassembler == true) {
    defines += [ "ENABLE_DISASSEMBLER" ]
  }
  if (v8_enable_gdbjit == true) {
    defines += [ "ENABLE_GDB_JIT_INTERFACE" ]
  }
  if (v8_object_print == true) {
    defines += [ "OBJECT_PRINT" ]
  }
  if (v8_enable_verify_heap == true) {
    defines += [ "VERIFY_HEAP" ]
  }
  if (v8_interpreted_regexp == true) {
    defines += [ "V8_INTERPRETED_REGEXP" ]
  }
  if (v8_deprecation_warnings == true) {
    defines += [ "V8_DEPRECATION_WARNINGS" ]
  }
  if (v8_enable_i18n_support == true) {
    defines += [ "V8_I18N_SUPPORT" ]
  }
  if (v8_enable_handle_zapping == true) {
    defines += [ "ENABLE_HANDLE_ZAPPING" ]
  }
  if (v8_use_external_startup_data == true) {
    defines += [ "V8_USE_EXTERNAL_STARTUP_DATA" ]
  }
}

config("toolchain") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  defines = []
  cflags = []

  # TODO(jochen): Add support for arm subarchs, mips, mipsel, mips64el.

  if (v8_target_arch == "arm") {
    defines += [ "V8_TARGET_ARCH_ARM" ]
    if (current_cpu == "arm") {
      if (arm_version == 7) {
        defines += [ "CAN_USE_ARMV7_INSTRUCTIONS" ]
      }
      if (arm_fpu == "vfpv3-d16") {
        defines += [ "CAN_USE_VFP3_INSTRUCTIONS" ]
      } else if (arm_fpu == "vfpv3") {
        defines += [
          "CAN_USE_VFP3_INSTRUCTIONS",
          "CAN_USE_VFP32DREGS",
        ]
      } else if (arm_fpu == "neon") {
        defines += [
          "CAN_USE_VFP3_INSTRUCTIONS",
          "CAN_USE_VFP32DREGS",
          "CAN_USE_NEON",
        ]
      }
    } else {
      # These defines ares used for the ARM simulator.
      defines += [
        "CAN_USE_ARMV7_INSTRUCTIONS",
        "CAN_USE_VFP3_INSTRUCTIONS",
        "CAN_USE_VFP32DREGS",
        "USE_EABI_HARDFLOAT=0",
      ]
    }

    # TODO(jochen): Add support for arm_test_noprobe.
  }
  if (v8_target_arch == "arm64") {
    defines += [ "V8_TARGET_ARCH_ARM64" ]
  }
  if (v8_target_arch == "mipsel") {
    defines += [ "V8_TARGET_ARCH_MIPS" ]
  }
  if (v8_target_arch == "mips64el") {
    defines += [ "V8_TARGET_ARCH_MIPS64" ]
  }
  if (v8_target_arch == "x86") {
    defines += [ "V8_TARGET_ARCH_IA32" ]
  }
  if (v8_target_arch == "x64") {
    defines += [ "V8_TARGET_ARCH_X64" ]
  }
  if (is_win) {
    defines += [ "WIN32" ]
    # TODO(jochen): Support v8_enable_prof.
  }

  # TODO(jochen): Add support for compiling with simulators.

  if (is_debug) {
    # TODO(jochen): Add support for different debug optimization levels.
    defines += [
      "ENABLE_DISASSEMBLER",
      "V8_ENABLE_CHECKS",
      "OBJECT_PRINT",
      "VERIFY_HEAP",
      "DEBUG",
      "OPTIMIZED_DEBUG",
    ]
  }
}

###############################################################################
# Actions
#

action("js2c") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  script = "tools/js2c.py"

  # The script depends on this other script, this rule causes a rebuild if it
  # changes.
  inputs = [ "tools/jsmin.py" ]

  sources = [
    "src/macros.py",
    "src/messages.h",
    "src/runtime.js",
    "src/prologue.js",
    "src/v8natives.js",
    "src/symbol.js",
    "src/array.js",
    "src/string.js",
    "src/uri.js",
    "src/math.js",
    "src/third_party/fdlibm/fdlibm.js",
    "src/date.js",
    "src/regexp.js",
    "src/arraybuffer.js",
    "src/typedarray.js",
    "src/iterator-prototype.js",
    "src/generator.js",
    "src/object-observe.js",
    "src/collection.js",
    "src/weak-collection.js",
    "src/collection-iterator.js",
    "src/promise.js",
    "src/messages.js",
    "src/json.js",
    "src/array-iterator.js",
    "src/string-iterator.js",
    "src/debug-debugger.js",
    "src/mirror-debugger.js",
    "src/liveedit-debugger.js",
    "src/templates.js",
    "src/harmony-array.js",
    "src/harmony-typedarray.js",
  ]

  outputs = [
    "$target_gen_dir/libraries.cc",
  ]

  if (v8_enable_i18n_support) {
    sources += [ "src/i18n.js" ]
  }

  args = [
           rebase_path("$target_gen_dir/libraries.cc", root_build_dir),
           "CORE",
         ] + rebase_path(sources, root_build_dir)

  if (v8_use_external_startup_data) {
    outputs += [ "$target_gen_dir/libraries.bin" ]
    args += [
      "--startup_blob",
      rebase_path("$target_gen_dir/libraries.bin", root_build_dir),
    ]
  }
}

action("js2c_experimental") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  script = "tools/js2c.py"

  # The script depends on this other script, this rule causes a rebuild if it
  # changes.
  inputs = [ "tools/jsmin.py" ]

  sources = [
    "src/macros.py",
    "src/messages.h",
    "src/proxy.js",
    "src/generator.js",
    "src/harmony-atomics.js",
    "src/harmony-array-includes.js",
    "src/harmony-concat-spreadable.js",
    "src/harmony-tostring.js",
    "src/harmony-regexp.js",
    "src/harmony-reflect.js",
    "src/harmony-spread.js",
    "src/harmony-object.js",
    "src/harmony-sharedarraybuffer.js"
  ]

  outputs = [
    "$target_gen_dir/experimental-libraries.cc",
  ]

  args = [
           rebase_path("$target_gen_dir/experimental-libraries.cc",
                       root_build_dir),
           "EXPERIMENTAL",
         ] + rebase_path(sources, root_build_dir)

  if (v8_use_external_startup_data) {
    outputs += [ "$target_gen_dir/libraries_experimental.bin" ]
    args += [
      "--startup_blob",
      rebase_path("$target_gen_dir/libraries_experimental.bin", root_build_dir),
    ]
  }
}

action("js2c_extras") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  script = "tools/js2c.py"

  # The script depends on this other script, this rule causes a rebuild if it
  # changes.
  inputs = [ "tools/jsmin.py" ]

  sources = v8_extra_library_files

  outputs = [
    "$target_gen_dir/extras-libraries.cc",
  ]

  args = [
           rebase_path("$target_gen_dir/extras-libraries.cc",
                       root_build_dir),
           "EXTRAS",
         ] + rebase_path(sources, root_build_dir)

  if (v8_use_external_startup_data) {
    outputs += [ "$target_gen_dir/libraries_extras.bin" ]
    args += [
      "--startup_blob",
      rebase_path("$target_gen_dir/libraries_extras.bin", root_build_dir),
    ]
  }
}

action("d8_js2c") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  script = "tools/js2c.py"

  inputs = [
    "src/d8.js",
    "src/macros.py",
  ]

  outputs = [
    "$target_gen_dir/d8-js.cc",
  ]

  args = rebase_path(outputs, root_build_dir) + [ "D8" ] +
         rebase_path(inputs, root_build_dir)
}

if (v8_use_external_startup_data) {
  action("natives_blob") {
    visibility = [ ":*" ]  # Only targets in this file can depend on this.

    deps = [
      ":js2c",
      ":js2c_experimental",
      ":js2c_extras",
    ]

    sources = [
      "$target_gen_dir/libraries.bin",
      "$target_gen_dir/libraries_experimental.bin",
      "$target_gen_dir/libraries_extras.bin",
    ]

    outputs = [
      "$root_out_dir/natives_blob.bin",
    ]

    script = "tools/concatenate-files.py"

    args = rebase_path(sources + outputs, root_build_dir)
  }
}

action("postmortem-metadata") {
  # Only targets in this file and the top-level visibility target can
  # depend on this.
  visibility = [
    ":*",
    "//:gn_visibility",
  ]

  script = "tools/gen-postmortem-metadata.py"

  sources = [
    "src/objects.h",
    "src/objects-inl.h",
  ]

  outputs = [
    "$target_gen_dir/debug-support.cc",
  ]

  args = rebase_path(outputs, root_build_dir) +
         rebase_path(sources, root_build_dir)
}

action("run_mksnapshot") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  deps = [
    ":mksnapshot($snapshot_toolchain)",
  ]

  script = "tools/run.py"

  outputs = [
    "$target_gen_dir/snapshot.cc",
  ]

  args = [
    "./" + rebase_path(get_label_info(":mksnapshot($snapshot_toolchain)",
                                      "root_out_dir") + "/mksnapshot",
                       root_build_dir),
    "--log-snapshot-positions",
    "--logfile",
    rebase_path("$target_gen_dir/snapshot.log", root_build_dir),
    rebase_path("$target_gen_dir/snapshot.cc", root_build_dir),
  ]

  if (v8_random_seed != "0") {
    args += [
      "--random-seed",
      v8_random_seed,
    ]
  }

  if (v8_use_external_startup_data) {
    outputs += [ "$root_out_dir/snapshot_blob.bin" ]
    args += [
      "--startup_blob",
      rebase_path("$root_out_dir/snapshot_blob.bin", root_build_dir),
    ]
  }
}

###############################################################################
# Source Sets (aka static libraries)
#

source_set("v8_nosnapshot") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  deps = [
    ":js2c",
    ":js2c_experimental",
    ":js2c_extras",
    ":v8_base",
  ]

  sources = [
    "$target_gen_dir/libraries.cc",
    "$target_gen_dir/experimental-libraries.cc",
    "$target_gen_dir/extras-libraries.cc",
    "src/snapshot/snapshot-empty.cc",
  ]

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [ "//build/config/compiler:no_chromium_code" ]
  configs += [
    ":internal_config",
    ":features",
    ":toolchain",
  ]
}

source_set("v8_snapshot") {
  # Only targets in this file and the top-level visibility target can
  # depend on this.
  visibility = [
    ":*",
    "//:gn_visibility",
  ]

  deps = [
    ":js2c",
    ":js2c_experimental",
    ":js2c_extras",
    ":v8_base",
  ]
  public_deps = [
    # This should be public so downstream targets can declare the snapshot
    # output file as their inputs.
    ":run_mksnapshot",
  ]

  sources = [
    "$target_gen_dir/libraries.cc",
    "$target_gen_dir/experimental-libraries.cc",
    "$target_gen_dir/extras-libraries.cc",
    "$target_gen_dir/snapshot.cc",
  ]

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [ "//build/config/compiler:no_chromium_code" ]
  configs += [
    ":internal_config",
    ":features",
    ":toolchain",
  ]
}

if (v8_use_external_startup_data) {
  source_set("v8_external_snapshot") {
    visibility = [ ":*" ]  # Only targets in this file can depend on this.

    deps = [
      ":js2c",
      ":js2c_experimental",
      ":js2c_extras",
      ":v8_base",
    ]
    public_deps = [
      ":natives_blob",
      ":run_mksnapshot",
    ]

    sources = [
      "src/snapshot/natives-external.cc",
      "src/snapshot/snapshot-external.cc",
    ]

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]
    configs += [
      ":internal_config",
      ":features",
      ":toolchain",
    ]
  }
}

source_set("v8_base") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  sources = [
    "include/v8-debug.h",
    "include/v8-platform.h",
    "include/v8-profiler.h",
    "include/v8-testing.h",
    "include/v8-util.h",
    "include/v8-version.h",
    "include/v8.h",
    "include/v8config.h",
    "src/accessors.cc",
    "src/accessors.h",
    "src/allocation.cc",
    "src/allocation.h",
    "src/allocation-site-scopes.cc",
    "src/allocation-site-scopes.h",
    "src/allocation-tracker.cc",
    "src/allocation-tracker.h",
    "src/api.cc",
    "src/api.h",
    "src/api-natives.cc",
    "src/api-natives.h",
    "src/arguments.cc",
    "src/arguments.h",
    "src/assembler.cc",
    "src/assembler.h",
    "src/assert-scope.h",
    "src/assert-scope.cc",
    "src/ast-literal-reindexer.cc",
    "src/ast-literal-reindexer.h",
    "src/ast-numbering.cc",
    "src/ast-numbering.h",
    "src/ast-value-factory.cc",
    "src/ast-value-factory.h",
    "src/ast.cc",
    "src/ast.h",
    "src/background-parsing-task.cc",
    "src/background-parsing-task.h",
    "src/bailout-reason.cc",
    "src/bailout-reason.h",
    "src/basic-block-profiler.cc",
    "src/basic-block-profiler.h",
    "src/bignum-dtoa.cc",
    "src/bignum-dtoa.h",
    "src/bignum.cc",
    "src/bignum.h",
    "src/bit-vector.cc",
    "src/bit-vector.h",
    "src/bootstrapper.cc",
    "src/bootstrapper.h",
    "src/builtins.cc",
    "src/builtins.h",
    "src/bytecodes-irregexp.h",
    "src/cached-powers.cc",
    "src/cached-powers.h",
    "src/char-predicates.cc",
    "src/char-predicates-inl.h",
    "src/char-predicates.h",
    "src/checks.cc",
    "src/checks.h",
    "src/circular-queue-inl.h",
    "src/circular-queue.h",
    "src/code-factory.cc",
    "src/code-factory.h",
    "src/code-stubs.cc",
    "src/code-stubs.h",
    "src/code-stubs-hydrogen.cc",
    "src/code.h",
    "src/codegen.cc",
    "src/codegen.h",
    "src/compilation-cache.cc",
    "src/compilation-cache.h",
    "src/compilation-dependencies.cc",
    "src/compilation-dependencies.h",
    "src/compilation-statistics.cc",
    "src/compilation-statistics.h",
    "src/compiler/access-builder.cc",
    "src/compiler/access-builder.h",
    "src/compiler/all-nodes.cc",
    "src/compiler/all-nodes.h",
    "src/compiler/ast-graph-builder.cc",
    "src/compiler/ast-graph-builder.h",
    "src/compiler/ast-loop-assignment-analyzer.cc",
    "src/compiler/ast-loop-assignment-analyzer.h",
    "src/compiler/basic-block-instrumentor.cc",
    "src/compiler/basic-block-instrumentor.h",
    "src/compiler/change-lowering.cc",
    "src/compiler/change-lowering.h",
    "src/compiler/coalesced-live-ranges.cc",
    "src/compiler/coalesced-live-ranges.h",
    "src/compiler/code-generator-impl.h",
    "src/compiler/code-generator.cc",
    "src/compiler/code-generator.h",
    "src/compiler/common-node-cache.cc",
    "src/compiler/common-node-cache.h",
    "src/compiler/common-operator-reducer.cc",
    "src/compiler/common-operator-reducer.h",
    "src/compiler/common-operator.cc",
    "src/compiler/common-operator.h",
    "src/compiler/control-builders.cc",
    "src/compiler/control-builders.h",
    "src/compiler/control-equivalence.cc",
    "src/compiler/control-equivalence.h",
    "src/compiler/control-flow-optimizer.cc",
    "src/compiler/control-flow-optimizer.h",
    "src/compiler/dead-code-elimination.cc",
    "src/compiler/dead-code-elimination.h",
    "src/compiler/diamond.h",
    "src/compiler/frame.h",
    "src/compiler/frame-elider.cc",
    "src/compiler/frame-elider.h",
    "src/compiler/frame-states.cc",
    "src/compiler/frame-states.h",
    "src/compiler/gap-resolver.cc",
    "src/compiler/gap-resolver.h",
    "src/compiler/graph-builder.h",
    "src/compiler/graph-reducer.cc",
    "src/compiler/graph-reducer.h",
    "src/compiler/graph-replay.cc",
    "src/compiler/graph-replay.h",
    "src/compiler/graph-trimmer.cc",
    "src/compiler/graph-trimmer.h",
    "src/compiler/graph-visualizer.cc",
    "src/compiler/graph-visualizer.h",
    "src/compiler/graph.cc",
    "src/compiler/graph.h",
    "src/compiler/greedy-allocator.cc",
    "src/compiler/greedy-allocator.h",
    "src/compiler/instruction-codes.h",
    "src/compiler/instruction-selector-impl.h",
    "src/compiler/instruction-selector.cc",
    "src/compiler/instruction-selector.h",
    "src/compiler/instruction.cc",
    "src/compiler/instruction.h",
    "src/compiler/js-builtin-reducer.cc",
    "src/compiler/js-builtin-reducer.h",
    "src/compiler/js-context-specialization.cc",
    "src/compiler/js-context-specialization.h",
    "src/compiler/js-frame-specialization.cc",
    "src/compiler/js-frame-specialization.h",
    "src/compiler/js-generic-lowering.cc",
    "src/compiler/js-generic-lowering.h",
    "src/compiler/js-graph.cc",
    "src/compiler/js-graph.h",
    "src/compiler/js-inlining.cc",
    "src/compiler/js-inlining.h",
    "src/compiler/js-intrinsic-lowering.cc",
    "src/compiler/js-intrinsic-lowering.h",
    "src/compiler/js-operator.cc",
    "src/compiler/js-operator.h",
    "src/compiler/js-type-feedback.cc",
    "src/compiler/js-type-feedback.h",
    "src/compiler/js-typed-lowering.cc",
    "src/compiler/js-typed-lowering.h",
    "src/compiler/jump-threading.cc",
    "src/compiler/jump-threading.h",
    "src/compiler/linkage-impl.h",
    "src/compiler/linkage.cc",
    "src/compiler/linkage.h",
    "src/compiler/liveness-analyzer.cc",
    "src/compiler/liveness-analyzer.h",
    "src/compiler/load-elimination.cc",
    "src/compiler/load-elimination.h",
    "src/compiler/loop-peeling.cc",
    "src/compiler/loop-analysis.cc",
    "src/compiler/loop-analysis.h",
    "src/compiler/machine-operator-reducer.cc",
    "src/compiler/machine-operator-reducer.h",
    "src/compiler/machine-operator.cc",
    "src/compiler/machine-operator.h",
    "src/compiler/machine-type.cc",
    "src/compiler/machine-type.h",
    "src/compiler/move-optimizer.cc",
    "src/compiler/move-optimizer.h",
    "src/compiler/node-aux-data.h",
    "src/compiler/node-cache.cc",
    "src/compiler/node-cache.h",
    "src/compiler/node-marker.cc",
    "src/compiler/node-marker.h",
    "src/compiler/node-matchers.cc",
    "src/compiler/node-matchers.h",
    "src/compiler/node-properties.cc",
    "src/compiler/node-properties.h",
    "src/compiler/node.cc",
    "src/compiler/node.h",
    "src/compiler/opcodes.cc",
    "src/compiler/opcodes.h",
    "src/compiler/operator-properties.cc",
    "src/compiler/operator-properties.h",
    "src/compiler/operator.cc",
    "src/compiler/operator.h",
    "src/compiler/osr.cc",
    "src/compiler/osr.h",
    "src/compiler/pipeline.cc",
    "src/compiler/pipeline.h",
    "src/compiler/pipeline-statistics.cc",
    "src/compiler/pipeline-statistics.h",
    "src/compiler/raw-machine-assembler.cc",
    "src/compiler/raw-machine-assembler.h",
    "src/compiler/register-allocator.cc",
    "src/compiler/register-allocator.h",
    "src/compiler/register-allocator-verifier.cc",
    "src/compiler/register-allocator-verifier.h",
    "src/compiler/register-configuration.cc",
    "src/compiler/register-configuration.h",
    "src/compiler/representation-change.h",
    "src/compiler/schedule.cc",
    "src/compiler/schedule.h",
    "src/compiler/scheduler.cc",
    "src/compiler/scheduler.h",
    "src/compiler/select-lowering.cc",
    "src/compiler/select-lowering.h",
    "src/compiler/simplified-lowering.cc",
    "src/compiler/simplified-lowering.h",
    "src/compiler/simplified-operator-reducer.cc",
    "src/compiler/simplified-operator-reducer.h",
    "src/compiler/simplified-operator.cc",
    "src/compiler/simplified-operator.h",
    "src/compiler/source-position.cc",
    "src/compiler/source-position.h",
    "src/compiler/state-values-utils.cc",
    "src/compiler/state-values-utils.h",
    "src/compiler/tail-call-optimization.cc",
    "src/compiler/tail-call-optimization.h",
    "src/compiler/typer.cc",
    "src/compiler/typer.h",
    "src/compiler/value-numbering-reducer.cc",
    "src/compiler/value-numbering-reducer.h",
    "src/compiler/verifier.cc",
    "src/compiler/verifier.h",
    "src/compiler/zone-pool.cc",
    "src/compiler/zone-pool.h",
    "src/compiler.cc",
    "src/compiler.h",
    "src/contexts.cc",
    "src/contexts.h",
    "src/conversions-inl.h",
    "src/conversions.cc",
    "src/conversions.h",
    "src/counters.cc",
    "src/counters.h",
    "src/cpu-profiler-inl.h",
    "src/cpu-profiler.cc",
    "src/cpu-profiler.h",
    "src/date.cc",
    "src/date.h",
    "src/dateparser-inl.h",
    "src/dateparser.cc",
    "src/dateparser.h",
    "src/debug.cc",
    "src/debug.h",
    "src/deoptimizer.cc",
    "src/deoptimizer.h",
    "src/disasm.h",
    "src/disassembler.cc",
    "src/disassembler.h",
    "src/diy-fp.cc",
    "src/diy-fp.h",
    "src/double.h",
    "src/dtoa.cc",
    "src/dtoa.h",
    "src/effects.h",
    "src/elements-kind.cc",
    "src/elements-kind.h",
    "src/elements.cc",
    "src/elements.h",
    "src/execution.cc",
    "src/execution.h",
    "src/expression-classifier.h",
    "src/extensions/externalize-string-extension.cc",
    "src/extensions/externalize-string-extension.h",
    "src/extensions/free-buffer-extension.cc",
    "src/extensions/free-buffer-extension.h",
    "src/extensions/gc-extension.cc",
    "src/extensions/gc-extension.h",
    "src/extensions/statistics-extension.cc",
    "src/extensions/statistics-extension.h",
    "src/extensions/trigger-failure-extension.cc",
    "src/extensions/trigger-failure-extension.h",
    "src/factory.cc",
    "src/factory.h",
    "src/fast-dtoa.cc",
    "src/fast-dtoa.h",
    "src/field-index.h",
    "src/field-index-inl.h",
    "src/fixed-dtoa.cc",
    "src/fixed-dtoa.h",
    "src/flag-definitions.h",
    "src/flags.cc",
    "src/flags.h",
    "src/frames-inl.h",
    "src/frames.cc",
    "src/frames.h",
    "src/full-codegen.cc",
    "src/full-codegen.h",
    "src/func-name-inferrer.cc",
    "src/func-name-inferrer.h",
    "src/gdb-jit.cc",
    "src/gdb-jit.h",
    "src/global-handles.cc",
    "src/global-handles.h",
    "src/globals.h",
    "src/handles-inl.h",
    "src/handles.cc",
    "src/handles.h",
    "src/hashmap.h",
    "src/heap-profiler.cc",
    "src/heap-profiler.h",
    "src/heap-snapshot-generator-inl.h",
    "src/heap-snapshot-generator.cc",
    "src/heap-snapshot-generator.h",
    "src/heap/gc-idle-time-handler.cc",
    "src/heap/gc-idle-time-handler.h",
    "src/heap/gc-tracer.cc",
    "src/heap/gc-tracer.h",
    "src/heap/heap-inl.h",
    "src/heap/heap.cc",
    "src/heap/heap.h",
    "src/heap/identity-map.cc",
    "src/heap/identity-map.h",
    "src/heap/incremental-marking.cc",
    "src/heap/incremental-marking.h",
    "src/heap/mark-compact-inl.h",
    "src/heap/mark-compact.cc",
    "src/heap/mark-compact.h",
    "src/heap/memory-reducer.cc",
    "src/heap/memory-reducer.h",
    "src/heap/objects-visiting-inl.h",
    "src/heap/objects-visiting.cc",
    "src/heap/objects-visiting.h",
    "src/heap/spaces-inl.h",
    "src/heap/spaces.cc",
    "src/heap/spaces.h",
    "src/heap/store-buffer-inl.h",
    "src/heap/store-buffer.cc",
    "src/heap/store-buffer.h",
    "src/hydrogen-alias-analysis.h",
    "src/hydrogen-bce.cc",
    "src/hydrogen-bce.h",
    "src/hydrogen-bch.cc",
    "src/hydrogen-bch.h",
    "src/hydrogen-canonicalize.cc",
    "src/hydrogen-canonicalize.h",
    "src/hydrogen-check-elimination.cc",
    "src/hydrogen-check-elimination.h",
    "src/hydrogen-dce.cc",
    "src/hydrogen-dce.h",
    "src/hydrogen-dehoist.cc",
    "src/hydrogen-dehoist.h",
    "src/hydrogen-environment-liveness.cc",
    "src/hydrogen-environment-liveness.h",
    "src/hydrogen-escape-analysis.cc",
    "src/hydrogen-escape-analysis.h",
    "src/hydrogen-flow-engine.h",
    "src/hydrogen-instructions.cc",
    "src/hydrogen-instructions.h",
    "src/hydrogen.cc",
    "src/hydrogen.h",
    "src/hydrogen-gvn.cc",
    "src/hydrogen-gvn.h",
    "src/hydrogen-infer-representation.cc",
    "src/hydrogen-infer-representation.h",
    "src/hydrogen-infer-types.cc",
    "src/hydrogen-infer-types.h",
    "src/hydrogen-load-elimination.cc",
    "src/hydrogen-load-elimination.h",
    "src/hydrogen-mark-deoptimize.cc",
    "src/hydrogen-mark-deoptimize.h",
    "src/hydrogen-mark-unreachable.cc",
    "src/hydrogen-mark-unreachable.h",
    "src/hydrogen-osr.cc",
    "src/hydrogen-osr.h",
    "src/hydrogen-range-analysis.cc",
    "src/hydrogen-range-analysis.h",
    "src/hydrogen-redundant-phi.cc",
    "src/hydrogen-redundant-phi.h",
    "src/hydrogen-removable-simulates.cc",
    "src/hydrogen-removable-simulates.h",
    "src/hydrogen-representation-changes.cc",
    "src/hydrogen-representation-changes.h",
    "src/hydrogen-sce.cc",
    "src/hydrogen-sce.h",
    "src/hydrogen-store-elimination.cc",
    "src/hydrogen-store-elimination.h",
    "src/hydrogen-types.cc",
    "src/hydrogen-types.h",
    "src/hydrogen-uint32-analysis.cc",
    "src/hydrogen-uint32-analysis.h",
    "src/i18n.cc",
    "src/i18n.h",
    "src/icu_util.cc",
    "src/icu_util.h",
    "src/ic/access-compiler.cc",
    "src/ic/access-compiler.h",
    "src/ic/call-optimization.cc",
    "src/ic/call-optimization.h",
    "src/ic/handler-compiler.cc",
    "src/ic/handler-compiler.h",
    "src/ic/ic-inl.h",
    "src/ic/ic-state.cc",
    "src/ic/ic-state.h",
    "src/ic/ic.cc",
    "src/ic/ic.h",
    "src/ic/ic-compiler.cc",
    "src/ic/ic-compiler.h",
    "src/ic/stub-cache.cc",
    "src/ic/stub-cache.h",
    "src/interface-descriptors.cc",
    "src/interface-descriptors.h",
    "src/interpreter-irregexp.cc",
    "src/interpreter-irregexp.h",
    "src/isolate.cc",
    "src/isolate.h",
    "src/json-parser.h",
    "src/json-stringifier.h",
    "src/jsregexp-inl.h",
    "src/jsregexp.cc",
    "src/jsregexp.h",
    "src/layout-descriptor-inl.h",
    "src/layout-descriptor.cc",
    "src/layout-descriptor.h",
    "src/list-inl.h",
    "src/list.h",
    "src/lithium-allocator-inl.h",
    "src/lithium-allocator.cc",
    "src/lithium-allocator.h",
    "src/lithium-codegen.cc",
    "src/lithium-codegen.h",
    "src/lithium.cc",
    "src/lithium.h",
    "src/liveedit.cc",
    "src/liveedit.h",
    "src/log-inl.h",
    "src/log-utils.cc",
    "src/log-utils.h",
    "src/log.cc",
    "src/log.h",
    "src/lookup-inl.h",
    "src/lookup.cc",
    "src/lookup.h",
    "src/macro-assembler.h",
    "src/messages.cc",
    "src/messages.h",
    "src/modules.cc",
    "src/modules.h",
    "src/msan.h",
    "src/objects-debug.cc",
    "src/objects-inl.h",
    "src/objects-printer.cc",
    "src/objects.cc",
    "src/objects.h",
    "src/optimizing-compile-dispatcher.cc",
    "src/optimizing-compile-dispatcher.h",
    "src/ostreams.cc",
    "src/ostreams.h",
    "src/pattern-rewriter.cc",
    "src/parser.cc",
    "src/parser.h",
    "src/pending-compilation-error-handler.cc",
    "src/pending-compilation-error-handler.h",
    "src/preparse-data-format.h",
    "src/preparse-data.cc",
    "src/preparse-data.h",
    "src/preparser.cc",
    "src/preparser.h",
    "src/prettyprinter.cc",
    "src/prettyprinter.h",
    "src/profile-generator-inl.h",
    "src/profile-generator.cc",
    "src/profile-generator.h",
    "src/property-details.h",
    "src/property.cc",
    "src/property.h",
    "src/prototype.h",
    "src/regexp-macro-assembler-irregexp-inl.h",
    "src/regexp-macro-assembler-irregexp.cc",
    "src/regexp-macro-assembler-irregexp.h",
    "src/regexp-macro-assembler-tracer.cc",
    "src/regexp-macro-assembler-tracer.h",
    "src/regexp-macro-assembler.cc",
    "src/regexp-macro-assembler.h",
    "src/regexp-stack.cc",
    "src/regexp-stack.h",
    "src/rewriter.cc",
    "src/rewriter.h",
    "src/runtime-profiler.cc",
    "src/runtime-profiler.h",
    "src/runtime/runtime-array.cc",
    "src/runtime/runtime-atomics.cc",
    "src/runtime/runtime-classes.cc",
    "src/runtime/runtime-collections.cc",
    "src/runtime/runtime-compiler.cc",
    "src/runtime/runtime-date.cc",
    "src/runtime/runtime-debug.cc",
    "src/runtime/runtime-forin.cc",
    "src/runtime/runtime-function.cc",
    "src/runtime/runtime-generator.cc",
    "src/runtime/runtime-i18n.cc",
    "src/runtime/runtime-internal.cc",
    "src/runtime/runtime-json.cc",
    "src/runtime/runtime-literals.cc",
    "src/runtime/runtime-liveedit.cc",
    "src/runtime/runtime-maths.cc",
    "src/runtime/runtime-numbers.cc",
    "src/runtime/runtime-object.cc",
    "src/runtime/runtime-observe.cc",
    "src/runtime/runtime-proxy.cc",
    "src/runtime/runtime-regexp.cc",
    "src/runtime/runtime-scopes.cc",
    "src/runtime/runtime-strings.cc",
    "src/runtime/runtime-symbol.cc",
    "src/runtime/runtime-test.cc",
    "src/runtime/runtime-typedarray.cc",
    "src/runtime/runtime-uri.cc",
    "src/runtime/runtime-utils.h",
    "src/runtime/runtime.cc",
    "src/runtime/runtime.h",
    "src/safepoint-table.cc",
    "src/safepoint-table.h",
    "src/sampler.cc",
    "src/sampler.h",
    "src/scanner-character-streams.cc",
    "src/scanner-character-streams.h",
    "src/scanner.cc",
    "src/scanner.h",
    "src/scopeinfo.cc",
    "src/scopeinfo.h",
    "src/scopes.cc",
    "src/scopes.h",
    "src/signature.h",
    "src/simulator.h",
    "src/small-pointer-list.h",
    "src/smart-pointers.h",
    "src/snapshot/natives.h",
    "src/snapshot/serialize.cc",
    "src/snapshot/serialize.h",
    "src/snapshot/snapshot-common.cc",
    "src/snapshot/snapshot-source-sink.cc",
    "src/snapshot/snapshot-source-sink.h",
    "src/splay-tree.h",
    "src/splay-tree-inl.h",
    "src/snapshot/snapshot.h",
    "src/startup-data-util.h",
    "src/startup-data-util.cc",
    "src/string-builder.cc",
    "src/string-builder.h",
    "src/string-search.cc",
    "src/string-search.h",
    "src/string-stream.cc",
    "src/string-stream.h",
    "src/strings-storage.cc",
    "src/strings-storage.h",
    "src/strtod.cc",
    "src/strtod.h",
    "src/token.cc",
    "src/token.h",
    "src/transitions-inl.h",
    "src/transitions.cc",
    "src/transitions.h",
    "src/type-feedback-vector-inl.h",
    "src/type-feedback-vector.cc",
    "src/type-feedback-vector.h",
    "src/type-info.cc",
    "src/type-info.h",
    "src/types-inl.h",
    "src/types.cc",
    "src/types.h",
    "src/typing.cc",
    "src/typing.h",
    "src/unbound-queue-inl.h",
    "src/unbound-queue.h",
    "src/unicode-inl.h",
    "src/unicode.cc",
    "src/unicode.h",
    "src/unicode-decoder.cc",
    "src/unicode-decoder.h",
    "src/unique.h",
    "src/utils.cc",
    "src/utils.h",
    "src/v8.cc",
    "src/v8.h",
    "src/v8memory.h",
    "src/v8threads.cc",
    "src/v8threads.h",
    "src/variables.cc",
    "src/variables.h",
    "src/version.cc",
    "src/version.h",
    "src/vm-state-inl.h",
    "src/vm-state.h",
    "src/zone.cc",
    "src/zone.h",
    "src/zone-allocator.h",
    "src/zone-containers.h",
    "src/third_party/fdlibm/fdlibm.cc",
    "src/third_party/fdlibm/fdlibm.h",
  ]

  if (v8_target_arch == "x86") {
    sources += [
      "src/ia32/assembler-ia32-inl.h",
      "src/ia32/assembler-ia32.cc",
      "src/ia32/assembler-ia32.h",
      "src/ia32/builtins-ia32.cc",
      "src/ia32/code-stubs-ia32.cc",
      "src/ia32/code-stubs-ia32.h",
      "src/ia32/codegen-ia32.cc",
      "src/ia32/codegen-ia32.h",
      "src/ia32/cpu-ia32.cc",
      "src/ia32/debug-ia32.cc",
      "src/ia32/deoptimizer-ia32.cc",
      "src/ia32/disasm-ia32.cc",
      "src/ia32/frames-ia32.cc",
      "src/ia32/frames-ia32.h",
      "src/ia32/full-codegen-ia32.cc",
      "src/ia32/interface-descriptors-ia32.cc",
      "src/ia32/lithium-codegen-ia32.cc",
      "src/ia32/lithium-codegen-ia32.h",
      "src/ia32/lithium-gap-resolver-ia32.cc",
      "src/ia32/lithium-gap-resolver-ia32.h",
      "src/ia32/lithium-ia32.cc",
      "src/ia32/lithium-ia32.h",
      "src/ia32/macro-assembler-ia32.cc",
      "src/ia32/macro-assembler-ia32.h",
      "src/ia32/regexp-macro-assembler-ia32.cc",
      "src/ia32/regexp-macro-assembler-ia32.h",
      "src/compiler/ia32/code-generator-ia32.cc",
      "src/compiler/ia32/instruction-codes-ia32.h",
      "src/compiler/ia32/instruction-selector-ia32.cc",
      "src/compiler/ia32/linkage-ia32.cc",
      "src/ic/ia32/access-compiler-ia32.cc",
      "src/ic/ia32/handler-compiler-ia32.cc",
      "src/ic/ia32/ic-ia32.cc",
      "src/ic/ia32/ic-compiler-ia32.cc",
      "src/ic/ia32/stub-cache-ia32.cc",
    ]
  } else if (v8_target_arch == "x64") {
    sources += [
      "src/x64/assembler-x64-inl.h",
      "src/x64/assembler-x64.cc",
      "src/x64/assembler-x64.h",
      "src/x64/builtins-x64.cc",
      "src/x64/code-stubs-x64.cc",
      "src/x64/code-stubs-x64.h",
      "src/x64/codegen-x64.cc",
      "src/x64/codegen-x64.h",
      "src/x64/cpu-x64.cc",
      "src/x64/debug-x64.cc",
      "src/x64/deoptimizer-x64.cc",
      "src/x64/disasm-x64.cc",
      "src/x64/frames-x64.cc",
      "src/x64/frames-x64.h",
      "src/x64/full-codegen-x64.cc",
      "src/x64/interface-descriptors-x64.cc",
      "src/x64/lithium-codegen-x64.cc",
      "src/x64/lithium-codegen-x64.h",
      "src/x64/lithium-gap-resolver-x64.cc",
      "src/x64/lithium-gap-resolver-x64.h",
      "src/x64/lithium-x64.cc",
      "src/x64/lithium-x64.h",
      "src/x64/macro-assembler-x64.cc",
      "src/x64/macro-assembler-x64.h",
      "src/x64/regexp-macro-assembler-x64.cc",
      "src/x64/regexp-macro-assembler-x64.h",
      "src/compiler/x64/code-generator-x64.cc",
      "src/compiler/x64/instruction-codes-x64.h",
      "src/compiler/x64/instruction-selector-x64.cc",
      "src/compiler/x64/linkage-x64.cc",
      "src/ic/x64/access-compiler-x64.cc",
      "src/ic/x64/handler-compiler-x64.cc",
      "src/ic/x64/ic-x64.cc",
      "src/ic/x64/ic-compiler-x64.cc",
      "src/ic/x64/stub-cache-x64.cc",
    ]
  } else if (v8_target_arch == "arm") {
    sources += [
      "src/arm/assembler-arm-inl.h",
      "src/arm/assembler-arm.cc",
      "src/arm/assembler-arm.h",
      "src/arm/builtins-arm.cc",
      "src/arm/code-stubs-arm.cc",
      "src/arm/code-stubs-arm.h",
      "src/arm/codegen-arm.cc",
      "src/arm/codegen-arm.h",
      "src/arm/constants-arm.h",
      "src/arm/constants-arm.cc",
      "src/arm/cpu-arm.cc",
      "src/arm/debug-arm.cc",
      "src/arm/deoptimizer-arm.cc",
      "src/arm/disasm-arm.cc",
      "src/arm/frames-arm.cc",
      "src/arm/frames-arm.h",
      "src/arm/full-codegen-arm.cc",
      "src/arm/interface-descriptors-arm.cc",
      "src/arm/interface-descriptors-arm.h",
      "src/arm/lithium-arm.cc",
      "src/arm/lithium-arm.h",
      "src/arm/lithium-codegen-arm.cc",
      "src/arm/lithium-codegen-arm.h",
      "src/arm/lithium-gap-resolver-arm.cc",
      "src/arm/lithium-gap-resolver-arm.h",
      "src/arm/macro-assembler-arm.cc",
      "src/arm/macro-assembler-arm.h",
      "src/arm/regexp-macro-assembler-arm.cc",
      "src/arm/regexp-macro-assembler-arm.h",
      "src/arm/simulator-arm.cc",
      "src/arm/simulator-arm.h",
      "src/compiler/arm/code-generator-arm.cc",
      "src/compiler/arm/instruction-codes-arm.h",
      "src/compiler/arm/instruction-selector-arm.cc",
      "src/compiler/arm/linkage-arm.cc",
      "src/ic/arm/access-compiler-arm.cc",
      "src/ic/arm/handler-compiler-arm.cc",
      "src/ic/arm/ic-arm.cc",
      "src/ic/arm/ic-compiler-arm.cc",
      "src/ic/arm/stub-cache-arm.cc",
    ]
  } else if (v8_target_arch == "arm64") {
    sources += [
      "src/arm64/assembler-arm64.cc",
      "src/arm64/assembler-arm64.h",
      "src/arm64/assembler-arm64-inl.h",
      "src/arm64/builtins-arm64.cc",
      "src/arm64/codegen-arm64.cc",
      "src/arm64/codegen-arm64.h",
      "src/arm64/code-stubs-arm64.cc",
      "src/arm64/code-stubs-arm64.h",
      "src/arm64/constants-arm64.h",
      "src/arm64/cpu-arm64.cc",
      "src/arm64/debug-arm64.cc",
      "src/arm64/decoder-arm64.cc",
      "src/arm64/decoder-arm64.h",
      "src/arm64/decoder-arm64-inl.h",
      "src/arm64/deoptimizer-arm64.cc",
      "src/arm64/disasm-arm64.cc",
      "src/arm64/disasm-arm64.h",
      "src/arm64/frames-arm64.cc",
      "src/arm64/frames-arm64.h",
      "src/arm64/full-codegen-arm64.cc",
      "src/arm64/instructions-arm64.cc",
      "src/arm64/instructions-arm64.h",
      "src/arm64/instrument-arm64.cc",
      "src/arm64/instrument-arm64.h",
      "src/arm64/interface-descriptors-arm64.cc",
      "src/arm64/interface-descriptors-arm64.h",
      "src/arm64/lithium-arm64.cc",
      "src/arm64/lithium-arm64.h",
      "src/arm64/lithium-codegen-arm64.cc",
      "src/arm64/lithium-codegen-arm64.h",
      "src/arm64/lithium-gap-resolver-arm64.cc",
      "src/arm64/lithium-gap-resolver-arm64.h",
      "src/arm64/macro-assembler-arm64.cc",
      "src/arm64/macro-assembler-arm64.h",
      "src/arm64/macro-assembler-arm64-inl.h",
      "src/arm64/regexp-macro-assembler-arm64.cc",
      "src/arm64/regexp-macro-assembler-arm64.h",
      "src/arm64/simulator-arm64.cc",
      "src/arm64/simulator-arm64.h",
      "src/arm64/utils-arm64.cc",
      "src/arm64/utils-arm64.h",
      "src/compiler/arm64/code-generator-arm64.cc",
      "src/compiler/arm64/instruction-codes-arm64.h",
      "src/compiler/arm64/instruction-selector-arm64.cc",
      "src/compiler/arm64/linkage-arm64.cc",
      "src/ic/arm64/access-compiler-arm64.cc",
      "src/ic/arm64/handler-compiler-arm64.cc",
      "src/ic/arm64/ic-arm64.cc",
      "src/ic/arm64/ic-compiler-arm64.cc",
      "src/ic/arm64/stub-cache-arm64.cc",
    ]
  } else if (v8_target_arch == "mipsel") {
    sources += [
      "src/mips/assembler-mips.cc",
      "src/mips/assembler-mips.h",
      "src/mips/assembler-mips-inl.h",
      "src/mips/builtins-mips.cc",
      "src/mips/codegen-mips.cc",
      "src/mips/codegen-mips.h",
      "src/mips/code-stubs-mips.cc",
      "src/mips/code-stubs-mips.h",
      "src/mips/constants-mips.cc",
      "src/mips/constants-mips.h",
      "src/mips/cpu-mips.cc",
      "src/mips/debug-mips.cc",
      "src/mips/deoptimizer-mips.cc",
      "src/mips/disasm-mips.cc",
      "src/mips/frames-mips.cc",
      "src/mips/frames-mips.h",
      "src/mips/full-codegen-mips.cc",
      "src/mips/interface-descriptors-mips.cc",
      "src/mips/lithium-codegen-mips.cc",
      "src/mips/lithium-codegen-mips.h",
      "src/mips/lithium-gap-resolver-mips.cc",
      "src/mips/lithium-gap-resolver-mips.h",
      "src/mips/lithium-mips.cc",
      "src/mips/lithium-mips.h",
      "src/mips/macro-assembler-mips.cc",
      "src/mips/macro-assembler-mips.h",
      "src/mips/regexp-macro-assembler-mips.cc",
      "src/mips/regexp-macro-assembler-mips.h",
      "src/mips/simulator-mips.cc",
      "src/mips/simulator-mips.h",
      "src/compiler/mips/code-generator-mips.cc",
      "src/compiler/mips/instruction-codes-mips.h",
      "src/compiler/mips/instruction-selector-mips.cc",
      "src/compiler/mips/linkage-mips.cc",
      "src/ic/mips/access-compiler-mips.cc",
      "src/ic/mips/handler-compiler-mips.cc",
      "src/ic/mips/ic-mips.cc",
      "src/ic/mips/ic-compiler-mips.cc",
      "src/ic/mips/stub-cache-mips.cc",
    ]
  } else if (v8_target_arch == "mips64el") {
    sources += [
      "src/mips64/assembler-mips64.cc",
      "src/mips64/assembler-mips64.h",
      "src/mips64/assembler-mips64-inl.h",
      "src/mips64/builtins-mips64.cc",
      "src/mips64/codegen-mips64.cc",
      "src/mips64/codegen-mips64.h",
      "src/mips64/code-stubs-mips64.cc",
      "src/mips64/code-stubs-mips64.h",
      "src/mips64/constants-mips64.cc",
      "src/mips64/constants-mips64.h",
      "src/mips64/cpu-mips64.cc",
      "src/mips64/debug-mips64.cc",
      "src/mips64/deoptimizer-mips64.cc",
      "src/mips64/disasm-mips64.cc",
      "src/mips64/frames-mips64.cc",
      "src/mips64/frames-mips64.h",
      "src/mips64/full-codegen-mips64.cc",
      "src/mips64/interface-descriptors-mips64.cc",
      "src/mips64/lithium-codegen-mips64.cc",
      "src/mips64/lithium-codegen-mips64.h",
      "src/mips64/lithium-gap-resolver-mips64.cc",
      "src/mips64/lithium-gap-resolver-mips64.h",
      "src/mips64/lithium-mips64.cc",
      "src/mips64/lithium-mips64.h",
      "src/mips64/macro-assembler-mips64.cc",
      "src/mips64/macro-assembler-mips64.h",
      "src/mips64/regexp-macro-assembler-mips64.cc",
      "src/mips64/regexp-macro-assembler-mips64.h",
      "src/mips64/simulator-mips64.cc",
      "src/mips64/simulator-mips64.h",
      "src/ic/mips64/access-compiler-mips64.cc",
      "src/ic/mips64/handler-compiler-mips64.cc",
      "src/ic/mips64/ic-mips64.cc",
      "src/ic/mips64/ic-compiler-mips64.cc",
      "src/ic/mips64/stub-cache-mips64.cc",
    ]
  }

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [ "//build/config/compiler:no_chromium_code" ]
  configs += [
    ":internal_config",
    ":features",
    ":toolchain",
  ]

  if (!is_debug) {
    configs -= [ "//build/config/compiler:optimize" ]
    configs += [ "//build/config/compiler:optimize_max" ]
  }

  defines = []
  deps = [
    ":v8_libbase",
  ]

  if (is_win) {
    # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
    cflags = [ "/wd4267" ]
  }

  if (v8_enable_i18n_support) {
    deps += [ "//third_party/icu" ]
    if (is_win) {
      deps += [ "//third_party/icu:icudata" ]
    }

    # TODO(jochen): Add support for icu_use_data_file_flag
    defines += [ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE" ]
  } else {
    sources -= [
      "src/i18n.cc",
      "src/i18n.h",
    ]
  }

  if (v8_postmortem_support) {
    sources += [ "$target_gen_dir/debug-support.cc" ]
    deps += [ ":postmortem-metadata" ]
  }
}

source_set("v8_libbase") {
  visibility = [ ":*" ]  # Only targets in this file can depend on this.

  sources = [
    "src/base/adapters.h",
    "src/base/atomicops.h",
    "src/base/atomicops_internals_arm64_gcc.h",
    "src/base/atomicops_internals_arm_gcc.h",
    "src/base/atomicops_internals_atomicword_compat.h",
    "src/base/atomicops_internals_mac.h",
    "src/base/atomicops_internals_mips_gcc.h",
    "src/base/atomicops_internals_mips64_gcc.h",
    "src/base/atomicops_internals_portable.h",
    "src/base/atomicops_internals_tsan.h",
    "src/base/atomicops_internals_x86_gcc.cc",
    "src/base/atomicops_internals_x86_gcc.h",
    "src/base/atomicops_internals_x86_msvc.h",
    "src/base/bits.cc",
    "src/base/bits.h",
    "src/base/build_config.h",
    "src/base/cpu.cc",
    "src/base/cpu.h",
    "src/base/division-by-constant.cc",
    "src/base/division-by-constant.h",
    "src/base/flags.h",
    "src/base/functional.cc",
    "src/base/functional.h",
    "src/base/iterator.h",
    "src/base/lazy-instance.h",
    "src/base/logging.cc",
    "src/base/logging.h",
    "src/base/macros.h",
    "src/base/once.cc",
    "src/base/once.h",
    "src/base/platform/elapsed-timer.h",
    "src/base/platform/time.cc",
    "src/base/platform/time.h",
    "src/base/platform/condition-variable.cc",
    "src/base/platform/condition-variable.h",
    "src/base/platform/mutex.cc",
    "src/base/platform/mutex.h",
    "src/base/platform/platform.h",
    "src/base/platform/semaphore.cc",
    "src/base/platform/semaphore.h",
    "src/base/safe_conversions.h",
    "src/base/safe_conversions_impl.h",
    "src/base/safe_math.h",
    "src/base/safe_math_impl.h",
    "src/base/sys-info.cc",
    "src/base/sys-info.h",
    "src/base/utils/random-number-generator.cc",
    "src/base/utils/random-number-generator.h",
  ]

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [ "//build/config/compiler:no_chromium_code" ]
  configs += [
    ":internal_config_base",
    ":features",
    ":toolchain",
  ]

  if (!is_debug) {
    configs -= [ "//build/config/compiler:optimize" ]
    configs += [ "//build/config/compiler:optimize_max" ]
  }

  defines = []

  if (is_posix) {
    sources += [ "src/base/platform/platform-posix.cc" ]
  }

  if (is_linux) {
    sources += [ "src/base/platform/platform-linux.cc" ]

    libs = [ "dl", "rt" ]
  } else if (is_android) {
    defines += [ "CAN_USE_VFP_INSTRUCTIONS" ]

    if (current_toolchain == host_toolchain) {
      libs = [ "dl", "rt" ]
      if (host_os == "mac") {
        sources += [ "src/base/platform/platform-macos.cc" ]
      } else {
        sources += [ "src/base/platform/platform-linux.cc" ]
      }
    } else {
      sources += [ "src/base/platform/platform-linux.cc" ]
    }
  } else if (is_mac) {
    sources += [ "src/base/platform/platform-macos.cc" ]
  } else if (is_win) {
    # TODO(jochen): Add support for cygwin.
    sources += [
      "src/base/platform/platform-win32.cc",
      "src/base/win32-headers.h",
    ]

    defines += [ "_CRT_RAND_S" ]  # for rand_s()

    libs = [
      "winmm.lib",
      "ws2_32.lib",
    ]
  }

  # TODO(jochen): Add support for qnx, freebsd, openbsd, netbsd, and solaris.
}

source_set("v8_libplatform") {
  sources = [
    "include/libplatform/libplatform.h",
    "src/libplatform/default-platform.cc",
    "src/libplatform/default-platform.h",
    "src/libplatform/task-queue.cc",
    "src/libplatform/task-queue.h",
    "src/libplatform/worker-thread.cc",
    "src/libplatform/worker-thread.h",
  ]

  configs -= [ "//build/config/compiler:chromium_code" ]
  configs += [ "//build/config/compiler:no_chromium_code" ]
  configs += [
    ":internal_config_base",
    ":features",
    ":toolchain",
  ]

  if (!is_debug) {
    configs -= [ "//build/config/compiler:optimize" ]
    configs += [ "//build/config/compiler:optimize_max" ]
  }

  deps = [
    ":v8_libbase",
  ]
}

###############################################################################
# Executables
#

if (current_toolchain == snapshot_toolchain) {
  executable("mksnapshot") {
    visibility = [ ":*" ]  # Only targets in this file can depend on this.

    sources = [
      "src/snapshot/mksnapshot.cc",
    ]

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]
    configs += [
      ":internal_config",
      ":features",
      ":toolchain",
    ]

    deps = [
      ":v8_base",
      ":v8_libplatform",
      ":v8_nosnapshot",
      "//build/config/sanitizers:deps",
    ]
  }
}

###############################################################################
# Public targets
#

if (is_component_build) {
  component("v8") {
    sources = [
      "src/v8dll-main.cc",
    ]

    if (v8_use_snapshot && v8_use_external_startup_data) {
      deps = [
        ":v8_base",
      ]
      public_deps = [
        ":v8_external_snapshot",
      ]
    } else if (v8_use_snapshot) {
      deps = [
        ":v8_base",
      ]
      # v8_snapshot should be public so downstream targets can declare the
      # snapshot file as their input.
      public_deps = [
        ":v8_snapshot",
      ]
    } else {
      assert(!v8_use_external_startup_data)
      deps = [
        ":v8_base",
        ":v8_nosnapshot",
      ]
    }

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]
    configs += [
      ":internal_config",
      ":features",
      ":toolchain",
    ]

    public_configs = [ ":external_config" ]

    libs = []
    if (is_android && current_toolchain != host_toolchain) {
      libs += [ "log" ]
    }
  }
} else {
  group("v8") {
    if (v8_use_snapshot && v8_use_external_startup_data) {
      deps = [
        ":v8_base",
        ":v8_external_snapshot",
      ]
    } else if (v8_use_snapshot) {
      deps = [
        ":v8_base",
      ]
      public_deps = [
        ":v8_snapshot",
      ]
    } else {
      assert(!v8_use_external_startup_data)
      deps = [
        ":v8_base",
        ":v8_nosnapshot",
      ]
    }

    public_configs = [ ":external_config" ]
  }
}

if ((current_toolchain == host_toolchain && v8_toolset_for_d8 == "host") ||
    (current_toolchain != host_toolchain && v8_toolset_for_d8 == "target")) {
  executable("d8") {
    sources = [
      "src/d8.cc",
      "src/d8.h",
    ]

    configs -= [ "//build/config/compiler:chromium_code" ]
    configs += [ "//build/config/compiler:no_chromium_code" ]
    configs += [
      # Note: don't use :internal_config here because this target will get
      # the :external_config applied to it by virtue of depending on :v8, and
      # you can't have both applied to the same target.
      ":internal_config_base",
      ":features",
      ":toolchain",
    ]

    deps = [
      ":d8_js2c",
      ":v8",
      ":v8_libplatform",
      "//build/config/sanitizers:deps",
    ]

    # TODO(jochen): Add support for readline and vtunejit.

    if (is_posix) {
      sources += [ "src/d8-posix.cc" ]
    } else if (is_win) {
      sources += [ "src/d8-windows.cc" ]
    }

    if (!is_component_build) {
      sources += [
        "src/d8-debug.cc",
        "src/d8-debug.h",
        "$target_gen_dir/d8-js.cc",
      ]
    }
    if (v8_enable_i18n_support) {
      deps += [ "//third_party/icu" ]
    }
  }
}
node-v4.2.6/deps/v8/ChangeLog000644 000766 000024 00001113111 12650222324 016005 0ustar00iojsstaff000000 000000 2015-07-08: Version 4.5.103

        Performance and stability improvements on all platforms.


2015-07-08: Version 4.5.102

        Performance and stability improvements on all platforms.


2015-07-07: Version 4.5.101

        Move compatible receiver check from CompileHandler to UpdateCaches
        (Chromium issue 505374).

        Performance and stability improvements on all platforms.


2015-07-07: Version 4.5.100

        Performance and stability improvements on all platforms.


2015-07-07: Version 4.5.99

        unicode-decoder: fix out-of-band write in utf16 (issue 4274).

        Performance and stability improvements on all platforms.


2015-07-06: Version 4.5.98

        Performance and stability improvements on all platforms.


2015-07-04: Version 4.5.97

        Performance and stability improvements on all platforms.


2015-07-03: Version 4.5.96

        Performance and stability improvements on all platforms.


2015-07-03: Version 4.5.95

        Performance and stability improvements on all platforms.


2015-07-02: Version 4.5.94

        Performance and stability improvements on all platforms.


2015-07-02: Version 4.5.93

        Include Harmony Array/TypedArray methods unconditionally (Chromium issue
        504629).

        Performance and stability improvements on all platforms.


2015-07-02: Version 4.5.92

        Performance and stability improvements on all platforms.


2015-07-01: Version 4.5.91

        Performance and stability improvements on all platforms.


2015-07-01: Version 4.5.90

        Performance and stability improvements on all platforms.


2015-07-01: Version 4.5.89

        Performance and stability improvements on all platforms.


2015-06-30: Version 4.5.88

        Performance and stability improvements on all platforms.


2015-06-30: Version 4.5.87

        Performance and stability improvements on all platforms.


2015-06-30: Version 4.5.86

        Ensure mjsunit tests use dashes not underscores in flags directives
        (Chromium issue 505228).

        Performance and stability improvements on all platforms.


2015-06-29: Version 4.5.85

        Fix flag convention in handle count tests and comment (Chromium issue
        505228).

        Performance and stability improvements on all platforms.


2015-06-29: Version 4.5.84

        Performance and stability improvements on all platforms.


2015-06-27: Version 4.5.83

        Performance and stability improvements on all platforms.


2015-06-26: Version 4.5.82

        Performance and stability improvements on all platforms.


2015-06-26: Version 4.5.81

        Remove obsolete options in ScriptCompiler::CompileOptions (Chromium
        issue 399580).

        Performance and stability improvements on all platforms.


2015-06-25: Version 4.5.80

        Performance and stability improvements on all platforms.


2015-06-25: Version 4.5.79

        Performance and stability improvements on all platforms.


2015-06-25: Version 4.5.78

        Serializer: clear next link in weak cells (Chromium issue 503552).

        Performance and stability improvements on all platforms.


2015-06-24: Version 4.5.77

        Performance and stability improvements on all platforms.


2015-06-24: Version 4.5.76

        Performance and stability improvements on all platforms.


2015-06-24: Version 4.5.75

        Date() should not depend on Date.prototype.toString (issue 4225).

        Performance and stability improvements on all platforms.


2015-06-23: Version 4.5.74

        Expose Map/Set methods through the API (issue 3340).

        [turbofan] NaN is never truish (issue 4207).

        Performance and stability improvements on all platforms.


2015-06-23: Version 4.5.73

        Re-ship Harmony Array/TypedArray methods (issue 3578).

        Performance and stability improvements on all platforms.


2015-06-23: Version 4.5.72

        Performance and stability improvements on all platforms.


2015-06-23: Version 4.5.71

        Performance and stability improvements on all platforms.


2015-06-20: Version 4.5.70

        Ship Harmony Array/TypedArray methods (issue 3578).

        Performance and stability improvements on all platforms.


2015-06-20: Version 4.5.69

        Ship arrow functions (issue 2700).

        Performance and stability improvements on all platforms.


2015-06-19: Version 4.5.68

        Performance and stability improvements on all platforms.


2015-06-19: Version 4.5.67

        Performance and stability improvements on all platforms.


2015-06-19: Version 4.5.66

        Ship arrow functions (issue 2700).

        Performance and stability improvements on all platforms.


2015-06-18: Version 4.5.65

        Performance and stability improvements on all platforms.


2015-06-18: Version 4.5.64

        Performance and stability improvements on all platforms.


2015-06-18: Version 4.5.63

        Performance and stability improvements on all platforms.


2015-06-17: Version 4.5.62

        Hydrogen object literals: always initialize in-object properties
        (Chromium issue 500497).

        Performance and stability improvements on all platforms.


2015-06-17: Version 4.5.61

        Add %TypedArray% to proto chain (issue 4085).

        Performance and stability improvements on all platforms.


2015-06-17: Version 4.5.60

        Performance and stability improvements on all platforms.


2015-06-17: Version 4.5.59

        [crankshaft] Fix wrong bailout points in for-in loop body (Chromium
        issue 500435).

        Performance and stability improvements on all platforms.


2015-06-16: Version 4.5.58

        Performance and stability improvements on all platforms.


2015-06-16: Version 4.5.57

        Inline code generation for %_IsTypedArray (issue 4085).

        Allow TypedArrays to be initialized with iterables (issue 4090).

        Performance and stability improvements on all platforms.


2015-06-15: Version 4.5.56

        Performance and stability improvements on all platforms.


2015-06-15: Version 4.5.55

        Performance and stability improvements on all platforms.


2015-06-14: Version 4.5.54

        Performance and stability improvements on all platforms.


2015-06-13: Version 4.5.53

        Performance and stability improvements on all platforms.


2015-06-12: Version 4.5.52

        Map::TryUpdate() must be in sync with Map::Update() (issue 4173).

        Add ToObject call in Array.prototype.sort (issue 4125).

        In Array.of and Array.from, fall back to DefineOwnProperty (issue 4168).

        Performance and stability improvements on all platforms.


2015-06-12: Version 4.5.51

        Performance and stability improvements on all platforms.


2015-06-11: Version 4.5.50

        Performance and stability improvements on all platforms.


2015-06-11: Version 4.5.49

        Performance and stability improvements on all platforms.


2015-06-11: Version 4.5.48

        Support rest parameters in arrow functions (issue 2700).

        Performance and stability improvements on all platforms.


2015-06-10: Version 4.5.47

        Implement %TypedArray%.prototype.slice (issue 3578).

        Performance and stability improvements on all platforms.


2015-06-09: Version 4.5.46

        Stage ES6 arrow functions (issue 2700).

        Performance and stability improvements on all platforms.


2015-06-09: Version 4.5.45

        Performance and stability improvements on all platforms.


2015-06-09: Version 4.5.44

        Performance and stability improvements on all platforms.


2015-06-08: Version 4.5.43

        [for-in] Make ForInNext and ForInFilter deal properly with exceptions
        (Chromium issue 496331).

        Performance and stability improvements on all platforms.


2015-06-08: Version 4.5.42

        Performance and stability improvements on all platforms.


2015-06-06: Version 4.5.41

        Performance and stability improvements on all platforms.


2015-06-05: Version 4.5.40

        Performance and stability improvements on all platforms.


2015-06-05: Version 4.5.39

        Stage ES6 Array and TypedArray methods (issue 3578).

        Performance and stability improvements on all platforms.


2015-06-05: Version 4.5.38

        Implement %TypedArray%.prototype.{reduce,reduceRight} (issue 3578).

        Add support for Embedded Constant Pools for PPC and Arm (Chromium issue
        478811).

        Performance and stability improvements on all platforms.


2015-06-04: Version 4.5.37

        Performance and stability improvements on all platforms.


2015-06-04: Version 4.5.36

        Performance and stability improvements on all platforms.


2015-06-04: Version 4.5.35

        Flatten the Arrays returned and consumed by the v8::Map API (Chromium
        issue 478263).

        Performance and stability improvements on all platforms.


2015-06-03: Version 4.5.34

        Also allocate small typed arrays on heap when initialized from an array-
        like (issue 3996).

        Implement %TypedArray%.prototype.{reduce,reduceRight} (issue 3578).

        Performance and stability improvements on all platforms.


2015-06-03: Version 4.5.33

        Add support for Embedded Constant Pools for PPC and Arm (Chromium issue
        478811).

        Implement %TypedArray%.prototype.{toString,toLocaleString,join} (issue
        3578).

        Performance and stability improvements on all platforms.


2015-06-03: Version 4.5.32

        Performance and stability improvements on all platforms.


2015-06-02: Version 4.5.31

        Performance and stability improvements on all platforms.


2015-06-02: Version 4.5.30

        Performance and stability improvements on all platforms.


2015-06-01: Version 4.5.29

        Reland "Re-enable on-heap typed array allocation" (issue 3996).

        Performance and stability improvements on all platforms.


2015-06-01: Version 4.5.28

        Re-enable on-heap typed array allocation (issue 3996).

        Also expose DefineOwnProperty (Chromium issue 475206).

        Performance and stability improvements on all platforms.


2015-06-01: Version 4.5.27

        Performance and stability improvements on all platforms.


2015-05-31: Version 4.5.26

        Performance and stability improvements on all platforms.


2015-05-30: Version 4.5.25

        Performance and stability improvements on all platforms.


2015-05-29: Version 4.5.24

        Debugger: consider try-finally scopes not catching wrt debug events
        (Chromium issue 492522).

        Performance and stability improvements on all platforms.


2015-05-29: Version 4.5.23

        Performance and stability improvements on all platforms.


2015-05-29: Version 4.5.22

        Do not eagerly convert exception to string when creating a message
        object (Chromium issue 490680).

        Performance and stability improvements on all platforms.


2015-05-28: Version 4.5.21

        Performance and stability improvements on all platforms.


2015-05-28: Version 4.5.20

        Introduce v8::Object::CreateDataProperty (Chromium issue 475206).

        Performance and stability improvements on all platforms.


2015-05-27: Version 4.5.19

        Performance and stability improvements on all platforms.


2015-05-27: Version 4.5.18

        Add {Map,Set}::FromArray to the API (issue 3340).

        Add {Map,Set}::AsArray to the API (issue 3340).

        Add basic API support for Map & Set (issue 3340).

        Performance and stability improvements on all platforms.


2015-05-26: Version 4.5.17

        Correctly hook up materialized receiver into the evaluation context
        chain (Chromium issue 491943).

        Implement bookmarks for ExternalStreamingStream (Chromium issue 470930).

        Performance and stability improvements on all platforms.


2015-05-26: Version 4.5.16

        Performance and stability improvements on all platforms.


2015-05-26: Version 4.5.15

        Performance and stability improvements on all platforms.


2015-05-23: Version 4.5.14

        Performance and stability improvements on all platforms.


2015-05-22: Version 4.5.13

        Remove v8::Private.

        Performance and stability improvements on all platforms.


2015-05-22: Version 4.5.12

        Performance and stability improvements on all platforms.


2015-05-22: Version 4.5.11

        Performance and stability improvements on all platforms.


2015-05-21: Version 4.5.10

        Re-land %TypedArray%.prototype.{map,filter,some} (issue 3578).

        Performance and stability improvements on all platforms.


2015-05-21: Version 4.5.9

        Performance and stability improvements on all platforms.


2015-05-20: Version 4.5.8

        Performance and stability improvements on all platforms.


2015-05-20: Version 4.5.7

        Implement %TypedArray%.{lastI,i}ndexOf (issue 3578).

        Implement %TypedArray%.prototype.sort (issue 3578).

        Implement %TypedArray%.reverse (issue 3578).

        Implement %TypedArray%.prototype.{map,filter,some,reduce,reduceRight}
        (issue 3578).

        Fix has_pending_exception logic in API's Array::CloneElementAt (issue
        4103).

        Adding api to get last gc object statistics for chrome://tracing
        (Chromium issue 476013).

        Fix harmless HGraph verification failure after hoisting inlined bounds
        checks (Chromium issue 487608).

        Performance and stability improvements on all platforms.


2015-05-20: Version 4.5.6

        Add TypedArray.from method (issue 3578).

        Performance and stability improvements on all platforms.


2015-05-19: Version 4.5.5

        ARM64: Propagate notification about aborted compilation from
        RegExpEngine to MacroAssembler (Chromium issue 489290).

        Performance and stability improvements on all platforms.


2015-05-18: Version 4.5.4

        Performance and stability improvements on all platforms.


2015-05-18: Version 4.5.3

        Performance and stability improvements on all platforms.


2015-05-17: Version 4.5.2

        Performance and stability improvements on all platforms.


2015-05-16: Version 4.5.1

        Test that TypedArray methods don't read length (issue 3578).

        Implement %TypedArray%.{fill,find,findIndex} (issue 3578).

        TypedArray.prototype.copyWithin method (issue 3578).

        Provide accessor for object internal properties that doesn't require
        debugger to be active (Chromium issue 481845).

        Don't create debug context if debug listener is not set (Chromium issue
        482290).

        Performance and stability improvements on all platforms.


2015-05-13: Version 4.4.65

        Deprecate Isolate::New.

        Factor out core of Array.forEach and .every, for use in TypedArrays
        (issue 3578).

        Performance and stability improvements on all platforms.


2015-05-12: Version 4.4.64

        Performance and stability improvements on all platforms.


2015-05-11: Version 4.4.63

        Let Runtime_GrowArrayElements accept non-Smi numbers as |key| (Chromium
        issue 485410).

        Make one copy for all TypedArray methods (issue 4085).

        Performance and stability improvements on all platforms.


2015-05-09: Version 4.4.62

        [turbofan] Fix handling of OsrLoopEntry in ControlReducer::ConnectNTL()
        (Chromium issue 485908).

        Performance and stability improvements on all platforms.


2015-05-08: Version 4.4.61

        Performance and stability improvements on all platforms.


2015-05-08: Version 4.4.60

        Performance and stability improvements on all platforms.


2015-05-08: Version 4.4.59

        Performance and stability improvements on all platforms.


2015-05-07: Version 4.4.58

        TypedArray.prototype.every method (issue 3578).

        [V8] Reland https://codereview.chromium.org/1121833003/ (Chromium issue
        480652).

        Performance and stability improvements on all platforms.


2015-05-07: Version 4.4.57

        Performance and stability improvements on all platforms.


2015-05-06: Version 4.4.56

        Shard v8_base.lib on Windows to avoid 2G .lib limit (Chromium issue
        485155).

        Implement a 'trial parse' step, that will abort pre-parsing excessively
        long and trivial functions, so that they can be eagerly compiled after
        all. This essentially allows the parser to renege on its earlier
        decision to lazy-parse, if additional information suggests it was a bad
        decision (Chromium issue 470930).

        Performance and stability improvements on all platforms.


2015-05-06: Version 4.4.55

        Handle the case when derived constructor is [[Call]]ed with 0 args
        (Chromium issue 474783).

        freed_nodes in global-handles should be addititive (Chromium issues
        479796, 484671).

        [V8] Reland https://codereview.chromium.org/1100993003/ (Chromium issue
        480652).

        [es6] When comparing two symbols we may need to throw a TypeError (issue
        4073).

        Performance and stability improvements on all platforms.


2015-05-06: Version 4.4.54

        Performance and stability improvements on all platforms.


2015-05-05: Version 4.4.53

        Performance and stability improvements on all platforms.


2015-05-05: Version 4.4.52

        Performance and stability improvements on all platforms.


2015-05-04: Version 4.4.51

        Performance and stability improvements on all platforms.


2015-05-04: Version 4.4.50

        Performance and stability improvements on all platforms.


2015-05-01: Version 4.4.49

        Performance and stability improvements on all platforms.


2015-05-01: Version 4.4.48

        [V8] Use previous token location as EOS token location (Chromium issue
        480652).

        Implement kToBeExecutedOnceCodeAge (Chromium issue 470930).

        Performance and stability improvements on all platforms.


2015-04-30: Version 4.4.47

        Performance and stability improvements on all platforms.


2015-04-30: Version 4.4.46

        Performance and stability improvements on all platforms.


2015-04-29: Version 4.4.45

        Performance and stability improvements on all platforms.


2015-04-29: Version 4.4.44

        Pass ArrayBuffer::Allocator via Isolate::CreateParams.

        Fix unobservable constructor replacement on prototype maps (Chromium
        issue 478522).

        Performance and stability improvements on all platforms.


2015-04-29: Version 4.4.43

        Performance and stability improvements on all platforms.


2015-04-28: Version 4.4.42

        MIPS: Fix FP load/store with large offsets from base register (Chromium
        issue 481519).

        Extending v8::GetHeapStatistics to return total available size (Chromium
        issue 476013).

        Performance and stability improvements on all platforms.


2015-04-28: Version 4.4.41

        Performance and stability improvements on all platforms.


2015-04-28: Version 4.4.40

        Do more to avoid last-resort stop-the-world GC (Chromium issue 481433).

        Performance and stability improvements on all platforms.


2015-04-27: Version 4.4.39

        Performance and stability improvements on all platforms.


2015-04-27: Version 4.4.38

        Performance and stability improvements on all platforms.


2015-04-25: Version 4.4.37

        Performance and stability improvements on all platforms.


2015-04-24: Version 4.4.36

        Performance and stability improvements on all platforms.


2015-04-24: Version 4.4.35

        Performance and stability improvements on all platforms.


2015-04-24: Version 4.4.34

        Performance and stability improvements on all platforms.


2015-04-23: Version 4.4.33

        Performance and stability improvements on all platforms.


2015-04-23: Version 4.4.32

        Performance and stability improvements on all platforms.


2015-04-23: Version 4.4.31

        Performance and stability improvements on all platforms.


2015-04-22: Version 4.4.30

        Performance and stability improvements on all platforms.


2015-04-22: Version 4.4.29

        Performance and stability improvements on all platforms.


2015-04-21: Version 4.4.28

        Performance and stability improvements on all platforms.


2015-04-21: Version 4.4.27

        Performance and stability improvements on all platforms.


2015-04-20: Version 4.4.26

        Allow for accessing an ArrayBuffer contents without externalizing it.

        Remove support for externally backed elements from the API (issue 3996).

        Deprecate 3-args ResourceConstraints::ConfigureDefaults.

        Indicate that low-memory-notificatin triggered GCs are "forced".

        Adding missing V8_EXPORT flag in SpaceStatistics class in v8.h (Chromium
        issues 466141, 476013).

        Performance and stability improvements on all platforms.


2015-04-20: Version 4.4.25

        Turn off SupportsFlexibleFloorAndRound for Arm64 due to a bug (Chromium
        issue 476477).

        Adding V8 api to get memory statistics of spaces in V8::Heap (Chromium
        issues 466141, 476013).

        Performance and stability improvements on all platforms.


2015-04-17: Version 4.4.24

        Performance and stability improvements on all platforms.


2015-04-17: Version 4.4.23

        Don't crash when reporting an access check failure for a detached global
        proxy (Chromium issue 475884).

        Use smaller heap growing factor in idle notification to start
        incremental marking when there is idle time >16ms (Chromium issue
        477323).

        Performance and stability improvements on all platforms.


2015-04-16: Version 4.4.22

        Reduce regexp compiler stack size when not optimizing regexps (Chromium
        issue 475705).

        Performance and stability improvements on all platforms.


2015-04-15: Version 4.4.21

        Remove support for specifying the number of available threads.

        When converting Maybe and MaybeLocal values with a check, always check.

        Performance and stability improvements on all platforms.


2015-04-15: Version 4.4.20

        Performance and stability improvements on all platforms.


2015-04-15: Version 4.4.19

        Reland "Remove support for thread-based recompilation" (issue 3608).

        Performance and stability improvements on all platforms.


2015-04-14: Version 4.4.18

        Reland "Remove support for thread-based recompilation" (issue 3608).

        Performance and stability improvements on all platforms.


2015-04-14: Version 4.4.17

        Performance and stability improvements on all platforms.


2015-04-13: Version 4.4.16

        Expose ArrayBufferView::HasBuffer (issue 3996).

        Performance and stability improvements on all platforms.


2015-04-13: Version 4.4.15

        Performance and stability improvements on all platforms.


2015-04-12: Version 4.4.14

        Performance and stability improvements on all platforms.


2015-04-12: Version 4.4.13

        Performance and stability improvements on all platforms.


2015-04-10: Version 4.4.12

        Performance and stability improvements on all platforms.


2015-04-10: Version 4.4.11

        Performance and stability improvements on all platforms.


2015-04-10: Version 4.4.10

        Don't #define snprintf in VS2015 - it's illegal and unneeded (Chromium
        issue 440500).

        Performance and stability improvements on all platforms.


2015-04-09: Version 4.4.9

        Performance and stability improvements on all platforms.


2015-04-09: Version 4.4.8

        Performance and stability improvements on all platforms.


2015-04-08: Version 4.4.7

        Make GetDebugContext a bit more robust (Chromium issue 474538).

        Performance and stability improvements on all platforms.


2015-04-08: Version 4.4.6

        Performance and stability improvements on all platforms.


2015-04-08: Version 4.4.5

        More robust when allocation fails during compaction (Chromium issue
        473307).

        MIPS: JSEntryTrampoline: check for stack space before pushing arguments
        (Chromium issue 469768).

        Performance and stability improvements on all platforms.


2015-04-07: Version 4.4.4

        Debugger: remove debug command API.

        Remove support for thread-based recompilation (issue 3608).

        JSEntryTrampoline: check for stack space before pushing arguments
        (Chromium issue 469768).

        Performance and stability improvements on all platforms.


2015-04-07: Version 4.4.3

        Performance and stability improvements on all platforms.


2015-04-06: Version 4.4.2

        Performance and stability improvements on all platforms.


2015-04-06: Version 4.4.1

        Support for typed arrays added to Heap::RightTrimFixedArray() (Chromium
        issue 472513).

        Expose an API on ArrayBufferView to copy out content w/o changing the
        buffer (issue 3996).

        Performance and stability improvements on all platforms.


2015-04-02: Version 4.3.66

        Reland: Fix JSON parser Handle leak (previous CL 1041483004) (issue
        3976, Chromium issue 472504).

        Turn off overapproximation of the weak closure again (issue 3862).

        Performance and stability improvements on all platforms.


2015-04-01: Version 4.3.65

        Performance and stability improvements on all platforms.


2015-04-01: Version 4.3.64

        Performance and stability improvements on all platforms.


2015-04-01: Version 4.3.63

        [V8] Don't ignore sourceURL comment in inline scripts in .stack (issue
        3920).

        Deprecate IdleNotification().

        Remove --harmony-numeric-literal flag.

        Performance and stability improvements on all platforms.


2015-03-31: Version 4.3.62

        Put newspace evacuation in an EvacuationScope (Chromium issue 471554).

        Fix libdl dependency on Android and remove librt hack (Chromium issue
        469973).

        Ensure that GC idle notifications either make progress or stop
        requesting more GCs (Chromium issue 470615).

        Layout descriptor must be trimmed when corresponding descriptors array
        is trimmed to stay in sync (Chromium issue 470804).

        Fix JSON parser Handle leak (issue 3976).

        Performance and stability improvements on all platforms.


2015-03-30: Version 4.3.61

        Performance and stability improvements on all platforms.


2015-03-28: Version 4.3.60

        Reland^2 "Filter invalid slots out from the SlotsBuffer after marking."
        (Chromium issues 454297, 470801).

        This fixes missing incremental write barrier issue when double fields
        unboxing is enabled (Chromium issue 469146).

        Performance and stability improvements on all platforms.


2015-03-27: Version 4.3.59

        Use a slot that is located on a heap page when removing invalid entries
        from the SlotsBuffer (Chromium issue 470801).

        Performance and stability improvements on all platforms.


2015-03-26: Version 4.3.58

        Return timestamp of the last recorded interval to the caller of
        HeapProfiler::GetHeapStats (Chromium issue 467222).

        Performance and stability improvements on all platforms.


2015-03-26: Version 4.3.57

        Reland [V8] Removed SourceLocationRestrict (Chromium issue 468781).

        Performance and stability improvements on all platforms.


2015-03-25: Version 4.3.56

        Remove v8::Isolate::ClearInterrupt.

        Performance and stability improvements on all platforms.


2015-03-25: Version 4.3.55

        Performance and stability improvements on all platforms.


2015-03-24: Version 4.3.54

        Do not assign positions to parser-generated desugarings (Chromium issue
        468661).

        Performance and stability improvements on all platforms.


2015-03-24: Version 4.3.53

        Filter invalid slots out from the SlotsBuffer after marking (Chromium
        issue 454297).

        Fix OOM bug 3976 (issue 3976).

        Performance and stability improvements on all platforms.


2015-03-24: Version 4.3.52

        Remove calls to IdleNotification().

        Save heap object tracking data in heap snapshot (Chromium issue 467222).

        Performance and stability improvements on all platforms.


2015-03-24: Version 4.3.51

        [V8] Removed SourceLocationRestrict (Chromium issue 468781).

        [turbofan] Fix control reducer bug with walking non-control edges during
        ConnectNTL phase (Chromium issue 469605).

        Performance and stability improvements on all platforms.


2015-03-23: Version 4.3.50

        Performance and stability improvements on all platforms.


2015-03-23: Version 4.3.49

        Ensure we don't overflow in BCE (Chromium issue 469148).

        [turbofan] Fix lowering of Math.max for integral inputs (Chromium issue
        468162).

        Use libdl to get symbols for backtraces.

        Performance and stability improvements on all platforms.


2015-03-19: Version 4.3.48

        Clarify what APIs return Maybe and MaybeLocal values (issue 3929).

        Introduce explicit constant for per Context debug data set by embedder
        (Chromium issue 466631).

        Adjust key behaviour for weak collections (issues 3970, 3971, Chromium
        issue 460083).

        Turn on overapproximation of the weak closure (issue 3862).

        Performance and stability improvements on all platforms.


2015-03-18: Version 4.3.47

        Performance and stability improvements on all platforms.


2015-03-17: Version 4.3.46

        Performance and stability improvements on all platforms.


2015-03-17: Version 4.3.45

        Performance and stability improvements on all platforms.


2015-03-17: Version 4.3.44

        Performance and stability improvements on all platforms.


2015-03-16: Version 4.3.43

        Bugfix in hydrogen GVN (Chromium issue 467481).

        Remove obsolete TakeHeapSnapshot method from API (Chromium issue
        465651).

        Beautify syntax error for unterminated argument list (Chromium issue
        339474).

        Performance and stability improvements on all platforms.


2015-03-16: Version 4.3.42

        Performance and stability improvements on all platforms.


2015-03-15: Version 4.3.41

        Performance and stability improvements on all platforms.


2015-03-14: Version 4.3.40

        Performance and stability improvements on all platforms.


2015-03-14: Version 4.3.39

        Performance and stability improvements on all platforms.


2015-03-14: Version 4.3.38

        Remove --harmony-scoping flag.

        Performance and stability improvements on all platforms.


2015-03-13: Version 4.3.37

        Implement TDZ in StoreIC for top-level lexicals (issue 3941).

        Turn on job-based optimizing compiler (issue 3608).

        Performance and stability improvements on all platforms.


2015-03-13: Version 4.3.36

        Performance and stability improvements on all platforms.


2015-03-12: Version 4.3.35

        Add Cast() for Int32 and Uint32 (Chromium issue 462402).

        Incorrect handling of HTransitionElementsKind in hydrogen check
        elimination phase fixed (Chromium issue 460917).

        Performance and stability improvements on all platforms.


2015-03-12: Version 4.3.34

        Performance and stability improvements on all platforms.


2015-03-12: Version 4.3.33

        Fix the toolchain used to build the snapshots in GN (Chromium issues
        395249, 465456).

        Performance and stability improvements on all platforms.


2015-03-11: Version 4.3.32

        Reland of Remove slots that point to unboxed doubles from the
        StoreBuffer/SlotsBuffer (Chromium issues 454297, 465273).

        Performance and stability improvements on all platforms.


2015-03-11: Version 4.3.31

        Performance and stability improvements on all platforms.


2015-03-11: Version 4.3.30

        Remove uid and title from HeapSnapshot (Chromium issue 465651).

        Remove deprecated CpuProfiler methods.

        [turbofan] Fix --turbo-osr for OSRing into inner loop inside for-in
        (Chromium issue 462775).

        Performance and stability improvements on all platforms.


2015-03-10: Version 4.3.29

        Performance and stability improvements on all platforms.


2015-03-10: Version 4.3.28

        Performance and stability improvements on all platforms.


2015-03-10: Version 4.3.27

        Performance and stability improvements on all platforms.


2015-03-07: Version 4.3.26

        Remove slots that point to unboxed doubles from the
        StoreBuffer/SlotsBuffer (Chromium issue 454297).

        Performance and stability improvements on all platforms.


2015-03-06: Version 4.3.25

        Performance and stability improvements on all platforms.


2015-03-06: Version 4.3.24

        convert more things to maybe (issue 3929).

        Performance and stability improvements on all platforms.


2015-03-05: Version 4.3.23

        [V8] Use Function.name for stack frames in v8::StackTrace (Chromium
        issue 17356).

        Allow passing sourceMapUrl when compiling scripts (Chromium issue
        462572).

        convert compile functions to use maybe (issue 3929).

        Performance and stability improvements on all platforms.


2015-03-05: Version 4.3.22

        give UniquePersistent full move semantics (issue 3669).

        Performance and stability improvements on all platforms.


2015-03-05: Version 4.3.21

        Performance and stability improvements on all platforms.


2015-03-04: Version 4.3.20

        convert remaining object functions to maybes (issue 3929).

        Performance and stability improvements on all platforms.


2015-03-04: Version 4.3.19

        ARM assembler: fix undefined behaviour in fits_shifter (Chromium issues
        444089, 463436).

        Implement subclassing Arrays (issue 3930).

        [es6] Fix for-const loops (issue 3983).

        Performance and stability improvements on all platforms.


2015-03-04: Version 4.3.18

        Implement subclassing Arrays (issue 3930).

        Performance and stability improvements on all platforms.


2015-03-04: Version 4.3.17

        Implement subclassing Arrays (issue 3930).

        convert more object functions to return maybes (issue 3929).

        Performance and stability improvements on all platforms.


2015-03-03: Version 4.3.16

        check for null context on execution entry (issue 3929).

        convert object::* to return maybe values (issue 3929).

        Removed funky Maybe constructor and made fields private (issue 3929).

        Polish Maybe API a bit, removing useless creativity and fixing some
        signatures (issue 3929).

        Performance and stability improvements on all platforms.


2015-03-02: Version 4.3.15

        Performance and stability improvements on all platforms.


2015-03-02: Version 4.3.14

        Performance and stability improvements on all platforms.


2015-02-28: Version 4.3.13

        Disallow subclassing Arrays (issue 3930).

        Performance and stability improvements on all platforms.


2015-02-28: Version 4.3.12

        Performance and stability improvements on all platforms.


2015-02-27: Version 4.3.11

        Disallow subclassing Arrays (issue 3930).

        convert Value::*Value() function to return Maybe results (issue 3929).

        Performance and stability improvements on all platforms.


2015-02-27: Version 4.3.10

        Convert v8::Value::To* to use MaybeLocal (issue 3929).

        Performance and stability improvements on all platforms.


2015-02-26: Version 4.3.9

        Add public version macros (issue 3075).

        Performance and stability improvements on all platforms.


2015-02-26: Version 4.3.8

        Performance and stability improvements on all platforms.


2015-02-25: Version 4.3.7

        Performance and stability improvements on all platforms.


2015-02-25: Version 4.3.6

        Performance and stability improvements on all platforms.


2015-02-25: Version 4.3.5

        Turn on job based recompilation (issue 3608).

        Performance and stability improvements on all platforms.


2015-02-24: Version 4.3.4

        Reland "Correctly propagate terminate exception in TryCall." (issue
        3892).

        Performance and stability improvements on all platforms.


2015-02-24: Version 4.3.3

        Performance and stability improvements on all platforms.


2015-02-24: Version 4.3.2

        Update GN build files with the cpu_arch -> current_cpu change.

        Performance and stability improvements on all platforms.


2015-02-23: Version 4.3.1

        Limit size of first page based on serialized data (Chromium issue
        453111).

        Performance and stability improvements on all platforms.


2015-02-19: Version 4.2.77

        Make generator constructors configurable (issue 3902).

        Performance and stability improvements on all platforms.


2015-02-19: Version 4.2.76

        Performance and stability improvements on all platforms.


2015-02-18: Version 4.2.75

        Performance and stability improvements on all platforms.


2015-02-18: Version 4.2.74

        Correctly propagate terminate exception in TryCall (issue 3892).

        Performance and stability improvements on all platforms.


2015-02-17: Version 4.2.73

        Performance and stability improvements on all platforms.


2015-02-17: Version 4.2.72

        [turbofan] Fix control reducer with re-reducing branches (Chromium issue
        458876).

        Performance and stability improvements on all platforms.


2015-02-16: Version 4.2.71

        Implement ES6 rest parameters (issue 2159).

        Performance and stability improvements on all platforms.


2015-02-13: Version 4.2.70

        new classes: no longer experimental (issue 3834).

        Make it possible to define arguments for CompileFunctionInContext.

        Performance and stability improvements on all platforms.


2015-02-12: Version 4.2.69

        Performance and stability improvements on all platforms.


2015-02-11: Version 4.2.68

        Performance and stability improvements on all platforms.


2015-02-11: Version 4.2.67

        Throw on range error when creating a string via API (issue 3853).

        Performance and stability improvements on all platforms.


2015-02-11: Version 4.2.66

        Performance and stability improvements on all platforms.


2015-02-10: Version 4.2.65

        Performance and stability improvements on all platforms.


2015-02-10: Version 4.2.64

        Performance and stability improvements on all platforms.


2015-02-10: Version 4.2.63

        Introduce a compile method that takes context extensions (Chromium issue
        456192).

        Performance and stability improvements on all platforms.


2015-02-09: Version 4.2.62

        Performance and stability improvements on all platforms.


2015-02-09: Version 4.2.61

        Performance and stability improvements on all platforms.


2015-02-07: Version 4.2.60

        Performance and stability improvements on all platforms.


2015-02-07: Version 4.2.59

        Performance and stability improvements on all platforms.


2015-02-07: Version 4.2.58

        Performance and stability improvements on all platforms.


2015-02-06: Version 4.2.57

        Performance and stability improvements on all platforms.


2015-02-06: Version 4.2.56

        Performance and stability improvements on all platforms.


2015-02-06: Version 4.2.55

        Protect against uninitialized lexical variables at top-level (Chromium
        issue 452510).

        Performance and stability improvements on all platforms.


2015-02-05: Version 4.2.54

        Fix HConstant(double, ...) constructor (issue 3865).

        Add NativeWeakMap to v8.h (Chromium issue 437416).

        Performance and stability improvements on all platforms.


2015-02-05: Version 4.2.53

        Fix issue with multiple properties and emit store (issue 3856).

        Class methods should be non enumerable (issue 3330).

        Performance and stability improvements on all platforms.


2015-02-04: Version 4.2.52

        Add WeakKeyMap to v8.h (Chromium issue 437416).

        Performance and stability improvements on all platforms.


2015-02-04: Version 4.2.51

        Performance and stability improvements on all platforms.


2015-02-03: Version 4.2.50

        Reset inlining limits due to overly long compilation times in
        Speedometer, Dart2JS (Chromium issue 454625).

        Add WeakMap to v8.h (Chromium issue 437416).

        [V8] Added line, column and script symbols for SyntaxError (Chromium
        issue 443140).

        Performance and stability improvements on all platforms.


2015-02-03: Version 4.2.49

        Compute the same hash for all NaN values (issue 3859).

        Performance and stability improvements on all platforms.


2015-02-03: Version 4.2.48

        Performance and stability improvements on all platforms.


2015-02-02: Version 4.2.47

        Check global object behind global proxy for extensibility (Chromium
        issue 454091).

        Performance and stability improvements on all platforms.


2015-02-02: Version 4.2.46

        Performance and stability improvements on all platforms.


2015-02-02: Version 4.2.45

        Performance and stability improvements on all platforms.


2015-02-01: Version 4.2.44

        Performance and stability improvements on all platforms.


2015-02-01: Version 4.2.43

        Performance and stability improvements on all platforms.


2015-01-31: Version 4.2.42

        Performance and stability improvements on all platforms.


2015-01-31: Version 4.2.41

        Layout descriptor sharing issue fixed (issue 3832, Chromium issue
        437713).

        Performance and stability improvements on all platforms.


2015-01-30: Version 4.2.40

        Performance and stability improvements on all platforms.


2015-01-30: Version 4.2.38

        Move object literal checking into checker classes (issue 3819).

        [turbofan] Fix OSR compilations of for-in.

        Performance and stability improvements on all platforms.


2015-01-30: Version 4.2.37

        Do not create unresolved variables when parsing arrow functions lazily
        (issue 3501).

        Performance and stability improvements on all platforms.


2015-01-29: Version 4.2.36

        Performance and stability improvements on all platforms.


2015-01-29: Version 4.2.35

        Performance and stability improvements on all platforms.


2015-01-28: Version 4.2.34

        Performance and stability improvements on all platforms.


2015-01-28: Version 4.2.33

        Performance and stability improvements on all platforms.


2015-01-27: Version 4.2.32

        Do not generalize field representations when making elements kind or
        observed transition (Chromium issue 448711).

        Performance and stability improvements on all platforms.


2015-01-27: Version 4.2.31

        [x86] Disable AVX unless the operating system explicitly claims to
        support it (issue 3846, Chromium issue 452033).

        Performance and stability improvements on all platforms.


2015-01-27: Version 4.2.30

        Performance and stability improvements on all platforms.


2015-01-26: Version 4.2.29

        MIPS: Fixed Hydrogen environment handling for mul-i ARM and ARM64 (issue
        451322).

        [turbofan] Simplify reduction if IfTrue and IfFalse and fix bugs
        (Chromium issue 451958).

        Add HeapNumber fast path to v8::Value::{Uint,Int}32Value() (Chromium
        issue 446097).

        Performance and stability improvements on all platforms.


2015-01-26: Version 4.2.28

        Fixed Hydrogen environment handling for mul-i on ARM and ARM64 (issue
        451322).

        Performance and stability improvements on all platforms.


2015-01-25: Version 4.2.27

        Performance and stability improvements on all platforms.


2015-01-24: Version 4.2.26

        ES6 Array.prototype.toString falls back on Object.prototype.toString if
        method "join" is not callable (issue 3793).

        Performance and stability improvements on all platforms.


2015-01-23: Version 4.2.25

        Performance and stability improvements on all platforms.


2015-01-23: Version 4.2.24

        Performance and stability improvements on all platforms.


2015-01-23: Version 4.2.23

        [x86] Blacklist AVX for Windows versions before 6.1 (Windows 7) (issue
        3846).

        Performance and stability improvements on all platforms.


2015-01-23: Version 4.2.22

        Fix run-time ARMv6 detection (issue 3844).

        Support concatenating with zero-size arrays with DICTIONARY_ELEMENTS in
        Runtime_ArrayConcat (Chromium issue 450895).

        Performance and stability improvements on all platforms.


2015-01-22: Version 4.2.21

        Performance and stability improvements on all platforms.


2015-01-22: Version 4.2.20

        Add a pretty printer to improve the error message non-function calls
        (Chromium issue 259443).

        Remove implicit uint8_t to char cast in string replace (Chromium issue
        446196).

        Performance and stability improvements on all platforms.


2015-01-21: Version 4.2.19

        Performance and stability improvements on all platforms.


2015-01-20: Version 4.2.18

        Fix issue with __proto__ when using ES6 object literals (issue 3818).

        Performance and stability improvements on all platforms.


2015-01-20: Version 4.2.17

        Performance and stability improvements on all platforms.


2015-01-20: Version 4.2.16

        Performance and stability improvements on all platforms.


2015-01-19: Version 4.2.15

        Unobscurified OFStream (Chromium issue 448102).

        Performance and stability improvements on all platforms.


2015-01-19: Version 4.2.14

        Performance and stability improvements on all platforms.


2015-01-18: Version 4.2.13

        Performance and stability improvements on all platforms.


2015-01-18: Version 4.2.12

        Performance and stability improvements on all platforms.


2015-01-17: Version 4.2.11

        Performance and stability improvements on all platforms.


2015-01-16: Version 4.2.10

        Performance and stability improvements on all platforms.


2015-01-16: Version 4.2.9

        MIPS: ES6 computed property names (issue 3754).

        ES6 computed property names (issue 3754).

        Performance and stability improvements on all platforms.


2015-01-15: Version 4.2.8

        Performance and stability improvements on all platforms.


2015-01-15: Version 4.2.7

        Performance and stability improvements on all platforms.


2015-01-15: Version 4.2.6

        Performance and stability improvements on all platforms.


2015-01-15: Version 4.2.5

        Performance and stability improvements on all platforms.


2015-01-14: Version 4.2.4

        Auto-generate v8 version based on tags (Chromium issue 446166).

        Remove support for signatures with arguments.

        Add proper support for proxies to HType (Chromium issue 448730).

        [turbofan] Fix truncation/representation sloppiness wrt. bool/bit (issue
        3812).

        Performance and stability improvements on all platforms.


2015-01-14: Version 4.2.3

        Performance and stability improvements on all platforms.


2015-01-14: Version 4.2.2

        Performance and stability improvements on all platforms.


2015-01-14: Version 4.2.1

        Map -0 to integer 0 for typed array constructors (Chromium issue
        447756).

        Introduce a gyp variable to control whether or not slow dchecks are on.

        Correctly setup the freelist of the coderange on Win64 (Chromium issue
        447555).

        Fast forward V8 to version 4.2.

        Remove "extra checks".

        Performance and stability improvements on all platforms.


2015-01-08: Version 3.32.7

        Correctly parse line ends for debugging (issue 2825).

        Fixed printing during DCE (issue 3679).

        Performance and stability improvements on all platforms.


2015-01-08: Version 3.32.6

        Performance and stability improvements on all platforms.


2015-01-08: Version 3.32.5

        Correct handling of exceptions occured during getting of exception stack
        trace (Chromium issue 444805).

        Fix bug in Runtime_CompileOptimized resulting from stack overflow
        (Chromium issue 446774).

        Turn on job-based recompilation (issue 3608).

        Performance and stability improvements on all platforms.


2015-01-07: Version 3.32.4

        Performance and stability improvements on all platforms.


2015-01-07: Version 3.32.3

        Performance and stability improvements on all platforms.


2015-01-07: Version 3.32.2

        Performance and stability improvements on all platforms.


2015-01-07: Version 3.32.1

        [turbofan] Don't crash when typing load from a Uint8ClampedArray
        (Chromium issue 446156).

        [turbofan] Truncation of Bit/Word8/16 to Word32 is a no-op (Chromium
        issue 445859).

        [x64] Rearrange code for OOB integer loads (Chromium issue 445858).

        Fix %NeverOptimizeFunction() intrinsic (Chromium issue 445732).

        [turbofan] Fix invalid bounds check with overflowing offset (Chromium
        issue 445267).

        [turbofan] Raise max virtual registers and call parameter limit (issue
        3786).

        Performance and stability improvements on all platforms.


2014-12-23: Version 3.31.74

        [turbofan] Turn DCHECK for fixed slot index into a CHECK (Chromium issue
        444681).

        Performance and stability improvements on all platforms.


2014-12-23: Version 3.31.73

        [turbofan] Fix missing ChangeUint32ToUint64 in lowering of LoadBuffer
        (Chromium issue 444695).

        Enable the embedder to specify what kind of context was disposed.

        Performance and stability improvements on all platforms.


2014-12-22: Version 3.31.72

        [turbofan] Correctify lowering of Uint8ClampedArray buffer access
        (Chromium issue 444508).

        Performance and stability improvements on all platforms.


2014-12-20: Version 3.31.71

        Performance and stability improvements on all platforms.


2014-12-20: Version 3.31.70

        Performance and stability improvements on all platforms.


2014-12-20: Version 3.31.69

        Performance and stability improvements on all platforms.


2014-12-19: Version 3.31.68

        [turbofan] Fix unsafe out-of-bounds check for checked loads/stores
        (Chromium issue 443744).

        Performance and stability improvements on all platforms.


2014-12-19: Version 3.31.67

        Performance and stability improvements on all platforms.


2014-12-19: Version 3.31.66

        Ship ES6 template literals (issue 3230).

        Performance and stability improvements on all platforms.


2014-12-18: Version 3.31.65

        ES6 template literals should not use legacy octal strings (issue 3736).

        Performance and stability improvements on all platforms.


2014-12-18: Version 3.31.64

        Fixed -fsanitize=float-cast-overflow problems (issue 3773).

        Performance and stability improvements on all platforms.


2014-12-18: Version 3.31.63

        ES6 computed property names (issue 3754).

        Performance and stability improvements on all platforms.


2014-12-17: Version 3.31.62

        Performance and stability improvements on all platforms.


2014-12-17: Version 3.31.61

        ES6: Update unscopables to match spec (issue 3632).

        ES6 computed property names (issue 3754).

        More -fsanitize=vptr fixes (Chromium issue 441099).

        [turbofan] Cache conversions inserted during typed lowering (issue
        3763).

        Performance and stability improvements on all platforms.


2014-12-16: Version 3.31.60

        Performance and stability improvements on all platforms.


2014-12-16: Version 3.31.59

        Performance and stability improvements on all platforms.


2014-12-16: Version 3.31.58

        Ship ES6 classes (issue 3330).

        ES6 computed property names (issue 3754).

        Performance and stability improvements on all platforms.


2014-12-12: Version 3.31.57

        Consistently use only one of virtual/OVERRIDE/FINAL (issue 3753).

        Performance and stability improvements on all platforms.


2014-12-12: Version 3.31.56

        Performance and stability improvements on all platforms.


2014-12-12: Version 3.31.55

        Performance and stability improvements on all platforms.


2014-12-11: Version 3.31.54

        Implement Array.from() (issue 3336).

        move v8_use_external_startup_data to standalone.gypi (Chromium issue
        421063).

        Performance and stability improvements on all platforms.


2014-12-11: Version 3.31.53

        Performance and stability improvements on all platforms.


2014-12-11: Version 3.31.52

        Ship ES6 block scoping (issue 2198).

        Optimize Object.seal and Object.preventExtensions (issue 3662, Chromium
        issue 115960).

        Add Array.prototype.includes (issue 3575).

        Performance and stability improvements on all platforms.


2014-12-10: Version 3.31.51

        [x64] Fix optimization for certain checked load/stores (Chromium issue
        439743).

        Performance and stability improvements on all platforms.


2014-12-09: Version 3.31.50

        Temporarily restore make dependencies.

        Performance and stability improvements on all platforms.


2014-12-09: Version 3.31.49

        Performance and stability improvements on all platforms.


2014-12-09: Version 3.31.48

        Performance and stability improvements on all platforms.


2014-12-09: Version 3.31.47

        Temporarily restore make dependencies.

        Performance and stability improvements on all platforms.


2014-12-08: Version 3.31.46

        Performance and stability improvements on all platforms.


2014-12-08: Version 3.31.45

        Update all DEPS to match chromium's DEPS at edb488e.

        Turn on DCHECKs and other debugging code if dcheck_always_on is 1 (issue
        3731).

        Optimize GetPrototype.

        Performance and stability improvements on all platforms.


2014-12-05: Version 3.31.44

        Performance and stability improvements on all platforms.


2014-12-04: Version 3.31.43

        ES6 template literals: Fix issue with template after rbrace (issue
        3734).

        Stage ES6 template literals (issue 3230).

        Performance and stability improvements on all platforms.


2014-12-04: Version 3.31.42

        Performance and stability improvements on all platforms.


2014-12-04: Version 3.31.41

        Simplify template literal raw string creation (issue 3710).

        Performance and stability improvements on all platforms.


2014-12-03: Version 3.31.40

        Performance and stability improvements on all platforms.


2014-12-03: Version 3.31.39

        Performance and stability improvements on all platforms.


2014-12-03: Version 3.31.38

        Stage ES6 classes and object literal extensions (issue 3330).

        Fixed environment handling for LFlooringDivI on ARM (Chromium issue
        437765).

        Add GetIdentityHash to v8::Name object API (Chromium issue 437416).

        Set V8_CC_GNU or V8_CC_MSVC for clang in gcc / cl mode (Chromium issue
        82385).

        Performance and stability improvements on all platforms.


2014-12-02: Version 3.31.37

        Performance and stability improvements on all platforms.


2014-12-02: Version 3.31.36

        Set V8_CC_GNU or V8_CC_MSVC for clang in gcc / cl mode (Chromium issue
        82385).

        Performance and stability improvements on all platforms.


2014-12-02: Version 3.31.35

        Performance and stability improvements on all platforms.


2014-12-01: Version 3.31.34

        Performance and stability improvements on all platforms.


2014-12-01: Version 3.31.33

        Performance and stability improvements on all platforms.


2014-12-01: Version 3.31.32

        Performance and stability improvements on all platforms.


2014-12-01: Version 3.31.31

        Performance and stability improvements on all platforms.


2014-11-29: Version 3.31.30

        Performance and stability improvements on all platforms.


2014-11-28: Version 3.31.29

        Stage @@toStringTag (--harmony-tostring).

        Performance and stability improvements on all platforms.


2014-11-28: Version 3.31.28

        Performance and stability improvements on all platforms.


2014-11-28: Version 3.31.27

        Ship harmony-strings.

        Performance and stability improvements on all platforms.


2014-11-28: Version 3.31.26

        Abort optimization in corner case (Chromium issue 436893).

        Performance and stability improvements on all platforms.


2014-11-26: Version 3.31.25

        Stage ES6 block scoping (issue 2198).

        Introduce legacy const slots in correct context (Chromium issue 410030).

        Performance and stability improvements on all platforms.


2014-11-26: Version 3.31.24

        Performance and stability improvements on all platforms.


2014-11-25: Version 3.31.23

        Performance and stability improvements on all platforms.


2014-11-25: Version 3.31.22

        Performance and stability improvements on all platforms.


2014-11-24: Version 3.31.21

        Performance and stability improvements on all platforms.


2014-11-24: Version 3.31.20

        Performance and stability improvements on all platforms.


2014-11-22: Version 3.31.19

        Performance and stability improvements on all platforms.


2014-11-21: Version 3.31.18

        Performance and stability improvements on all platforms.


2014-11-21: Version 3.31.17

        Performance and stability improvements on all platforms.


2014-11-21: Version 3.31.16

        Cache template literal callSiteObj (issue 3230).

        Rename String.prototype.contains to 'includes'.

        Reserve code range block for evacuation (Chromium issue 430118).

        Performance and stability improvements on all platforms.


2014-11-20: Version 3.31.15

        Rename String.prototype.contains to 'includes'.

        Performance and stability improvements on all platforms.


2014-11-19: Version 3.31.14

        Remove Weak{Map,Set}.prototype.clear.

        Performance and stability improvements on all platforms.


2014-11-19: Version 3.31.13

        Performance and stability improvements on all platforms.


2014-11-19: Version 3.31.12

        Classes: Expand test to cover strict runtime behavior (issue 3330).

        v8::String::Concat must not throw (Chromium issue 420240).

        Fix disabling all break points from within the debug event callback
        (Chromium issue 432493).

        Performance and stability improvements on all platforms.


2014-11-18: Version 3.31.11

        Performance and stability improvements on all platforms.


2014-11-17: Version 3.31.10

        Performance and stability improvements on all platforms.


2014-11-17: Version 3.31.9

        Expose internal properties of map/set iterators via mirrors.

        Performance and stability improvements on all platforms.


2014-11-17: Version 3.31.8

        Performance and stability improvements on all platforms.


2014-11-15: Version 3.31.7

        Classes: Add support for stepping through default constructors (issue
        3674).

        Performance and stability improvements on all platforms.


2014-11-14: Version 3.31.6

        Fix desugaring of let bindings in for loops to handle continue properly
        (issue 3683).

        Performance and stability improvements on all platforms.


2014-11-14: Version 3.31.5

        Classes: Implement correct name binding (issue 3330).

        Performance and stability improvements on all platforms.


2014-11-14: Version 3.31.4

        Performance and stability improvements on all platforms.


2014-11-14: Version 3.31.3

        Classes: Cleanup default constructor flag.

        Soft fail for invalid cache data.

        Implement .of() on typed arrays (issue 3578).

        Performance and stability improvements on all platforms.


2014-11-13: Version 3.31.2

        MIPS: Leaving a generator via an exception causes it to close (issue
        3096).

        MIPS: ES6: Add support for super in object literals (issue 3571).

        Increase the target new space size to the max new space size (issue
        3626).

        Leaving a generator via an exception causes it to close (issue 3096).

        Correctly compute line numbers in functions from the function
        constructor (Chromium issue 109362).

        Rename v8::Exception::GetMessage to CreateMessage.

        Classes: Add support for arguments in default constructor (issue 3672).

        ES6: Add support for super in object literals (issue 3571).

        Performance and stability improvements on all platforms.


2014-11-12: Version 3.31.1

        Fix has_constant_parameter_count() confusion in LReturn (Chromium issue
        431602).

        Performance and stability improvements on all platforms.


2014-11-05: Version 3.30.33

        `1..isPrototypeOf.call(null)` should return false, not throw TypeError
        (issue 3483).

        Refactor ObjectGetOwnPropertyKeys to accept bitmask rather than boolean
        (issue 3549).

        Add debug mirror support for ES6 Map/Set iterators (Chromium issue
        427868).

        Performance and stability improvements on all platforms.


2014-11-04: Version 3.30.30

        Performance and stability improvements on all platforms.


2014-11-02: Version 3.30.27

        Performance and stability improvements on all platforms.


2014-11-02: Version 3.30.26

        Performance and stability improvements on all platforms.


2014-11-01: Version 3.30.25

        Performance and stability improvements on all platforms.


2014-11-01: Version 3.30.24

        Ensure we don't try to inline raw access to indexed interceptor
        receivers (Chromium issue 419220).

        Performance and stability improvements on all platforms.


2014-10-31: Version 3.30.23

        Introduce v8::Exception::GetMessage to find location of an error object
        (Chromium issue 427954).

        Performance and stability improvements on all platforms.


2014-10-30: Version 3.30.22

        MIPS: Classes: Add super support in methods and accessors (issue 3330).

        Classes: Add super support in methods and accessors (issue 3330).

        Performance and stability improvements on all platforms.


2014-10-29: Version 3.30.21

        MIPS: Classes: Add basic support for properties (issue 3330).

        Classes: Add more tests for prototype edge cases (Chromium issue 3655).

        Classes: Add test for method prototype (issue 3330).

        Get stack trace for uncaught exceptions/promise rejections from the
        simple stack when available.

        Classes: Add basic support for properties (issue 3330).

        Allow duplicate property names in classes (issue 3570).

        Windows: use SystemTimeToTzSpecificLocalTime instead of localtime_s
        (Chromium issue 417640).

        Performance and stability improvements on all platforms.


2014-10-28: Version 3.30.20

        Performance and stability improvements on all platforms.


2014-10-27: Version 3.30.19

        Check string literals with escapes in PreParserTraits::GetSymbol()
        (issue 3606).

        only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue 405225).

        Performance and stability improvements on all platforms.


2014-10-24: Version 3.30.18

        Narrow cases where Sparse/Smart versions of Array methods are used
        (issues 2615, 3612, 3621).

        Shrink new space in idle notification (Chromium issue 424423).

        Performance and stability improvements on all platforms.


2014-10-23: Version 3.30.17

        ARM64: Fix stack manipulation (Chromium issue 425585).

        Speed up creation of Objects whose prototype has dictionary elements
        (Chromium issue 422754).

        Enable libstdc++ debug mode in debug builds (issue 3638).

        Performance and stability improvements on all platforms.


2014-10-22: Version 3.30.16

        Remove v8stdint.h, it doesn't serve a purpose anymore.

        Performance and stability improvements on all platforms.


2014-10-21: Version 3.30.15

        Avoid the Marsaglia effect in 3D (Chromium issue 423311).

        Performance and stability improvements on all platforms.


2014-10-20: Version 3.30.14

        Performance and stability improvements on all platforms.


2014-10-17: Version 3.30.13

        Don't expose Array.prototype.values as it breaks webcompat (Chromium
        issue 409858).

        Fix break location calculation (Chromium issue 419663).

        Enable libstdc++ debug mode in debug builds (issue 3638).

        Performance and stability improvements on all platforms.


2014-10-17: Version 3.30.12

        Implement .forEach() on typed arrays (issue 3578).

        Introduce v8::Exception::GetStackTrace API method.

        Remove SmartMove, bringing Array methods further into spec compliance
        (issue 2615).

        Convert argument toObject() in Object.getOwnPropertyNames/Descriptors
        (issue 3443).

        Performance and stability improvements on all platforms.


2014-10-15: Version 3.30.11

        Array.prototype.{every, filter, find, findIndex, forEach, map, some}:
        Use fresh primitive wrapper for calls (issue 3536).

        Correctly expand literal buffer for surrogate pairs (Chromium issue
        423212).

        Performance and stability improvements on all platforms.


2014-10-15: Version 3.30.10

        Squeeze the layout of various AST node types (Chromium issue 417697).

        Performance and stability improvements on all platforms.


2014-10-14: Version 3.30.9

        Performance and stability improvements on all platforms.


2014-10-13: Version 3.30.8

        AST nodes have at most one bailout/typefeedback ID now, saving lots of
        memory (Chromium issue 417697).

        Allow identifier code points from supplementary multilingual planes
        (issue 3617).

        Performance and stability improvements on all platforms.


2014-10-10: Version 3.30.7

        Fix computation of UTC time from local time at DST change points (issue
        3116, Chromium issues 415424, 417640).

        Convert `obj` ToObject in Object.keys() (issue 3587).

        Performance and stability improvements on all platforms.


2014-10-09: Version 3.30.6

        Update unicode to 7.0.0 (issue 2892).

        Classes: Add support for toString (issue 3330).

        Don't enable WPO on Win64 and require Server 2003 / x64 for win64
        (Chromium issue 421363).

        Performance and stability improvements on all platforms.


2014-10-08: Version 3.30.5

        Performance and stability improvements on all platforms.


2014-10-08: Version 3.30.4

        This uses a runtime function to set up the the constructor and its
        prototype (issue 3330).

        Remove PersistentBase::ClearAndLeak.

        Squeeze the layout of variable proxy nodes (Chromium issue 417697).

        Add MonotonicallyIncreasingTime to V8 Platform (Chromium issue 417668).

        Fix representation of HLoadRoot (Chromium issue 419036).

        Performance and stability improvements on all platforms.


2014-10-03: Version 3.30.3

        Removed the Isolate* field from literal nodes (Chromium issue 417697).

        Squeeze the layout of expression nodes a bit (Chromium issue 417697).

        Merged FeedbackSlotInterface into AstNode, removing the need for a 2nd
        vtable (Chromium issue 417697).

        Extend CPU profiler with mapping ticks to source lines.

        Remove support for parallel sweeping.

        Introduce v8::Object::GetIsolate().

        Performance and stability improvements on all platforms.


2014-10-02: Version 3.30.2

        Fix Hydrogen's BuildStore() (Chromium issue 417508).

        Move unit tests to test/unittests (issue 3489).

        Changes to ALLOW_UNUSED to match upcoming changes to the Chromium trunk:
        * Eliminate usage of ALLOW_UNUSED to define COMPILE_ASSERT and just use
        static_assert() in all cases now that all platforms build with C++11. *
        Convert remaining uses of ALLOW_UNUSED to ALLOW_UNUSED_TYPE to match how
        Chromium will be splitting this functionality.  (In Chromium we'll have
        both   ALLOW_UNUSED_TYPE and ALLOW_UNUSED_LOCAL, which have different
        syntax to   enable us to use these with MSVC.) (Chromium issue 81439).

        Performance and stability improvements on all platforms.


2014-10-01: Version 3.30.1

        Introduce PromiseRejectCallback (issue 3093).

        ES6: Implement object literal property shorthand (issue 3584).

        Performance and stability improvements on all platforms.


2014-09-30: Version 3.29.93

        Add a getter for the address and size of the code range to the pulic API
        (issue 3598).

        Convert `obj` ToObject in Object.keys() (issue 3587).

        Performance and stability improvements on all platforms.


2014-09-29: Version 3.29.92

        Performance and stability improvements on all platforms.


2014-09-26: Version 3.29.91

        Performance and stability improvements on all platforms.


2014-09-25: Version 3.29.88

        Performance and stability improvements on all platforms.


2014-09-24: Version 3.29.87

        Preserve message when rethrowing exception (issue 3583).

        Fix escaped index JSON parsing (Chromium issue 416449).

        Performance and stability improvements on all platforms.


2014-09-23: Version 3.29.84

        Performance and stability improvements on all platforms.


2014-09-23: Version 3.29.83

        Performance and stability improvements on all platforms.


2014-09-23: Version 3.29.82

        Fix escaped index JSON parsing (Chromium issue 416449).

        Performance and stability improvements on all platforms.


2014-09-17: Version 3.29.70

        Enable ES6 generators (issue 2355).

        Fixed int vs. uintptr_t confusion (plus some cleanup on the way) (issue
        3556).

        Move configuration of ResourceConstraints to Isolate construction.

        Performance and stability improvements on all platforms.


2014-09-16: Version 3.29.66

        Currently, a new isolate is created in an uninitialized state, and
        several API methods will automatically initialize it. During this
        uninitialized state, code event handlers and function entry handlers can
        be attached to the isolate.

        Performance and stability improvements on all platforms.


2014-09-15: Version 3.29.64

        ES6: String(symbol) should work like symbol.toString (issue 3554).

        Arrow functions: Cleanup handling of the prototype property (issue
        2700).

        Remove V8_HOST_CAN_READ_UNALIGNED and its uses (Chromium issue 412967).

        Fix Smi vs. HeapObject confusion in HConstants (Chromium issue 412215).

        Performance and stability improvements on all platforms.


2014-09-12: Version 3.29.59

        Do not use wide reads in CopyCharsUnsigned (Chromium issue 412967).

        Fix inaccurate type condition in Hydrogen (Chromium issue 412210).

        Fix crash in ScriptDebugServer::wrapCallFrames (Chromium issue 411196).

        Performance and stability improvements on all platforms.


2014-09-11: Version 3.29.57

        ES6: Add support for method shorthand in object literals (issue 3516).

        Unbreak FreeBSD build (hopefully) (issue 3548).

        Performance and stability improvements on all platforms.


2014-09-09: Version 3.29.53

        Performance and stability improvements on all platforms.


2014-09-08: Version 3.29.50

        Allocate a new empty number dictionary when resetting elements (Chromium
        issue 410332).

        Performance and stability improvements on all platforms.


2014-09-05: Version 3.29.43

        Enforce correct number comparisons when inlining Array.indexOf (Chromium
        issue 407946).

        Performance and stability improvements on all platforms.


2014-09-04: Version 3.29.41

        Performance and stability improvements on all platforms.


2014-09-03: Version 3.29.40

        Use correct receiver for DOM accessors on the prototype chain (issue
        3538).

        Performance and stability improvements on all platforms.


2014-09-02: Version 3.29.38

        Do not clear weak monomorphic IC after context disposal (Chromium issue
        404020).

        Turn on job-based sweeping (issue 3104).

        Performance and stability improvements on all platforms.


2014-09-01: Version 3.29.35

        Performance and stability improvements on all platforms.


2014-08-29: Version 3.29.29

        Performance and stability improvements on all platforms.


2014-08-28: Version 3.29.27

        Performance and stability improvements on all platforms.


2014-08-28: Version 3.29.25

        Performance and stability improvements on all platforms.


2014-08-28: Version 3.29.24

        Tweaks to generate XP-compatible .exes (Chromium issue 407517).

        Performance and stability improvements on all platforms.


2014-08-28: Version 3.29.23

        Performance and stability improvements on all platforms.


2014-08-27: Version 3.29.20

        Handle empty allocation list in CodeRange properly (issue 3540, Chromium
        issue 407566).

        Fixed inlining of constant values (issue 3529).

        Performance and stability improvements on all platforms.


2014-08-25: Version 3.29.17

        Performance and stability improvements on all platforms.


2014-08-24: Version 3.29.16

        Fix issue with numeric property names (issue 3507).

        Add back the duplicate property checker (issue 3498).

        Performance and stability improvements on all platforms.


2014-08-22: Version 3.29.14

        Don't inline Array.shift() if receiver map is not extensible (Chromium
        issue 405517).

        Performance and stability improvements on all platforms.


2014-08-21: Version 3.29.11

        Refactor ParseObjectLiteral.

        Support symbol-named properties in API (issue 3394).

        Suppress test262 test that tests duplicate properties.

        ES6: Duplicate properties are no longer an error (issue 3498).

        Expose function CheckDebugBreak in the debugger api.

        Remove RegExp.$input (issue 3486).

        Performance and stability improvements on all platforms.


2014-08-21: Version 3.29.10

        ES6: Make sure we do not store -0 as the key in Map/Set (issue 3515).

        Remove removed flags from tests.

        Expose well-known Symbols to C++ API (Chromium issue 341423).

        Implement ES6 Array.of() (issue 3427).

        Performance and stability improvements on all platforms.


2014-08-20: Version 3.29.9

        Correctly handle holes when concat()ing double arrays (Chromium issue
        403409).

        [turbofan] Refactor the InstructionSelector tests (issue 3489).

        ES6: Make Map/Set constructors support iterable values (issue 3508).

        WeakMap/WeakSet: Add test for non object keys (issue 3399).

        Performance and stability improvements on all platforms.


2014-08-12: Version 3.28.71

        ToNumber(Symbol) should throw TypeError (issue 3499).

        Performance and stability improvements on all platforms.


2014-08-11: Version 3.28.69

        Performance and stability improvements on all platforms.


2014-08-09: Version 3.28.65

        Performance and stability improvements on all platforms.


2014-08-08: Version 3.28.64

        ES6: Implement WeakMap and WeakSet constructor logic (issue 3399).

        Enable ES6 unscopables (issue 3401).

        Turn on harmony_unscopables for es_staging (issue 3401).

        Remove proxies from --harmony switch for M38, because problems.

        Reland "Add initial support for compiler unit tests using GTest/GMock."
        (issue 3489).

        Enable ES6 iteration by default (issue 2214).

        Performance and stability improvements on all platforms.


2014-08-07: Version 3.28.62

        Only escape U+0022 in argument values of `String.prototype` HTML methods
        (issue 2217).

        Update webkit test for expected own properties.

        This implements unscopables (issue 3401).

        Add `CheckObjectCoercible` for the `String.prototype` HTML methods
        (issue 2218).

        Add initial support for compiler unit tests using GTest/GMock (issue
        3489).

        Trigger exception debug events on Promise reject (Chromium issue
        393913).

        Refactor unit tests for the base library to use GTest (issue 3489).

        Performance and stability improvements on all platforms.


2014-08-06: Version 3.28.60

        Enable ES6 Map and Set by default (issue 1622).

        Performance and stability improvements on all platforms.


2014-08-06: Version 3.28.59

        Removed GetConstructor from the API. Instead either get the
        "constructor" property stored in the prototype, or keep a side-table.

        Enable ES6 Symbols by default (issue 2158).

        Performance and stability improvements on all platforms.


2014-08-05: Version 3.28.57

        Add dependencies on gtest and gmock.

        Performance and stability improvements on all platforms.


2014-08-04: Version 3.28.54

        Performance and stability improvements on all platforms.


2014-08-01: Version 3.28.53

        Performance and stability improvements on all platforms.


2014-07-31: Version 3.28.52

        Performance and stability improvements on all platforms.


2014-07-31: Version 3.28.51

        Drop deprecated memory related notification API (Chromium issue 397026).

        Performance and stability improvements on all platforms.


2014-07-31: Version 3.28.50

        Use emergency memory in the case of out of memory during evacuation
        (Chromium issue 395314).

        Performance and stability improvements on all platforms.


2014-07-30: Version 3.28.48

        Fix Object.freeze with field type tracking. Keep the descriptor properly
        intact while update the field type (issue 3458).

        Performance and stability improvements on all platforms.


2014-07-29: Version 3.28.45

        Performance and stability improvements on all platforms.


2014-07-28: Version 3.28.43

        Performance and stability improvements on all platforms.


2014-07-25: Version 3.28.38

        Fix issue with setters and their holders in accessors.cc (Chromium issue
        3462).

        Introduce more debug events for promises (issue 3093).

        Move gc notifications from V8 to Isolate and make idle hint mandatory
        (Chromium issue 397026).

        The accessors should get the value from the holder and not from this
        (issue 3461).

        Performance and stability improvements on all platforms.


2014-07-24: Version 3.28.35

        Rebaseline/update the intl tests with ICU 52 (issue 3454).

        Expose the content of Sets and WeakSets through SetMirror (issue 3093).

        Performance and stability improvements on all platforms.


2014-07-23: Version 3.28.32

        Update ICU to 5.2 (matching chromium) (issue 3452).

        Performance and stability improvements on all platforms.


2014-07-22: Version 3.28.31

        Remove harmony-typeof.

        Implement String.prototype.codePointAt and String.fromCodePoint (issue
        2840).

        Performance and stability improvements on all platforms.


2014-07-21: Version 3.28.30

        Performance and stability improvements on all platforms.


2014-07-21: Version 3.28.29

        Performance and stability improvements on all platforms.


2014-07-18: Version 3.28.28

        Performance and stability improvements on all platforms.


2014-07-17: Version 3.28.26

        Ship ES6 Math functions (issue 2938).

        Make ToPrimitive throw on symbol wrappers (issue 3442).

        Performance and stability improvements on all platforms.


2014-07-16: Version 3.28.25

        Performance and stability improvements on all platforms.


2014-07-16: Version 3.28.24

        Removed some copy-n-paste from StackFrame::Foo API entries (issue 3436).

        Performance and stability improvements on all platforms.


2014-07-15: Version 3.28.23

        Fix error message about read-only symbol properties (issue 3441).

        Include symbol properties in Object.{create,defineProperties} (issue
        3440).

        Performance and stability improvements on all platforms.


2014-07-14: Version 3.28.22

        Performance and stability improvements on all platforms.


2014-07-11: Version 3.28.21

        Make `let` usable as an identifier in ES6 sloppy mode (issue 2198).

        Support ES6 Map and Set in heap profiler (issue 3368).

        Performance and stability improvements on all platforms.


2014-07-10: Version 3.28.20

        Remove deprecate counter/histogram methods.

        Fixed printing of external references (Chromium issue 392068).

        Fix several issues with ES6 redeclaration checks (issue 3426).

        Performance and stability improvements on all platforms.


2014-07-09: Version 3.28.19

        Performance and stability improvements on all platforms.


2014-07-09: Version 3.28.18

        Reland "Postpone termination exceptions in debug scope." (issue 3408).

        Performance and stability improvements on all platforms.


2014-07-08: Version 3.28.17

        MIPS: Fix computed properties on object literals with a double as
        propertyname (Chromium issue 390732).

        Performance and stability improvements on all platforms.


2014-07-08: Version 3.28.16

        Fix computed properties on object literals with a double as propertyname
        (Chromium issue 390732).

        Avoid brittle use of .bind in Promise.all (issue 3420).

        Performance and stability improvements on all platforms.


2014-07-07: Version 3.28.15

        Remove a bunch of Isolate::UncheckedCurrent calls.

        Performance and stability improvements on all platforms.


2014-07-07: Version 3.28.14

        Use the HeapObjectIterator to scan-on-scavenge map pages (Chromium issue
        390732).

        Introduce debug events for Microtask queue (Chromium issue 272416).

        Split out libplatform into a separate libary.

        Add clang-format to presubmit checks.

        Stack traces exposed to Javascript should omit extensions (issue 311).

        Remove deprecated v8::Context::HasOutOfMemoryException.

        Postpone termination exceptions in debug scope (issue 3408).

        Performance and stability improvements on all platforms.


2014-07-04: Version 3.28.13

        Rollback to r22134.


2014-07-04: Version 3.28.12

        Use the HeapObjectIterator to scan-on-scavenge map pages (Chromium issue
        390732).

        Introduce debug events for Microtask queue (Chromium issue 272416).

        Performance and stability improvements on all platforms.


2014-07-03: Version 3.28.11

        Split out libplatform into a separate libary.

        Performance and stability improvements on all platforms.


2014-07-03: Version 3.28.10

        Add clang-format to presubmit checks.

        Stack traces exposed to Javascript should omit extensions (issue 311).

        Remove deprecated v8::Context::HasOutOfMemoryException.

        Postpone termination exceptions in debug scope (issue 3408).

        Performance and stability improvements on all platforms.


2014-07-02: Version 3.28.9

        Make freeze & friends ignore private properties (issue 3419).

        Introduce a builddeps make target (issue 3418).

        Performance and stability improvements on all platforms.


2014-07-01: Version 3.28.8

        Remove static initializer from isolate.

        ES6: Add missing Set.prototype.keys function (issue 3411).

        Introduce debug events for promises (issue 3093).

        Performance and stability improvements on all platforms.


2014-06-30: Version 3.28.7

        Performance and stability improvements on all platforms.


2014-06-30: Version 3.28.6

        Unbreak "os" stuff in shared d8 builds (issue 3407).

        Performance and stability improvements on all platforms.


2014-06-26: Version 3.28.4

        Compile optimized code with active debugger but no break points
        (Chromium issue 386492).

        Optimize Map/Set.prototype.forEach.

        Collect garbage with kReduceMemoryFootprintMask in IdleNotification
        (Chromium issue 350720).

        Performance and stability improvements on all platforms.


2014-06-26: Version 3.28.3

        Grow heap slower if GC freed many global handles (Chromium issue
        263503).

        Performance and stability improvements on all platforms.


2014-06-25: Version 3.28.2

        Remove bogus assertions in HCompareObjectEqAndBranch (Chromium issue
        387636).

        Do not eagerly update allow_osr_at_loop_nesting_level (Chromium issue
        387599).

        Set host_arch to ia32 on machines with a 32bit userland but a 64bit
        kernel (Chromium issue 368384).

        Map/Set: Implement constructor parameter handling (issue 3398).

        Performance and stability improvements on all platforms.


2014-06-24: Version 3.28.1

        Support LiveEdit on Arm64 (Chromium issue 368580).

        Run JS micro tasks in the appropriate context (Chromium issue 385349).

        Add a use counter API.

        Set host_arch to ia32 on machines with a 32bit userland but a 64bit
        kernel.

        Performance and stability improvements on all platforms.


2014-06-23: Version 3.28.0

        MIPS: Support LiveEdit (Chromium issue 368580).

        Array.concat: properly go to dictionary mode when required (Chromium
        issue 387031).

        Support LiveEdit on ARM (Chromium issue 368580).

        Performance and stability improvements on all platforms.


2014-06-18: Version 3.27.34

        Reduce number of writes to DependentCode array when inserting dependent
        IC (Chromium issue 305878).

        Performance and stability improvements on all platforms.


2014-06-17: Version 3.27.33

        Do GC if CodeRange fails to allocate a block (Chromium issue 305878).

        Throw syntax error when a getter/setter has the wrong number of params
        (issue 3371).

        Performance and stability improvements on all platforms.


2014-06-17: Version 3.27.32

        Performance and stability improvements on all platforms.


2014-06-16: Version 3.27.31

        Version fix.


2014-06-16: Version 3.27.30

        Fix representation of Phis for mutable-heapnumber-in-object-literal
        properties (issue 3392).

        Performance and stability improvements on all platforms.


2014-06-16: Version 3.27.29

        Emulate MLS on pre-ARMv6T2. Cleaned up thumbee vs. thumb2 confusion.

        X87: Fixed flooring division by a power of 2, once again.. (issue 3259).

        Fixed undefined behavior in RNG (Chromium issue 377790).

        Performance and stability improvements on all platforms.


2014-06-13: Version 3.27.28

        Add v8::Promise::Then (Chromium issue 371288).

        Performance and stability improvements on all platforms.


2014-06-12: Version 3.27.27

        Fix detection of VFP3D16 on Galaxy Tab 10.1 (issue 3387).

        Performance and stability improvements on all platforms.


2014-06-12: Version 3.27.26

        MIPS: Fixed flooring division by a power of 2, once again.. (issue
        3259).

        Fixed flooring division by a power of 2, once again.. (issue 3259).

        Fix unsigned comparisons (issue 3380).

        Performance and stability improvements on all platforms.


2014-06-11: Version 3.27.25

        Performance and stability improvements on all platforms.


2014-06-11: Version 3.27.24

        Fix invalid attributes when generalizing because of incompatible map
        change (Chromium issue 382143).

        Fix missing smi check in inlined indexOf/lastIndexOf (Chromium issue
        382513).

        Performance and stability improvements on all platforms.


2014-06-06: Version 3.27.23

        Performance and stability improvements on all platforms.


2014-06-06: Version 3.27.22

        Performance and stability improvements on all platforms.


2014-06-06: Version 3.27.21

        Turn on harmony_collections for es_staging (issue 1622).

        Do not make heap iterable eagerly (Chromium issue 379740).

        Performance and stability improvements on all platforms.


2014-06-05: Version 3.27.20

        Fix invalid loop condition for Array.lastIndexOf() (Chromium issue
        380512).

        Add API support for passing a C++ function as a microtask callback.

        Performance and stability improvements on all platforms.


2014-06-04: Version 3.27.19

        Split Put into Put and Remove.

        ES6: Add support for values/keys/entries for Map and Set (issue 1793).

        Performance and stability improvements on all platforms.


2014-06-03: Version 3.27.18

        Remove PROHIBITS_OVERWRITING as it is subsumed by non-configurable
        properties.

        Performance and stability improvements on all platforms.


2014-06-02: Version 3.27.17

        BuildNumberToString: Check for undefined keys in the cache (Chromium
        issue 368114).

        HRor and HSar can deoptimize (issue 3359).

        Simplify, speed-up correct-context ObjectObserve calls.

        Performance and stability improvements on all platforms.


2014-05-29: Version 3.27.16

        Allow microtasks to throw exceptions and handle them gracefully
        (Chromium issue 371566).

        Performance and stability improvements on all platforms.


2014-05-28: Version 3.27.15

        Performance and stability improvements on all platforms.


2014-05-27: Version 3.27.14

        Reland "Customized support for feedback on calls to Array." and follow-
        up fixes (Chromium issues 377198, 377290).

        Performance and stability improvements on all platforms.


2014-05-26: Version 3.27.13

        Performance and stability improvements on all platforms.


2014-05-26: Version 3.27.12

        Check for cached transition to ExternalArray elements kind (issue 3337).

        Support ES6 weak collections in heap profiler (Chromium issue 376196).

        Performance and stability improvements on all platforms.


2014-05-23: Version 3.27.11

        Add support for ES6 Symbol in heap profiler (Chromium issue 376194).

        Performance and stability improvements on all platforms.


2014-05-22: Version 3.27.10

        Implement Mirror object for Symbols (issue 3290).

        Allow debugger to step into Map and Set forEach callbacks (issue 3341).

        Fix ArrayShift hydrogen support (Chromium issue 374838).

        Use SameValueZero for Map and Set (issue 1622).

        Array Iterator next should check for own property.

        Performance and stability improvements on all platforms.


2014-05-21: Version 3.27.9

        Disable ArrayShift hydrogen support (Chromium issue 374838).

        ES6 Map/Set iterators/forEach improvements (issue 1793).

        Performance and stability improvements on all platforms.


2014-05-20: Version 3.27.8

        Move microtask queueing logic from JavaScript to C++.

        Partial revert of "Next bunch of fixes for check elimination" (Chromium
        issue 372173).

        Performance and stability improvements on all platforms.


2014-05-19: Version 3.27.7

        Performance and stability improvements on all platforms.


2014-05-19: Version 3.27.6

        Performance and stability improvements on all platforms.


2014-05-16: Version 3.27.5

        Performance and stability improvements on all platforms.


2014-05-15: Version 3.27.4

        Drop thenable coercion cache (Chromium issue 372788).

        Skip write barriers when updating the weak hash table (Chromium issue
        359401).

        Performance and stability improvements on all platforms.


2014-05-14: Version 3.27.3

        Performance and stability improvements on all platforms.


2014-05-13: Version 3.27.2

        Harden %SetIsObserved with RUNTIME_ASSERTs (Chromium issue 371782).

        Drop unused static microtask API.

        Introduce an api to query the microtask autorun state of an isolate.

        Performance and stability improvements on all platforms.


2014-05-12: Version 3.27.1

        Object.observe: avoid accessing acceptList properties more than once
        (issue 3315).

        Array Iterator prototype should not have a constructor (issue 3293).

        Fix typos in unit test for Array.prototype.fill().

        Shorten autogenerated error message for functions only (issue 3019,
        Chromium issue 331971).

        Reland "Removed default Isolate." (Chromium issue 359977).

        Performance and stability improvements on all platforms.


2014-05-09: Version 3.27.0

        Unbreak samples and tools.

        Performance and stability improvements on all platforms.


2014-05-08: Version 3.26.33

        Removed default Isolate (Chromium issue 359977).

        Performance and stability improvements on all platforms.


2014-05-07: Version 3.26.32

        Performance and stability improvements on all platforms.


2014-05-06: Version 3.26.31

        Add a basic gn file for V8.

        Performance and stability improvements on all platforms.


2014-05-05: Version 3.26.30

        Introduce a microtask suppression scope and move microtask methods to
        isolate (Chromium issue 369503).

        Re-enable Object.observe and add enforcement for security invariants.

        Move cache line size calculation directly into CPU::FlushICache
        (Chromium issue 359977).

        Generation of our home-grown memmove doesn't depend on serializer state
        anymore (Chromium issue 359977).

        Fix |RunMicrotasks()| leaking reference to the last context being run
        on.

        Object.defineProperty shouldn't be a hint that we're constructing a
        dictionary (Chromium issue 362870).

        Performance and stability improvements on all platforms.


2014-05-01: Version 3.26.29

        Added a Isolate* parameter to Serializer::enabled() (Chromium issue
        359977).

        ES6: Add support for Array.prototype.fill() (issue 3273).

        Performance and stability improvements on all platforms.


2014-04-29: Version 3.26.28

        PromiseThen should ignore non-function parameters (Chromium issue
        347455).

        Performance and stability improvements on all platforms.


2014-04-29: Version 3.26.27

        Error stack getter should not overwrite itself with a data property
        (issue 3294).

        Performance and stability improvements on all platforms.


2014-04-28: Version 3.26.26

        Expose promise value through promise mirror (issue 3093).

        Simplified CPU/CpuFeatures a bit (Chromium issue 359977).

        Performance and stability improvements on all platforms.


2014-04-28: Version 3.26.25

        Add timestamps to CPU profile samples (Chromium issue 363976).

        Expose promise status through promise mirror (issue 3093).

        Remove static CallCompletedCallback handlers.

        Added an Isolate* field to NoTrackDoubleFieldsForSerializerScope,
        PlatformFeatureScope and BinaryOpIC::State (Chromium issue 359977).

        Trigger debug event on not yet caught exception in promises (issue
        3093).

        Unbreak vtunejit=on (issue 3288).

        Performance and stability improvements on all platforms.


2014-04-25: Version 3.26.24

        MIPS: CodeStubs contain their corresponding Isolate* now. (part 2)
        (Chromium issue 359977).

        MIPS: CodeStubs contain their corresponding Isolate* now. (part 1)
        (Chromium issue 359977).

        CodeStubs contain their corresponding Isolate* now. (part 2) (Chromium
        issue 359977).

        Make DescriptorArray::IsMoreGeneralThan() and DescriptorArray::Merge()
        compatible again (Chromium issue 365172).

        CodeStubs contain their corresponding Isolate* now. (part 1) (Chromium
        issue 359977).

        Performance and stability improvements on all platforms.


2014-04-24: Version 3.26.23

        Performance and stability improvements on all platforms.


2014-04-23: Version 3.26.22

        Disable field type tracking by default (Chromium issue 365172).

        Performance and stability improvements on all platforms.


2014-04-23: Version 3.26.21

        Context-allocate all parameters in generators (issue 3280).

        Simplify v8/Isolate teardown (Chromium issue 359977).

        Performance and stability improvements on all platforms.


2014-04-21: Version 3.26.20

        ES6: Add support for Map/Set forEach (Chromium issues 1793, 2323).

        Performance and stability improvements on all platforms.


2014-04-18: Version 3.26.19

        ES6: Add support for Map/Set forEach (Chromium issues 1793, 2323).

        Performance and stability improvements on all platforms.


2014-04-17: Version 3.26.18

        Removed Isolate::EnterDefaultIsolate (Chromium issue 359977).

        Performance and stability improvements on all platforms.


2014-04-16: Version 3.26.17

        Clear invalid field maps in PropertyAccessInfo (Chromium issue 363956).

        ES6: Add support for Map/Set forEach (Chromium issues 1793, 2323).

        Performance and stability improvements on all platforms.


2014-04-16: Version 3.26.16

        Removed EnterIsolateIfNeeded and a soon-to-be-useless assertion
        (Chromium issue 359977).

        Removed GetDefaultIsolate{Debugger,ForLocking,StackGuard} (Chromium
        issue 359977).

        Performance and stability improvements on all platforms.


2014-04-15: Version 3.26.15

        Fix result of LCodeGen::DoWrapReceiver for strict functions and builtins
        (Chromium issue 362128).

        Performance and stability improvements on all platforms.


2014-04-15: Version 3.26.14

        Performance and stability improvements on all platforms.


2014-04-14: Version 3.26.13

        Make maps in monomorphic IC stubs weak (issue 2073).

        x64: Make sure that the upper half of a 64bit register contains 0 for
        int32 values (Chromium issue 360611).

        Performance and stability improvements on all platforms.


2014-04-11: Version 3.26.12

        Do not use ranges after range analysis (Chromium issue 361608).

        Performance and stability improvements on all platforms.


2014-04-10: Version 3.26.11

        Performance and stability improvements on all platforms.


2014-04-10: Version 3.26.10

        Allow the embedder to pass the virtual memory limit to v8.

        Performance and stability improvements on all platforms.


2014-04-09: Version 3.26.9

        Fix invalid local property lookup for transitions (Chromium issue
        361025).

        MIPS: Fixed flooring division by -1 (issue 3259).

        Fixed flooring division by -1 on ARM (issue 3259).

        Make `String.prototype.contains` throw when passing a regular expression
        (issue 3261).

        Performance and stability improvements on all platforms.


2014-04-08: Version 3.26.8

        Yet another regression test for range analysis (issue 3204).

        Performance and stability improvements on all platforms.


2014-04-07: Version 3.26.7

        Performance and stability improvements on all platforms.


2014-04-04: Version 3.26.6

        Performance and stability improvements on all platforms.


2014-04-03: Version 3.26.5

        Performance and stability improvements on all platforms.


2014-04-03: Version 3.26.4

        Make stray 'return' an early error.

        Show references from weak containers as weak in heap snapshots (Chromium
        issue 356590).

        Make invalid LHSs that are calls late errors (Chromium issue 358346).

        Performance and stability improvements on all platforms.


2014-04-02: Version 3.26.3

        Support typed arrays in IsMoreGeneralElementsKindTransition (Chromium
        issue 357054).

        Remove debugger_auto_break flag.

        Store i18n meta data in hidden symbols instead of js accessible
        properties (Chromium issue 354967).

        Performance and stability improvements on all platforms.


2014-04-01: Version 3.26.2

        Performance and stability improvements on all platforms.


2014-04-01: Version 3.26.1

        Fix Type::Intersect to skip uninhabited bitsets (Chromium issue 357330).

        Fix PrepareKeyedOperand on arm (Chromium issue 358057).

        Performance and stability improvements on all platforms.


2014-03-31: Version 3.26.0

        Deprecate Start/StopCpuProfiling methods (issue 3213).

        Don't crash if we get a timezone change notification on an uninitialized
        isolate (Chromium issue 357362).

        Performance and stability improvements on all platforms.


2014-03-28: Version 3.25.30

        NativeContext::map_cache reference should be strong in heap snapshots
        (Chromium issue 357060).

        Performance and stability improvements on all platforms.


2014-03-27: Version 3.25.29

        Performance and stability improvements on all platforms.


2014-03-27: Version 3.25.28

        Performance and stability improvements on all platforms.


2014-03-26: Version 3.25.27

        Promise constructor should not be enumerable (Chromium issue 352597).

        Performance and stability improvements on all platforms.


2014-03-26: Version 3.25.26

        Performance and stability improvements on all platforms.


2014-03-25: Version 3.25.25

        Roll ICU 239289:258359 and add support for external ICU data tables
        (issue 3142, Chromium issue 72633).

        Performance and stability improvements on all platforms.


2014-03-25: Version 3.25.24

        Add support for per-isolate private symbols.

        No longer OOM on invalid string length (issue 3060).

        Remove Failure::OutOfMemory propagation and
        V8::IgnoreOutOfMemoryException (issue 3060).

        Tentative Windows dll build fix: Don't V8_EXPORT ScriptCompiler::Source
        (issue 3228).

        Performance and stability improvements on all platforms.


2014-03-24: Version 3.25.23

        Rename A64 port to ARM64 port (Chromium issue 354405).

        Fix missing access check in Runtime_SetPrototype (Chromium issue
        354123).

        Fix polymorphic hydrogen handling of SLOPPY_ARGUMENTS_ELEMENTS (Chromium
        issue 354391).

        Performance and stability improvements on all platforms.


2014-03-20: Version 3.25.22

        Increase the "local variables in a function" limit (issue 3205).

        Implement ES6 symbol registry and predefined symbols.

        Throw exception on invalid string length instead of OOM (Chromium issue
        349329).

        Performance and stability improvements on all platforms.


2014-03-20: Version 3.25.21

        Performance and stability improvements on all platforms.


2014-03-20: Version 3.25.20

        Fix polymorphic keyed loads for SLOPPY_ARGUMENTS_ELEMENTS (Chromium
        issue 350867).

        Performance and stability improvements on all platforms.


2014-03-19: Version 3.25.19

        Performance and stability improvements on all platforms.


2014-03-19: Version 3.25.18

        Performance and stability improvements on all platforms.


2014-03-19: Version 3.25.17

        Performance and stability improvements on all platforms.


2014-03-18: Version 3.25.16

        Apply numeric casts correctly in typed arrays and related code (Chromium
        issue 353004).

        Performance and stability improvements on all platforms.


2014-03-18: Version 3.25.15

        Don't generate keyed store ICs for global proxies (Chromium issue
        352983).

        MIPS: Make invalid LHSs a parse-time (reference) error (Chromium issue
        351658).

        Make invalid LHSs a parse-time (reference) error (Chromium issue
        351658).

        Add Promises/A+ Compliance Test Suite (Chromium issue 347095).

        Split Promise API into Promise/Resolver.

        Performance and stability improvements on all platforms.


2014-03-17: Version 3.25.14

        Performance and stability improvements on all platforms.


2014-03-17: Version 3.25.13

        Move profiler callback interfaces from v8.h to v8-profiler.h.

        Performance and stability improvements on all platforms.


2014-03-14: Version 3.25.12

        PromiseCoerce should deal with an error during accessing "then"
        (Chromium issue 347095).

        Propagate updated offsets in BoundsCheckBbData (Chromium issue 350863).

        Add regression test for range analysis bug (issue 3204).

        Continued fix for 351257. Reusing the feedback vector is too complex
        (Chromium issue 351257).

        StopCpuProfiling should return non-const CpuProfile (issue 3213).

        Allow for compiling with xcode 5.1 (which doesn't have gcc anymore).

        Performance and stability improvements on all platforms.


2014-03-14: Version 3.25.11

        MIPS: Remove uses of CanBeNegative() in HMod (issue 3204).

        MIPS: Remove uses of RangeCanInclude() in flooring division by power of
        2 (issue 3204).

        MIPS: Fix uses of range analysis results in HChange (issue 3204).

        Make translation of modulus operation '--stress-opt'-proof (Chromium
        issue 352059).

        Remove uses of CanBeNegative() in HMod (issue 3204).

        Remove uses of RangeCanInclude() in flooring division by power of 2
        (issue 3204).

        Fix uses of range analysis results in HChange (issue 3204).

        Performance and stability improvements on all platforms.


2014-03-14: Version 3.25.10

        This version was not committed due to script failures.


2014-03-13: Version 3.25.9

        Reland "Enable Object.observe by default" again (issue 2409).

        Use intrinsics for builtin ArrayBuffer property accesses (Chromium issue
        351787).

        Performance and stability improvements on all platforms.


2014-03-12: Version 3.25.8

        Fix HIsSmiAndBranch::KnownSuccessorBlock() by deleting it (Chromium
        issue 351320).

        Fix handling of polymorphic array accesses with constant index (Chromium
        issue 351319).

        Fix lazy deopt after tagged binary ops (Chromium issue 350434).

        MIPS: Cleanup some of the range uses in ModI/DivI (issue 3204).

        Fix issue with getOwnPropertySymbols and hidden properties (Chromium
        issue 350864).

        Cleanup some of the range uses in ModI/DivI (issue 3204).

        PromiseCoerce should ignore primitive values (Chromium issue 347095).

        Use a per-isolate cache for the date object JS bits (Chromium issue
        348856).

        Performance and stability improvements on all platforms.


2014-03-11: Version 3.25.7

        Promise.all and Promise.race should reject non-array parameter (Chromium
        issue 347453).

        Promise.all and Promise race should use "then" rather than "chain"
        (Chromium issue 347427).

        Merge the "Compute Minus Zero Checks" phase into the range analysis
        (issue 3204).

        Performance and stability improvements on all platforms.


2014-03-10: Version 3.25.6

        Replace the recursion in PropagateMinusZeroChecks() with a loop and a
        worklist (issue 3204).

        Reland "Enable Object.observe by default" (issue 2409).

        Enable Object.observe by default (issue 2409).

        AllocationTracker now maintains a map from address range to stack trace
        that allocated the range. When snapshot is generated the map is used to
        find construction stack trace for an object using its address (Chromium
        issue 277984).

        Introduce Runtime_GetAllScopesDetails to get all scopes at once for a
        frame (Chromium issue 340285).

        Reduce heavy runtime calls from debug mirrors (Chromium issue 340285).

        Check and clear date cache in DateCurrentTime, DateLocalTimezone and
        getTimezoneOffset (Chromium issue 142141).

        Performance and stability improvements on all platforms.


2014-03-06: Version 3.25.5

        Fix HConstants with Smi-ranged HeapNumber values (Chromium issue
        349878).

        Fix issues with JSON stringify replacer array (issues 3200, 3201).

        Performance and stability improvements on all platforms.


2014-03-05: Version 3.25.4

        x64: Fix LMathMinMax for constant Smi right-hand operands (Chromium
        issue 349079).

        Performance and stability improvements on all platforms.


2014-03-04: Version 3.25.3

        Clear optimized code cache in shared function info when code gets
        deoptimized (Chromium issue 343609).

        Fixed constant folding for Math.clz32 (Chromium issue 347906).

        Fix JSObject::PrintTransitions (Chromium issue 347912).

        Fix handling of constant global variable assignments (Chromium issue
        347904).

        Removed bogus ASSERT (Chromium issue 347542).

        Mark HCompareMap as having Tagged representation (Chromium issue
        346636).

        Fix crasher in Object.getOwnPropertySymbols (Chromium issue 346141).

        Fix the bit massaging code in CompleteParserRecorder::WriteNumber
        (Chromium issue 346221).

        Don't eliminate loads with incompatible types or representations
        (Chromium issue 346343).

        Check that after a weak callback, the handle is either dead or strong
        (Chromium issue 346061).

        Lazy preparsing vs. lazy parsing fix (Chromium issue 346207).

        Performance and stability improvements on all platforms.


2014-02-25: Version 3.25.2

        Fix the bit massaging code in CompleteParserRecorder::WriteNumber
        (Chromium issue 346221).

        Revert r19455 "Load target types and handlers before IC computation."
        (Chromium issue 346149).

        Don't eliminate loads with incompatible types or representations
        (Chromium issue 346343).

        Fix for a smi stores optimization on x64 with a regression test
        (Chromium issue 345715).

        Check that after a weak callback, the handle is either dead or strong
        (Chromium issue 346061).

        negative bounds checking on realm calls (Chromium issue 344285).

        Lazy preparsing vs. lazy parsing fix (Chromium issue 346207).

        Fix optimistic BCE to back off after deopt (issue 3176).

        Performance and stability improvements on all platforms.


2014-02-21: Version 3.25.1

        Performance and stability improvements on all platforms.


2014-02-19: Version 3.25.0

        ES6: Tighten up Object.prototype.__proto__ (issue 3064).

        Fix Hydrogen bounds check elimination (Chromium issue 344186).

        Performance and stability improvements on all platforms.


2014-02-19: Version 3.24.40

        A64: Let the MacroAssembler resolve branches to distant targets (issue
        3148).

        Fixed and improved code for integral division. Fixed and extended tests
        (issue 3151).

        MIPS: Fix assignment of function name constant (issue 3138).

        Fix assignment of function name constant (issue 3138).

        Performance and stability improvements on all platforms.


2014-02-14: Version 3.24.39

        Introduce --job-based-sweeping flag and use individual jobs for sweeping
        if set (issue 3104).

        Performance and stability improvements on all platforms.


2014-02-13: Version 3.24.38

        Merge experimental/a64 to bleeding_edge (issue 3113).

        Performance and stability improvements on all platforms.


2014-02-12: Version 3.24.37

        Fix spec violations in JSON.stringify wrt replacer array (issue 3135).

        Performance and stability improvements on all platforms.


2014-02-11: Version 3.24.36

        Fix inconsistencies wrt whitespaces (issue 3109).

        Performance and stability improvements on all platforms.


2014-02-10: Version 3.24.35

        Fix inconsistencies wrt whitespaces (issue 3109).

        Performance and stability improvements on all platforms.


2014-02-07: Version 3.24.34

        Performance and stability improvements on all platforms.


2014-02-06: Version 3.24.33

        Allow externalizing strings in old pointer space (Chromium issue
        268686).

        Performance and stability improvements on all platforms.


2014-02-05: Version 3.24.32

        Add Box object to heap profiler.

        Check the offset argument of TypedArray.set for fitting into Smi
        (Chromium issue 340125).

        Performance and stability improvements on all platforms.


2014-02-04: Version 3.24.31

        Fix short-circuiting logical and/or in HOptimizedGraphBuilder (Chromium
        issue 336148).

        Elements field of newly allocated JSArray could be left uninitialized in
        some cases (fast literal case) (Chromium issue 340124).

        Re-enable escape analysis.

        Performance and stability improvements on all platforms.


2014-02-03: Version 3.24.30

        Performance and stability improvements on all platforms.


2014-02-01: Version 3.24.29

        Performance and stability improvements on all platforms.


2014-01-31: Version 3.24.28

        Don't crash in Array.join() if the resulting string exceeds the max
        string length (Chromium issue 336820).

        Implements ES6 String.prototype.normalize method (issue 2943).

        Performance and stability improvements on all platforms.


2014-01-30: Version 3.24.27

        Performance and stability improvements on all platforms.


2014-01-29: Version 3.24.26

        ES6: Map and Set needs to normalize minus zero (issue 3069).

        Make `String.prototype.{starts,ends}With` throw when passing a regular
        expression (issue 3070).

        Performance and stability improvements on all platforms.


2014-01-28: Version 3.24.25

        Performance and stability improvements on all platforms.


2014-01-27: Version 3.24.24

        MIPS: Reduce the stack requirements of GetNoCodeAgeSequence (issue
        3111).

        Delete v8_shell target now that chrome uses d8 (Chromium issue 331585).

        ARM: Reduce the stack requirements of GetNoCodeAgeSequence (issue 3111).

        Performance and stability improvements on all platforms.


2014-01-24: Version 3.24.23

        Performance and stability improvements on all platforms.


2014-01-23: Version 3.24.22

        Fix compilation on x64 architectures (issue 3110).

        Ensure we don't overwrite transitions in SetPropertyIgnoreAttributes
        (Chromium issue 326155).

        ES6: Implement Object.setPrototypeOf (issue 2675).

        Fixed floor-of-div optimization (Chromium issue 334708).

        Performance and stability improvements on all platforms.


2014-01-22: Version 3.24.21

        Performance and stability improvements on all platforms.


2014-01-21: Version 3.24.20

        ES6: Implement Object.setPrototypeOf (issue 2675).

        Performance and stability improvements on all platforms.


2014-01-20: Version 3.24.19

        Introduce a setting to control the toolset for which d8 is compiled
        (issue 1775).

        Performance and stability improvements on all platforms.


2014-01-17: Version 3.24.18

        Performance and stability improvements on all platforms.


2014-01-16: Version 3.24.17

        Make cells pointing to JSObjects weak in optimized code (issue 2073).

        Performance and stability improvements on all platforms.


2014-01-15: Version 3.24.16

        Annotate mapped memory regions for LeakSanitizer (Chromium issue
        328552).

        Turn Runtime_MigrateInstance into Runtime_TryMigrateInstance (Chromium
        issue 315252).

        Performance and stability improvements on all platforms.


2014-01-14: Version 3.24.15

        Introduce an API mirroring the gc extension.

        Performance and stability improvements on all platforms.


2014-01-10: Version 3.24.14

        ES6: Add Object.getOwnPropertySymbols (issue 3049).

        Performance and stability improvements on all platforms.


2014-01-09: Version 3.24.13

        Add Isolate parameter to HandleScope::NumberOfHandles (Chromium issue
        324225).

        Removed v8::AssertNoGCScope.

        Performance and stability improvements on all platforms.


2014-01-08: Version 3.24.12

        Correctly handle instances without elements in polymorphic keyed
        load/store (Chromium issue 331416).

        Fix selection of popular pages in store buffer (Chromium issue 331444).

        Prepare removal of ObjectTemplate::New without Isolate parameter
        (Chromium issue 324225).

        Performance and stability improvements on all platforms.


2014-01-07: Version 3.24.11

        Remove generated makefiles on linux when running gyp_v8
        (Chromium issue 331475)

        Fix building d8 with readline support due to API changes

        Performance and stability improvements on all platforms.


2014-01-03: Version 3.24.10

        Reland r18383: More API cleanup (Chromium issue 324225).

        MIPS: Fix loading of global object in LWrapReceiver (Chromium issue
        318420).

        Performance and stability improvements on all platforms.


2014-01-02: Version 3.24.9

        Performance and stability improvements on all platforms.


2013-12-30: Version 3.24.8

        ARM: fix loading of global object in LWrapReceiver (Chromium issue
        318420).

        Fix a race between concurrent recompilation and OSR (Chromium issue
        330046).

        Turn off concurrent sweeping (issue 3071).

        Performance and stability improvements on all platforms.


2013-12-23: Version 3.24.7

        Fix small spec violation in String.prototype.split (issue 3026).

        Correctly resolve forcibly context allocated parameters in debug-
        evaluate (Chromium issue 325676).

        Introduce Function::GetBoundFunction. 

        Performance and stability improvements on all platforms.


2013-12-20: Version 3.24.6

        Performance and stability improvements on all platforms.


2013-12-19: Version 3.24.5

        Performance and stability improvements on all platforms.


2013-12-18: Version 3.24.4

        Removed all stuff marked as V8_DEPRECATED.

        Performance and stability improvements on all platforms.


2013-12-17: Version 3.24.3

        Performance and stability improvements on all platforms.


2013-12-17: Version 3.24.2

        Flush instruction cache for deserialized code objects.

        Performance and stability improvements on all platforms.


2013-12-13: Version 3.24.1

        Fix polymorphic inlined calls with migrating prototypes.

        Fixed global object leak caused by overwriting the global receiver (the
        global proxy) in the global object with the global object itself
        (Chromium issue 324812).

        Initialize Date parse cache with SMI instead of double to workaround
        sharing mutable heap numbers in snapshot (Chromium issue 280531).

        Switch armv7 setting to arm_version==7 in v8 gyp files (Chromium issue
        234135).

        Performance and stability improvements on all platforms.


2013-12-09: Version 3.24.0

        Performance and stability improvements on all platforms.


2013-12-04: Version 3.23.18

        Performance and stability improvements on all platforms.


2013-12-03: Version 3.23.17

        Performance and stability improvements on all platforms.


2013-12-02: Version 3.23.16

        Array builtins need to be prevented from changing frozen objects, and
        changing structure on sealed objects (Chromium issue 299979).

        Performance and stability improvements on all platforms.


2013-11-29: Version 3.23.15

        Fix context register allocation in LTransitionElementsKind
        (Chromium issue 324306).

        Fix bug in inlining Function.apply (Chromium issue 323942).

        Ensure that length is Smi in TypedArrayFromArrayLike constructor
        (Chromium issue 324028).

        Performance and stability improvements on all platforms.


2013-11-28: Version 3.23.14

        Shorten autogenerated error message (issue 3019).

        Performance and stability improvements on all platforms.


2013-11-27: Version 3.23.13

        Increase precision for base conversion for large integers (issue 3025).

        Flatten cons string for single character substrings (Chromium issue
        323041).

        Performance and stability improvements on all platforms.


2013-11-26: Version 3.23.12

        Performance and stability improvements on all platforms.


2013-11-25: Version 3.23.11

        Deprecate old versions of Isolate::SetData and GetData.

        Performance and stability improvements on all platforms.


2013-11-22: Version 3.23.10

        Remove preemption thread and API.
        (issue 3004)

        Performance and stability improvements on all platforms.


2013-11-21: Version 3.23.9

        API: Change AdjustAmountOfExternalAllocatedMemory calls to use int64_t
        instead of intptr_t.

        Remove deprecated v8::SetResourceConstraints without Isolate parameter.

        Remove deprecated v8-defaults.h and defaults.cc.
        (Chromium issue 312241)

        Make it possible to add more than one piece of embedder data to
        isolates.
        (Chromium issue 317398)

        Performance and stability improvements on all platforms.


2013-11-20: Version 3.23.8

        Fixed crashes exposed though fuzzing.
        (Chromium issue 320948)

        Deprecated v8::External::New without Isolate parameter.

        Made number of available threads isolate-dependent and exposed it to
        ResourceConstraints.
        (issue 2991)

        Performance and stability improvements on all platforms.


2013-11-19: Version 3.23.7

        Bugfix: dependent code field in AllocationSite was keeping code objects
        alive even after context death.
        (Chromium issue 320532)

        Fixed data view accessors to throw execptions on offsets bigger than
        size_t.
        (issue 3013)

        Performance and stability improvements on all platforms.


2013-11-18: Version 3.23.6

        Limit size of dehoistable array indices.
        (Chromium issues 319835, 319860)

        Limit the size for typed arrays to MaxSmi.
        (Chromium issue 319722)

        Performance and stability improvements on all platforms.


2013-11-15: Version 3.23.5

        Fixed missing type feedback check for Generic*String addition.
        (Chromium issue 318671)

        Fixed duplicate check in DependentCode::Insert.
        (Chromium issue 318454)

        Performance and stability improvements on all platforms.


2013-11-14: Version 3.23.4

        Fixed overflow in TypedArray initialization function.
        (Chromium issue 319120)

        Performance and stability improvements on all platforms.


2013-11-13: Version 3.23.3

        Fixed compilation with GCC 4.8.
        (issue 2767, 2149)

        Added explicit Isolate parameter to External::New.
        (Chromium issue 266838)

        Performance and stability improvements on all platforms.


2013-11-12: Version 3.23.2

        Fixed --extra-code flag for snapshot creation.
        (issue 2994)

        Fixed error message wording when instanceof throws.
        (Chromium issue 82797, issue 1593)

        Performance and stability improvements on all platforms.


2013-11-08: Version 3.23.1

        Made HCapturedObjects non-deletable for DCE. (issue 2987)

        Use a fixed random seed per default. (issue 1880, 2885)

        Fixed y-umlaut to uppercase. (issue 2984)

        Performance and stability improvements on all platforms.


2013-11-06: Version 3.23.0

        Fixed loading message from an Error object.  (Chromium issue 306220)

        Made Object.freeze/seal/preventExtensions observable. (issue 2975, 2941)

        Made snapshots reproducible. (issue 2885)

        Added missing negative dictionary lookup to NonexistentHandlerFrontend.
        (issue 2980)

        Performance and stability improvements on all platforms.


2013-10-31: Version 3.22.24

        Fixed uint32-to-smi conversion in Lithium.
        (Chromium issue 309623)

        Performance and stability improvements on all platforms.


2013-10-28: Version 3.22.23

        Renamed deprecated __attribute__((no_address_safety_analysis)) to
        __attribute__((no_sanitize_address)) (Chromium issue 311283)

        Defined DEBUG for v8_optimized_debug=2

        Performance and stability improvements on all platforms.


2013-10-25: Version 3.22.22

        Record allocation stack traces. (Chromium issue 277984,v8:2949)

        Performance and stability improvements on all platforms.


2013-10-24: Version 3.22.21

        Performance and stability improvements on all platforms.


2013-10-24: Version 3.22.20

        Made Array.prototype.pop throw if the last element is not configurable.

        Fixed HObjectAccess for loads from migrating prototypes.
        (Chromium issue 305309)

        Enabled preaging of code objects when --optimize-for-size.
        (Chromium issue 280984)

        Exposed v8::Function::GetDisplayName to public API.
        (Chromium issue 17356)

        Performance and stability improvements on all platforms.


2013-10-23: Version 3.22.19

        Fix materialization of captured objects with field tracking.
        (Chromium issue 298990)

        Performance and stability improvements on all platforms.


2013-10-22: Version 3.22.18

        Add tool to visualize machine code/lithium.

        Handle misaligned loads and stores in load elimination. Do not track
        misaligned loads and be conservative about invalidating misaligned
        stores. (issue 2934)

        Performance and stability improvements on all platforms.


2013-10-21: Version 3.22.17

        Harmony: Implement Math.trunc and Math.sign. (issue 2938)

        Performance and stability improvements on all platforms.


2013-10-21: Version 3.22.16

        Performance and stability improvements on all platforms.


2013-10-18: Version 3.22.15

        Enabled calling the SetReference* & SetObjectGroupId functions with a
        Persistent.

        Performance and stability improvements on all platforms.


2013-10-17: Version 3.22.14

        Performance and stability improvements on all platforms.


2013-10-16: Version 3.22.13

        Do not look up ArrayBuffer on global object in typed array constructor.
        (issue 2931)

        Performance and stability improvements on all platforms.


2013-10-15: Version 3.22.12

        Added histograms to track fraction of heap spaces and percentage of
        generated crankshaft code.

        Moved v8_optimized_debug default value to standalone.gypi.

        Track JS allocations as they arrive with no affection on performance
        when tracking is switched off (Chromium issue 277984).

        Performance and stability improvements on all platforms.


2013-10-14: Version 3.22.11

        Performance and stability improvements on all platforms.


2013-10-11: Version 3.22.10

        Fixed timezone issues with date-time/parse-* tests.
        (Chromium issue 2919)

        Added column getter to CpuProfileNode (Chromium issue 302537)

        Performance and stability improvements on all platforms.


2013-10-10: Version 3.22.9

        Ensure only whitelisted stubs have sse2 versions in the snapshot.
        (fix for chromium 304565)

        Implement ArrayBuffer.isView.

        Performance and stability improvements on all platforms.


2013-10-04: Version 3.22.8

        Performance and stability improvements on all platforms.


2013-10-03: Version 3.22.7

        Debug: Allow stepping into on a given call frame
        (Chromium issue 296963).

        Always use timeGetTime() for TimeTicks::Now() on Windows
        (Chromium issue 288924).

        Performance and stability improvements on all platforms.


2013-10-02: Version 3.22.6

        Performance and stability improvements on all platforms.


2013-10-01: Version 3.22.5

        Disabled externalization of sliced/cons strings in old pointer space
        (Chromium issue 276357).

        Turned on handle zapping for release builds

        Performance and stability improvements on all platforms.


2013-09-30: Version 3.22.4

        Function::Call and Object::CallAsFunction APIs should allow v8::Value as
        a receiver (issue 2915).

        Removed unnecessary mutex (Chromium issue 291236).

        Removed ArrayBufferView::BaseAddress method.

        Performance and stability improvements on all platforms.


2013-09-27: Version 3.22.3

        Added methods to enable configuration of ResourceConstraints based on
        limits derived at runtime.
        (Chromium issue 292928)

        Added -optimize-for-size flag to optimize for memory size (will be used
        by pre-aging CL), and removed the is_memory_constrained
        ResourceConstraint.
        (Chromium issue 292928)

        Performance and stability improvements on all platforms.


2013-09-26: Version 3.22.2

        Performance and stability improvements on all platforms.


2013-09-25: Version 3.22.1

        Sped up creating typed arrays from array-like objects.
        (Chromium issue 270507)

        Performance and stability improvements on all platforms.


2013-09-23: Version 3.22.0

        LiveEdit to mark more closure functions for re-instantiation when scope
        layout changes.
        (issue 2872)

        Made bounds check elimination iterative instead of recursive.
        (Chromium issue 289706)

        Turned on i18n support by default.

        Set the proper instance-type on HAllocate in BuildFastLiteral.
        (Chromium issue 284577)

        Performance and stability improvements on all platforms.


2013-09-18: Version 3.21.17

        Implemented local load/store elimination on basic blocks.

        Added mutex when accessing concurrent recompilation output queue.
        (Chromium issue 291236)

        Don't lookup the cache for the result of Function::New.
        (Chromium issue 272579)

        Tweaked HConstant::EmitAtUses() to eliminate useless constant
        generation.
        (Chromium issue 2881)

        Performance and stability improvements on all platforms.


2013-09-16: Version 3.21.16

        Every place where AllocationMemento is initialized with an
        AllocationSite is now checked to be sure a valid Site goes in. This is
        temporary code to diagnose chromium bug 284577.

        Performance and stability improvements on all platforms.


2013-09-13: Version 3.21.15

        Non-JSObject heap objects are now handled using slow-path IC stub
        guarded by the map.
        (Chromium issue 280632)

        i18n Javascript code added to the snapshot.
        (V8 issue 2745)

        Performance and stability improvements on all platforms.

2013-09-12: Version 3.21.14

        Added access check for observed objects.
        (V8 issue 2778)

        Cleaned up v8::ArrayBuffer::Allocator interface.
        (V8 issue 2823)

        Performance and stability improvements on all platforms.

2013-09-11: Version 3.21.13

        Added a ResourceConstraint for the embedder to specify that V8 is
        running on a memory constrained device.
        (Chromium issue 280984)

        Removed HandleScope default ctor.
        (Chromium issue 236173)

        Enabled escape analysis for Hydrogen.

        Correctly stringified mixed encoding indirect strings.
        (Chromium issue 287476)

        Performance and stability improvements on all platforms.


2013-09-09: Version 3.21.12

        Fixed bitwise negation on x64.
        (Chromium issue 285355)

        Dropped GetCurrentThreadId() and TerminateExecution(int) from 
	the external API.

        Fixed polymorphic INTERCEPTOR StoreICs on ARM/MIPS.
        (Chromium issue 284998)

        Added check if timeout has expired after processing each sample.
        (issue 2814,v8:2871)

        Removed obsolete global V8::has_been_fooed flags.
        (issue 2744)

        Performance and stability improvements on all platforms.


2013-09-05: Version 3.21.11

        Performance and stability improvements on all platforms.


2013-09-04: Version 3.21.10

        Fixed Eternal::IsEmpty logic (issue 2870).

        Performance and stability improvements on all platforms.


2013-09-03: Version 3.21.9

        Deprecated Persistent functions which were marked to be deprecated.

        Allowed uncacheable identifiers to go generic (issue 2867).

        Performance and stability improvements on all platforms.


2013-09-02: Version 3.21.8

        Added scriptId to StackTrace frames (issue 2865).

        Performance and stability improvements on all platforms.


2013-08-30: Version 3.21.7

        Fixed casts of eternal handles.

        Turned on global handle zapping.

        Always visit branches during HGraph building (Chromium issue 280333).

        Profiler changes: removed deprecated API, support higher sampling
        rate on Windows.

        Performance and stability improvements on all platforms.


2013-08-29: Version 3.21.6

        Fixed inlined 'throw' statements interfering with live range
        computation. (issue 2843)

        Performance and stability improvements on all platforms.


2013-08-28: Version 3.21.5

        Fixed compilation with recent MinGW64 versions. (issue 2300)

        Added RemovePrototype to FunctionTemplate. (Chromium issue 272440)

        Performance and stability improvements on all platforms.


2013-08-26: Version 3.21.4

        Lowered kInitialMaxFastElementArray constant to 95K (issue 2790).

        Use signals for cpu profiling on Mac OS X (issue 2814).

        Deprecated CpuProfileNode::GetSelfSamplesCount (Chromium issue 267595).

        Added support for higher CPU profiler sampling rate on posix systems
        (issue 2814).

        Worked around 'inlining failed' build error with older GCC 4.x releases.

        Added source map support to tick processor.

        Stability improvements on all platforms.


2013-08-23: Version 3.21.3

        Temporarily disabled optimization for StringWrappers to use native
        valueOf. (issue 2855)

        Fixed crash on function declarations in eval inside non-trivial local
        scope. (issue 2594)

        Rewrote SamplingCircularQueue. (issue 2814)

        Fixed hidden properties on object with frozen prototype. (issue 2829)

        Fix deoptimization bug. (Chromium issue 274164)

        Stability improvements on all platforms.


2013-08-22: Version 3.21.2

        Stability improvements on all platforms.


2013-08-21: Version 3.21.1

        Promoted ArrayBuffer, DataView and typed arrays to non-experimental.
        (Chromium issue 270527)

        Replaced OS::MemCopy with memcpy in typed array initialization.
        (Chromium issue 270642)

        Moved i18n break iterator C++ code to runtime (issue 2745)

        Fixed invalid out-of-bounds store in MacroAssembler::Allocate.
        (Chromium issue 263515)

        Fixed register misuse in Allocate() on ARM. (issue 2851)

        Fixed empty handle dereference in Runtime_InternalNumberFormat.
        (Chromium issue 275467)

        Performance and stability improvements on all platforms.


2013-08-19: Version 3.21.0

        Fixed GC-related crasher (Chromium issue 274438)

        Reverted making Intl non-enumerable.

        Performance and stability improvements on all platforms.


2013-08-14: Version 3.20.17

        Fixed Math.round/floor that had bogus Smi representation
        (Chromium issue 272564)

        Performance and stability improvements on all platforms.


2013-08-13: Version 3.20.16

        Fixed bug in HPhi::SimplifyConstantInput (Chromium issue 269679)

        Fixed gcmole bugs in i18n code (issue 2745)

        ia32: Calls to the TranscendentalCacheStub must ensure that esi is
        set (issue 2827)

        Made sure polymorphic element access creates non-replaying
        phis. (issue 2815)

        Allowed HPhis to have an invalid merge index. (issue 2815)

        Fixed smi-based math floor. (Chromium issue 270268)

        Deprecated self and total time getters and total sample count
        getter on CpuProfileNode. (Chromium issue 267595)

        Fixed Object.freeze, Object.observe wrt CountOperation and
        CompoundAssignment. (issue 2774,2779)

        Performance and stability improvements on all platforms.


2013-08-07: Version 3.20.15

        Exposed eternal handle api.

        Bugfix to solve issues with enabling V8 typed arrays in Blink.

        Fixed Array index dehoisting.  (Chromium issue 264203)

        Updated Array Iterator to use numeric indexes (issue 2818)

        Return start/end profiling time in microseconds instead of milliseconds
        (issue 2824)

        Performance and stability improvements on all platforms.


2013-08-06: Version 3.20.14

        Added new Harmony methods to Array.prototype object.
        (issue 2776,v8:2777)

        Performance and stability improvements on all platforms.


2013-08-01: Version 3.20.12

        Removed buggy ToNumber truncation (partial fix for issue 2813)

        Calling Map etc without new should throw TypeError (issue 2819)

        Fixed a crash for large code objects on ARM (Chromium issue 2736)

        Fixed stale unhandlified value in JSObject::SetPropertyForResult.
        (Chromium issue 265894)

        Added new Harmony methods to String.prototype object.
        (issue 2796,v8:2797,v8:2798,v8:2799)

        Performance and stability improvements on all platforms.


2013-07-30: Version 3.20.11

        Performance and stability improvements on all platforms.


2013-07-29: Version 3.20.10

        Performance and stability improvements on all platforms.


2013-07-26: Version 3.20.9

        Check that ExternalString objects get aligned resources.

        Fixed JSArray-specific length lookup in polymorphic array handling
        (Chromium issues 263276, 263905).

        Performance and stability improvements on all platforms.


2013-07-24: Version 3.20.8

        Deprecated v8::V8::Pause/ResumeProfiler.

        Fixed Chromium issues 247688, 258519 and 260203.

        Performance and stability improvements on all platforms.


2013-07-22: Version 3.20.7

        Deprecated some debugger methods.

        Fixed wrong bailout id in polymorphic stores (Chromium issue 259787).

        Fixed data race in SamplingCircularQueue (Chromium issue 251218).

        Fixed type feedback in presence of negative lookups
        (Chromium issue 252797).

        Do not materialize context-allocated values for debug-evaluate
        (Chromium issue 259300).

        Synchronized Compare-Literal behavior in FullCodegen and Hydrogen
        (Chromium issue 260345).

        Performance and stability improvements on all platforms.


2013-07-17: Version 3.20.6

        Try to remove invalidated stubs before falling back to checking the
        constant state (Chromium issue 260585).

        Fixed gyp_v8 to work with use_system_icu=1 (issue 2475).

        Fixed sloppy-mode 'const' under Harmony flag (Chromium issue 173361).

        Use internal array as API function cache  (Chromium issue 260106).

        Fixed possible stack overflow in range analysis
        (Chromium issue 259452).

        Performance and stability improvements on all platforms.


2013-07-15: Version 3.20.5

        Ensured that the length of frozen arrays is immutable
        (issue 2711, Chromium issue 259548).

        Performance and stability improvements on all platforms.


2013-07-10: Version 3.20.4

        Fixed garbage-collection issue that causes a crash on ARM
        (Chromium issue 254570)

        Performance and stability improvements on all platforms.


2013-07-08: Version 3.20.3

        Performance and stability improvements on all platforms.


2013-07-05: Version 3.20.2

        Remove deprecated heap profiler methods from V8 public API

        Mark i18n functions as native and set proper names
        (issue 2745)

        Correctly report stack trace when current function is FunctionApply
        builtin (Chromium issue 252097)

        Enable GDBJIT interface for standalone by default.

        Fix debuggersupport=off build. (issue 2754)

        Introduce -m64 flag for making x64 when the default gcc compiler is for
        X32

        Performance and stability improvements on all platforms.


2013-07-02: Version 3.20.1

        Implemented WeakMap.prototype.clear function. (issue 2753)

        Ensure CheckInitialized is present independent of define.
        (Chromium issue 255779)

        Performance and stability improvements on all platforms.


2013-06-28: Version 3.20.0

        Migrated several tests from blink to V8 repository.

        Allowed users of the V8 API to distinguish between unset and undefined
        HiddenValues (issue 2746).

        Deprecated old style callbacks in the V8 API.

        Turned on parallel recompilation.

        Performance and stability improvements on all platforms.


2013-06-18: Version 3.19.18

	Fixed read-only attribute of Function.length in strict mode.
	(issue 2705)

	Fixed Runtime_SetProperty to properly handle OOM failures
	(Chromium issue 249873)

	Emit deprecated check for constant function transitions.
	(Chromium issue 250609)
	
	Made MathFloorOfDiv optimization trigger more often
	(Issue 2205)

	Make more GCs in idle notification handler.
	(Chromium issue 241815)

	Increased default type info threshold.
	(Issue 2730)

        Performance and stability improvements on all platforms.


2013-06-14: Version 3.19.16

        Performance and stability improvements on all platforms.


2013-06-13: Version 3.19.15

        Performance and stability improvements on all platforms.


2013-06-13: Version 3.19.14

        Fixed crashes when calling new Array(a) with a single argument that
        could result in creating a holey array with a packed elements kind.
        (Chromium issue 245480)

        Fixed issues in parallel compilation.
        (Chromium issue 248076)

        Performance and stability improvements on all platforms.


2013-06-11: Version 3.19.13

        Performance and stability improvements on all platforms.


2013-06-10: Version 3.19.12

        Fixed arguments array access. (Chromium issue 247303)

        Fixed bug in LookupForWrite. (Chromium issue 242332)

        Performance and stability improvements on all platforms.


2013-06-07: Version 3.19.11

        Performance and stability improvements on all platforms.


2013-06-06: Version 3.19.10

        Performance and stability improvements on all platforms.


2013-06-05: Version 3.19.9

        Implemented Load IC support for loading properties from primitive
        values to avoid perpetual soft deopts.  (Chromium issue 242512)

        Implemented Freeing of PerThreadAssertData when possible to avoid
        memory leak. (Chromium issue 246567)

        Removed V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS.

        Performance and stability improvements on all platforms.


2013-06-03: Version 3.19.8

        Fixed bug with inlining 'Array' function. (Chromium issue 244461)

        Fixed initialization of literal objects. (Chromium issue 245424)

        Fixed function name inferred inside closures. (Chromium issue 224884)

        Performance and stability improvements on all platforms.


2013-05-31: Version 3.19.7

        Added support for //# sourceURL similar to deprecated //@ sourceURL one.
        (issue 2702)

        Made sure IfBuilder::Return clears the current block.
        (Chromium issue 243868)

        Fixed two CPU profiler tests on ARM and MIPS simulators
        (issue 2628)

        Fixed idle incremental GC for large objects.
        (Chromium issue 241815)

        Disabled --optimize-constructed-arrays due to crashes
        (Chromium issue 244461)

        Performance and stability improvements on all platforms.


2013-05-28: Version 3.19.6

        Fixed IfBuilder::Deopt to clear the current block
        (Chromium issue 243868).

        Performance and stability improvements on all platforms.


2013-05-27: Version 3.19.5

        Reset regexp parser flag after scanning ahead for capture groups.
        (issue 2690)

        Removed flakiness in test-cpu-profiler/SampleWhenFrameIsNotSetup.
        (issue 2628)

        Performance and stability improvements on all platforms.


2013-05-24: Version 3.19.4

        Fixed edge case in stack trace formatting. (Chromium issue 237617)

        Fixed embedded new-space pointer in LCmpObjectEqAndBranch. (Chromium
	issue 240032)

        Made Object.freeze fast (issue 1858, Chromium issue 115960)

        Fixed bogus deopt in BuildEmitDeepCopy for holey arrays. (Chromium issue
        242924)

        Performance and stability improvements on all platforms.


2013-05-22: Version 3.19.3

        Performance and stability improvements on all platforms.


2013-05-17: Version 3.19.2

        Fill in one-word-fillers for the unused property fields
        (Chromium issue 240056).

        Removed use_system_v8 logic from the mainline gyp file
        (Chromium issue 226860).

        Skip CPU profiler samples where top function's stack frame is not
        set up properly (issue 2628).

        Performance and stability improvements on all platforms.


2013-05-14: Version 3.19.1

        Fixed missing hole check for loads from Smi arrays when all uses are
        changes (Chromium issue 233737)

        Performance and stability improvements on all platforms.


2013-05-10: Version 3.19.0

        Deprecated Context::New which returns Persistent.

        Added Persistent::Reset which disposes the handle and redirects it to
        point to another object.

        Deprecated WriteAscii and MayContainNonAscii.

        Exposed AssertNoAllocation to API.

        Performance and stability improvements on all platforms.


2013-04-30: Version 3.18.5

        Allowed setting debugger breakpoints on CompareNilICs (issue 2660)

        Fixed beyond-heap load on x64 Crankshafted StringCharFromCode
        (Chromium issue 235311)

        Change 'Parse error' to three more informative messages.
        (Chromium issue 2636)

        Performance and stability improvements on all platforms.


2013-04-26: Version 3.18.4

        Added a preliminary API for ES6 ArrayBuffers

        Replaced qsort with std::sort. (Chromium issue 2639)

        Performance and stability improvements on all platforms.


2013-04-24: Version 3.18.3

        Exposed the GC under a name that is less collision prone than window.gc.
        (issue 2641)

        Do not emit double values at their use sites. (Chromium issue 234101)

        Added methods to allow resuming execution after calling
        TerminateExecution(). (issue 2361)

        Performance and stability improvements on all platforms.


2013-04-22: Version 3.18.2

        OS::MemMove/OS::MemCopy: Don't call through to generated code when size
        == 0 to avoid prefetching invalid memory (Chromium issue 233500)

        Removed heap snapshot size limit. (Chromium issue 232305)

        Performance and stability improvements on all platforms.


2013-04-18: Version 3.18.1

        Removed SCons related files and deprecated test suite configurations.

        Improved handling of unary plus (issue 2527).

        Performance and stability improvements on all platforms.


2013-04-17: Version 3.18.0

        Enabled pretenuring of fast literals in high promotion mode.

        Removed preparser library; link preparser executable against full V8.

        Fixed set-up of intrinsic's 'constructor' properties.
        (Chromium issue 229445)

        ES6 symbols: extended V8 API to support symbols (issue 2158).

        Removed ARM support for VFP2.

        Made __proto__ a real JavaScript accessor property.
        (issue 1949 and issue 2606)

        Performance and stability improvements on all platforms.


2013-04-04: Version 3.17.16

        Stack trace API: poison stack frames below the first strict mode frame.
        (issue 2564)

        Made Isolate::GetHeapStatistics robust against half-initialized
        isolates (Chromium issue 2591).

        Finished implementation of ES6 symbols aka. private names (issue 2158).

        Performance and stability improvements on all platforms.


2013-03-21: Version 3.17.15

        Rolled back API changes to maintain compatibility with older
        3.17.x versions of V8.

        Disable zapping of global handles in release mode.

        Always mark the entire valid prefix of the descriptor array.
        (Chromium issue 196331)

        Use internal memcpy for CopyWords and when copying code.
        (Chromium issue 196330)

        Performance and stability improvements on all platforms.


2013-03-20: Version 3.17.14

        Use internal memcpy when initializing code objects.
        (Chromium issue 196330)

        Disabled weak embedded maps because of crashes.
        (Chromium issues 172489, 217858)

        Performance and stability improvements on all platforms.


2013-03-19: Version 3.17.13

        Turned Flags into a uint32_t typedef (Chromium issue 194749).

        Performance and stability improvements on all platforms.


2013-03-18: Version 3.17.12

        Unified kMaxArguments with number of bits used to encode it.
        (Chromium issue 211741)

        Fixed detection of |handle_smi| case in
        HOptimizedGraphBuilder::HandlePolymorphicCallNamed.
        (Chromium issue 196583)

        Performance and stability improvements on all platforms.


2013-03-15: Version 3.17.11

        Added a version of the v8::HandleScope constructor with an v8::Isolate
        parameter and made AdjustAmountOfExternalAllocatedMemory an instance
        method of v8::Isolate.
        (issue 2487)

        Fixed two register allocator bugs (off-by-one error/failure
        propagation). (issue 2576)

        Fixed huge heap snapshot when a heavily shared context has many
        variables. (Chromium issue 145687)

        Performance and stability improvements on all platforms.


2013-03-13: Version 3.17.10

        Fixed heap snapshot creation for Harmony collections. (issue 2535)

        Fixed register allocation corner case. (Chromium issue 177883)

        Performance and stability improvements on all platforms.


2013-03-08: Version 3.17.9

        Restored Function()'s expected string representation. (issue 2470)

        Enabled deprecatations (again). (issue 2487)

        Avoid bool to Oddball conversions by being lazy. (issue 2491)

        Added %p option to --logfile.

        Hardened Function()'s parsing of function literals. (issue 2470)

        ES6 symbols: Refine test for getOwnPropertyNames. (issue 2158)

        Performance and stability improvements on all platforms.


2013-03-07: Version 3.17.8

        Added missing license headers. (Chromium issue 98597)

        Inserted missing type cast in JSON.stringify. (issue 2570)

        Reverted "Send SIGPROF signals on the profiler event processor thread"
        (issue 2571)

        Fixed Array.length, String.length and Function.prototype LoadICs on x64.
        (issue 2568)

        ES6 symbols: filter symbols form for-in loops and Object.keys.
        (issue 2158)

        Properly handle misses for StoreArrayLengthStub on ia32 and x64
        (issue 2566)

        Fixed x32 handling of Atomic64. (Chromium issue chromium-os:36866)

        Removed "library" variable from standalone.gypi. (Chromium issue 111541)

        Fixed HCheckSmiOrInt <-> HBoundsCheck interaction wrt. representations.
        (issue 2556)

        Enabled zapping of disposed global handles in release mode.
        (Chromium issue 176056)

        Added workaround for redefinition of __proto__ property. (issue 2565)

        ES6 symbols: Allow symbols as property names. (issue 2158)

        Performance and stability improvements on all platforms.


2013-03-04: Version 3.17.7

        Limited recursion in regexp compilation by a budget.
        (Chromium issue 178790)

        ES6 symbols: Implemented Symbol intrinsic and basic functionality
        (issue 2158)

        Performance and stability improvements on all platforms.


2013-02-28: Version 3.17.6

        Fixed materialization of arguments objects with unknown values.
        (Chromium issue 163530)

        Set default number of sweeper threads to at most four.

        Performance and stability improvements on all platforms.


2013-02-27: Version 3.17.5

        Made __proto__ a foreign callback on Object.prototype.
        (issue 621, issue 1949 and issue 2441)

        Performance and stability improvements on all platforms.


2013-02-25: Version 3.17.4

        Performance and stability improvements on all platforms.


2013-02-21: Version 3.17.3

        Performance and stability improvements on all platforms.


2013-02-19: Version 3.17.2

        Removed bogus check for TOP register in deoptimizer.
        (Chromium issue 176943)

        Made the Isolate parameter mandatory for internal HandleScopes.
        (issue 2487)

        Fixed f.apply() optimization when declared arguments are mutated.
        (issue 2539)

        Performance and stability improvements on all platforms.


2013-02-14: Version 3.17.1

        Performance and stability improvements on all platforms.


2013-02-13: Version 3.17.0

        Enabled parallel sweeping.

        Don't try to unlink instructions twice during GVN
        (Chromium issue 175141)

        Fixed code flusher disabling while marking incrementally.
        (Chromium issue 173458, 168582)

        Don't use TLS for space iterators.
        (issue 2531)

        Added new GetHeapStatistics API entry and deprecated old one.

        Fixed DoubleStackSlot-to-DoubleStackSlot moves on ia32. Unified
        platform-independent code.
        (Chromium issue 173907)

        Added --trace-array-abuse to help find OOB accesses.

        Performance and stability improvements on all platforms.


2013-02-06: Version 3.16.14

        Performance and stability improvements on all platforms.


2013-02-04: Version 3.16.13

        Tagged stubs that rely on instance types as MEGAMORPHIC.
        (Chromium issue 173974)

        Fixed clearing of dead dependent codes and verifing of weak
        embedded maps on full GC. (Chromium issue 172488,172489)

        Made the arm port build cleanly with Clang.

        Performance and stability improvements on all platforms.


2013-01-31: Version 3.16.12

        Performance and stability improvements on all platforms.


2013-01-30: Version 3.16.11

        Put making embedded maps in optimized code weak behind a flag.
        (Chromium issue 172488,172489)

        Performance and stability improvements on all platforms.


2013-01-25: Version 3.16.10

        Avoid excessive memory usage during redundant phi elimination.
        (issue 2510)

        Fixed additional spec violations wrt RegExp.lastIndex.
        (issue 2437)

        Added Isolate parameter to Persistent class.
        (issue 2487)

        Performance and stability improvements on all platforms.


2013-01-24: Version 3.16.9

        Made embedded maps in optimized code weak.
        (issue 2073)

        Fixed corner case when JSFunction is evicted from flusher.
        (Chromium issue 168801)

        Correctly set kCanBeDivByZero flag for HMathFloorOfDiv.
        (Chromium issue 171641)

        Performance and stability improvements on all platforms.


2013-01-23: Version 3.16.8

        Correctly reset lastIndex in an RegExp object.
        (Chromium issue 170856)

        Added a workaround for Windows compilation problems related to V8EXPORT.
        (issue 2507)

        tools/run-tests.py: shlex.split() the value of --command-prefix
        (Chromium issue 171553)

        Fixed pattern detection for replacing shifts by rotation.
        (Chromium issue 2499)

        Performance and stability improvements on all platforms.


2013-01-21: Version 3.16.7

        Removed <(library) usage from v8.gyp.
        (Chromium issue 111541)

        Fixed out of bounds memory access in TestJSArrayForAllocationSiteInfo.
        (Chromium issue 169928)

        Performance and stability improvements on all platforms.


2013-01-18: Version 3.16.6

        Made the Isolate parameter mandatory in Locker and Unlocker classes.
        (issue 2487)

        Avoid pointer underflow in CopyCharsUnsigned.
        (issue 2493)

        Generate shim headers when using system v8.
        (Chromium issue 165264)

        Fixed arguments materialization for inlined apply().
        (issue 2489)

        Sync'ed laziness between BuildFunctionInfo and MakeFunctionInfo.
        (Chromium issue 147497)

        Added sanity check to CodeFlusher::AddCandidate.
        (Chromium issue 169209)

        Performance and stability improvements on all platforms.


2013-01-15: Version 3.16.5

        Removed deprecated functions from V8's external API.

        Prepared API for WebKit use of Latin-1.

        Fixed V8 issue 2486.

        Fixed Chromium issue 169723.

        Performance and stability improvements on all platforms.


2013-01-11: Version 3.16.4

        Fixed Chromium issues 168545 and 169209.

        Performance and stability improvements on all platforms.


2013-01-09: Version 3.16.3

        Improved GC performance when moving parts of a FixedArray (issue 2452).

        Enabled readline on d8 while building a shared lib (issue 1781).

        Fixed missing exception check in typed array constructor
        (Chromium issue 168545).

        Check for read-only-ness when preparing for array sort (issue 2419).

        Performance and stability improvements on all platforms.


2013-01-04: Version 3.16.2

        Added Makefile options to build for the Raspberry Pi (armv7=0,
        arm_fpu=vfp2).

        Performance and stability improvements on all platforms.


2012-12-27: Version 3.16.1

        Fixed x64 MathMinMax for negative untagged int32 arguments.
        (Chromium issue 164442)

        Fixed FloatingPointHelper::CheckSSE2OperandIsInt32.
        (issue 2458)

        Performance and stability improvements on all platforms.


2012-12-21: Version 3.16.0

        V8_Fatal now prints C++ stack trace in debug mode.

        Added HTML-based tick processor.

        Continued implementation of Object.observe (V8 issue 2409).

        Fixed V8 issues 2243, 2340, 2393, 2399, 2457.

        Fixed Chromium issues 125308, 165637, 166379, 166553.

        Performance and stability improvements on all platforms.


2012-12-10: Version 3.15.11

        Define CAN_USE_VFP2/3_INSTRUCTIONS based on arm_neon and arm_fpu GYP
        flags.

        Performance and stability improvements on all platforms.


2012-12-07: Version 3.15.10

        Enabled optimisation of functions inside eval. (issue 2315)

        Fixed spec violations in methods of Number.prototype. (issue 2443)

        Added GCTracer metrics for a scavenger GC for DOM wrappers.

        Performance and stability improvements on all platforms.


2012-12-06: Version 3.15.9

        Fixed candidate eviction in code flusher.
        (Chromium issue 159140)

        Iterate through all arguments for side effects in Math.min/max.
        (issue 2444)

        Fixed spec violations related to regexp.lastIndex
        (issue 2437, issue 2438)

        Performance and stability improvements on all platforms.


2012-12-04: Version 3.15.8

        Enforced stack allocation of TryCatch blocks.
        (issue 2166,chromium:152389)

        Fixed external exceptions in external try-catch handlers.
        (issue 2166)

        Activated incremental code flushing by default.

        Performance and stability improvements on all platforms.


2012-11-30: Version 3.15.7

        Activated code aging by default.

        Included more information in --prof log.

        Removed eager sweeping for lazy swept spaces. Try to find in
        SlowAllocateRaw a bounded number of times a big enough memory slot.
        (issue 2194)

        Performance and stability improvements on all platforms.


2012-11-26: Version 3.15.6

        Ensure double arrays are filled with holes when extended from
        variations of empty arrays. (Chromium issue 162085)

        Performance and stability improvements on all platforms.


2012-11-23: Version 3.15.5

        Fixed JSON.stringify for objects with interceptor handlers.
        (Chromium issue 161028)

        Fixed corner case in x64 compare stubs. (issue 2416)

        Performance and stability improvements on all platforms.


2012-11-16: Version 3.15.4

        Fixed Array.prototype.join evaluation order. (issue 2263)

        Perform CPU sampling by CPU sampling thread only iff processing thread
        is not running. (issue 2364)

        When using an Object as a set in Object.getOwnPropertyNames, null out
        the proto. (issue 2410)

        Disabled EXTRA_CHECKS in Release build.

        Heap explorer: Show representation of strings.

        Removed 'type' and 'arguments' properties from Error object.
        (issue 2397)

        Added atomics implementation for ThreadSanitizer v2.
        (Chromium issue 128314)

        Fixed LiveEdit crashes when object/array literal is added. (issue 2368)

        Performance and stability improvements on all platforms.


2012-11-13: Version 3.15.3

        Changed sample shell to send non-JS output (e.g. errors) to stderr
        instead of stdout.

        Correctly check for stack overflow even when interrupt is pending.
        (issue 214)

        Collect stack trace on stack overflow. (issue 2394)

        Performance and stability improvements on all platforms.


2012-11-12: Version 3.15.2

        Function::GetScriptOrigin supplies sourceURL when script name is
        not available.  (Chromium issue 159413)

        Made formatting error message side-effect-free.  (issue 2398)

        Fixed length check in JSON.stringify.  (Chromium issue 160010)

        ES6: Added support for Set and Map clear method (issue 2400)

        Fixed slack tracking when instance prototype changes.
        (Chromium issue 157019)

        Fixed disabling of code flusher while marking.  (Chromium issue 159140)

        Added a test case for object grouping in a scavenger GC (issue 2077)

        Support shared library build of Android for v8.
        (Chromium issue 158821)

        ES6: Added support for size to Set and Map (issue 2395)

        Performance and stability improvements on all platforms.


2012-11-06: Version 3.15.1

        Put incremental code flushing behind a flag. (Chromium issue 159140)

        Performance and stability improvements on all platforms.


2012-10-31: Version 3.15.0

        Loosened aligned code target requirement on ARM (issue 2380)

        Fixed JSON.parse to treat leading zeros correctly.
        (Chromium issue 158185)

        Performance and stability improvements on all platforms.


2012-10-22: Version 3.14.5

        Killed off the SCons based build.

        Added a faster API for creating v8::Integer objects.

        Speeded up function deoptimization by avoiding quadratic pass over
        optimized function list. (Chromium issue 155270)

        Always invoke the default Array.sort functions from builtin functions.
        (issue 2372)

        Reverted recent CPU profiler changes because they broke --prof.
        (issue 2364)

        Switched code flushing to use different JSFunction field.
        (issue 1609)

        Performance and stability improvements on all platforms.


2012-10-15: Version 3.14.4

        Allow evals for debugger even if they are prohibited in the debugee
        context. (Chromium issue 154733)

        Enabled --verify-heap in release mode (issue 2120)

        Performance and stability improvements on all platforms.


2012-10-11: Version 3.14.3

        Use native context to retrieve ErrorMessageForCodeGenerationFromStrings
        (Chromium issue 155076).

        Bumped variable limit further to 2^17 (Chromium issue 151625).

        Performance and stability improvements on all platforms.


2012-10-10: Version 3.14.2

        ARM: allowed VFP3 instructions when hardfloat is enabled.
        (Chromium issue 152506)

        Fixed instance_descriptors() and PushStackTraceAndDie regressions.
        (Chromium issue 151749)

        Made GDBJIT interface compile again. (issue 1804)

        Fixed Accessors::FunctionGetPrototype's proto chain traversal.
        (Chromium issue 143967)

        Made sure that names of temporaries do not clash with real variables.
        (issue 2322)

        Rejected local module declarations. (Chromium issue 150628)

        Rejected uses of lexical for-loop variable on the RHS. (issue 2322)

        Fixed slot recording of code target patches.
        (Chromium issue 152615,chromium:144230)

        Changed the Android makefile to use GCC 4.6 instead of GCC 4.4.3.

        Performance and stability improvements on all platforms.


2012-10-01: Version 3.14.1

        Don't set -m32 flag when compiling with Android ARM compiler.
        (Chromium issue 143889)

        Restore the descriptor array before returning allocation failure.
        (Chromium issue 151750)

        Lowered kMaxVirtualRegisters (v8 issue 2139, Chromium issues 123822 and
        128252).

        Pull more recent gyp in 'make dependencies'.

        Made sure that the generic KeyedStoreIC changes length and element_kind
        atomically (issue 2346).

        Bumped number of allowed variables per scope to 65535, to address GWT.
        (Chromium issue 151625)

        Support sourceURL for dynamically inserted scripts (issue 2342).

        Performance and stability improvements on all platforms.


2012-09-20: Version 3.14.0

        Fixed missing slot recording during clearing of CallICs.
        (Chromium issue 144230)

        Fixed LBoundsCheck on x64 to handle (stack slot + constant) correctly.
        (Chromium issue 150729)

        Fixed minus zero test. (Issue 2133)

        Fixed setting array length to zero for slow elements.
        (Chromium issue 146910)

        Fixed lost arguments dropping in HLeaveInlined.
        (Chromium issue 150545)

        Fixed casting error for receiver of interceptors.
        (Chromium issue 149912)

        Throw a more descriptive exception when blocking 'eval' via CSP.
        (Chromium issue 140191)

        Fixed debugger's eval when close to stack overflow. (issue 2318)

        Added checks to live edit. (issue 2297)

        Switched on code compaction on incremental GCs.

        Fixed caching of optimized code for OSR. (issue 2326)

        Not mask exception thrown by toString in String::UtfValue etc.
        (issue 2317)

        Fixed API check for length of external arrays. (Chromium issue 148896)

        Ensure correct enumeration indices in the dict (Chromium issue 148376)

        Correctly initialize regexp global cache. (Chromium issue 148378)

        Fixed arguments object materialization during deopt. (issue 2261)

        Introduced new API to expose external string resource regardless of
        encoding.

        Fixed CHECK failure in LCodeGen::DoWrapReceiver when
        --deopt-every-n-times flag is present
        (Chromium issue 148389)

        Fixed edge case of extension with NULL as source string.
        (Chromium issue 144649)

        Fixed array index dehoisting. (Chromium issue 141395)

        Performance and stability improvements on all platforms.


2012-09-11: Version 3.13.7

        Enable/disable LiveEdit using the (C++) debug API.

        Performance and stability improvements on all platforms.


2012-09-06: Version 3.13.6

        Added validity checking to API functions and calls.

        Disabled accessor inlining (Chromium issue 134609).

        Fixed bug in Math.min/max in optimized code (Chromium issue 145961).

        Directly use %ObjectKeys in json stringify (Chromium issue 2312).

        Fixed VS2005 build (issue 2313).

        Activated fixed ES5 readonly semantics by default.

        Added hardfp flag to the Makefile.

        Performance and stability improvements on all platforms.


2012-08-29: Version 3.13.5

        Release stack trace data after firing Error.stack accessor.
        (issue 2308)

        Added a new API V8::SetJitCodeEventHandler to push code name and
        location to users such as profilers.

        Allocate block-scoped global bindings to global context.

        Performance and stability improvements on all platforms.


2012-08-28: Version 3.13.4

        Print reason for disabling optimization. Kill --trace-bailout flag.

        Provided option to disable full DEBUG build on Android.

        Introduced global contexts to represent lexical global scope(s).

        Fixed rounding in Uint8ClampedArray setter. (issue 2294)

        Performance and stability improvements on all platforms.


2012-08-21: Version 3.13.3

        Performance and stability improvements on all platforms.


2012-08-20: Version 3.13.2

        Performance and stability improvements on all platforms.


2012-08-16: Version 3.13.1

        Performance and stability improvements on all platforms.


2012-08-10: Version 3.13.0

        Added histograms for total allocated/live heap size, as well as
        allocated size and percentage of total for map and cell space.

        Fixed parseInt's octal parsing behavior (ECMA-262 Annex E 15.1.2.2).
        (issue 1645)

        Added checks for interceptors to negative lookup code in Crankshaft.
        (Chromium issue 140473)

        Made incremental marking clear ICs and type feedback cells.

        Performance and stability improvements on all platforms.


2012-08-01: Version 3.12.19

        Performance and stability improvements on all platforms.


2012-07-30: Version 3.12.18

        Forced using bit-pattern for signed zero double. (issue 2239)

        Made sure double to int conversion is correct. (issue 2260)

        Performance and stability improvements on all platforms.


2012-07-27: Version 3.12.17

        Always set the callee's context when calling a function from optimized
        code.
        (Chromium issue 138887)

        Fixed building with GCC 3.x
        (issue 2016, 2017)

        Improved API calls that return empty handles.
        (issue 2245)

        Performance and stability improvements on all platforms.


2012-07-25: Version 3.12.16

        Performance and stability improvements on all platforms.


2012-07-24: Version 3.12.15

        Added PRESERVE_ASCII_NULL option to String::WriteAscii.
        (issue 2252)

        Added dependency to HLoadKeyed* instructions to prevent invalid
        hoisting. (Chromium issue 137768)

        Enabled building d8 for Android on Mac.

        Interpret negative hexadecimal literals as NaN.
        (issue 2240)

        Expose counters in javascript when using --track-gc-object-stats.

        Enabled building and testing V8 on Android IA.

        Added --trace-parse flag to parser.

        Performance and stability improvements on all platforms.


2012-07-18: Version 3.12.14

        Deactivated optimization of packed arrays.
        (Chromium issue 137768)

        Fixed broken accessor transition.
        (Chromium issue 137689)

        Performance and stability improvements on all platforms.


2012-07-17: Version 3.12.13

        Fixed missing tagging of stack value in finally block.
        (Chromium issue 137496)

        Added more support for heap analysis.

        Performance and stability improvements on all platforms.


2012-07-16: Version 3.12.12

        Added an option to the tickprocessor to specify the directory for lib
        lookup.

        Fixed ICs for slow objects with native accessor (Chromium issue 137002).

        Fixed transcendental cache on ARM in optimized code (issue 2234).

        New heap inspection tools: counters for object sizes and counts,
        histograms for external fragmentation.

        Incorporated constness into inferred interfaces (in preparation for
        handling imports) (issue 1569).

        Performance and stability improvements on all platforms.


2012-07-12: Version 3.12.11

        Renamed "mips" arch to "mipsel" in the GYP build.

        Fixed computation of call targets on prototypes in Crankshaft.
        (Chromium issue 125148)

        Removed use of __lookupGetter__ when generating stack trace.
        (issue 1591)

        Turned on ES 5.2 globals semantics by default.
        (issue 1991, Chromium issue 80591)

        Synced preparser and parser wrt syntax error in switch..case.
        (issue 2210)

        Fixed reporting of octal literals in strict mode when preparsing.
        (issue 2220)

        Fixed inline constructors for Harmony Proxy prototypes.
        (issue 2225)

        Performance and stability improvements on all platforms.


2012-07-10: Version 3.12.10

        Re-enabled and fixed issue with array bounds check elimination
        (Chromium issue 132114).

        Fixed Debug::Break crash. (Chromium issue 131642)

        Added optimizing compiler support for JavaScript getters.

        Performance and stability improvements on all platforms.


2012-07-06: Version 3.12.9

        Correctly advance the scanner when scanning unicode regexp flag.
        (Chromium issue 136084)

        Fixed unhandlified code calling Harmony Proxy traps.
        (issue 2219)

        Performance and stability improvements on all platforms.


2012-07-05: Version 3.12.8

        Implemented TypedArray.set and ArrayBuffer.slice in d8.

        Performance and stability improvements on all platforms.


2012-07-03: Version 3.12.7

        Fixed lazy compilation for strict eval scopes.
        (Chromium issue 135066)

        Made MACOSX_DEPLOYMENT_TARGET configurable in GYP.
        (issue 2151)

        Report "hidden properties" in heap profiler for properties case.
        (issue 2212)

        Activated optimization of packed arrays by default.

        Performance and stability improvements on all platforms.


2012-06-29: Version 3.12.6

        Cleaned up hardfp ABI detection for ARM (V8 issue 2140).

        Extended TypedArray support in d8.


2012-06-28: Version 3.12.5

        Fixed lazy parsing heuristics to respect outer scope.
        (Chromium issue 135008)

        Allow using test-wrapper-gypbuild.py on Windows when no python
        interpreter is registered.

        Performance and stability improvements on all platforms.


2012-06-27: Version 3.12.4

        Removed -fomit-frame-pointer flag from Release builds to make
        the stack walkable by TCMalloc (Chromium issue 133723).

        Ported r7868 (constant masking) to x64 (issue 1374).

        Expose more detailed memory statistics (issue 2201).

        Fixed Harmony Maps and WeakMaps for undefined values
        (Chromium issue 132744).

        Correctly throw reference error in strict mode with ICs disabled
        (issue 2119).

        Performance and stability improvements on all platforms.


2012-06-25: Version 3.12.3

        Reverted r11835 'Unify promotion and allocation limit computation' due
        to V8 Splay performance regression on Mac.  (Chromium issue 134183)

        Fixed sharing of literal boilerplates for optimized code.  (issue 2193)

        Performance and stability improvements on all platforms.


2012-06-22: Version 3.12.2

        Made near-jump check more strict in LoadNamedFieldPolymorphic on
        ia32/x64. (Chromium issue 134055)

        Fixed lazy sweeping heuristics to prevent old-space expansion.
        (issue 2194)

        Performance and stability improvements on all platforms.


2012-06-21: Version 3.12.1

        Performance and stability improvements on all platforms.


2012-06-20: Version 3.12.0

        Fixed Chromium issues:
        115100, 129628, 131994, 132727, 132741, 132742, 133211

        Fixed V8 issues:
        915, 1914, 2034, 2087, 2094, 2134, 2156, 2166, 2172, 2177, 2179, 2185

        Added --extra-code flag to mksnapshot to load JS code into the VM
        before creating the snapshot.

        Support 'restart call frame' command in the debugger.

        Performance and stability improvements on all platforms.


2012-06-13: Version 3.11.10

        Implemented heap profiler memory usage reporting.

        Preserved error message during finally block in try..finally.
        (Chromium issue 129171)

        Fixed EnsureCanContainElements to properly handle double values.
        (issue 2170)

        Improved heuristics to keep objects in fast mode with inherited
        constructors.

        Performance and stability improvements on all platforms.


2012-06-06: Version 3.11.9

        Implemented ES5-conformant semantics for inherited setters and read-only
        properties. Currently behind --es5_readonly flag, because it breaks
        WebKit bindings.

        Exposed last seen heap object id via v8 public api.

        Performance and stability improvements on all platforms.


2012-05-31: Version 3.11.8

        Avoid overdeep recursion in regexp where a guarded expression with a
        minimum repetition count is inside another quantifier.
        (Chromium issue 129926)

        Fixed missing write barrier in store field stub.
        (issues 2143, 1465, Chromium issue 129355)

        Proxies: Fixed receiver for setters inherited from proxies.
        Proxies: Fixed ToStringArray function so that it does not reject some
        keys.
        (issue 1543)

        Performance and stability improvements on all platforms.


2012-05-29: Version 3.11.7

        Get better function names in stack traces.

        Performance and stability improvements on all platforms.


2012-05-24: Version 3.11.6

        Fixed RegExp.prototype.toString for incompatible receivers
        (issue 1981).

        Performance and stability improvements on all platforms.


2012-05-23: Version 3.11.5

        Performance and stability improvements on all platforms.


2012-05-22: Version 3.11.4

        Some cleanup to common.gypi. This fixes some host/target combinations
        that weren't working in the Make build on Mac.

        Handle EINTR in socket functions and continue incomplete sends.
        (issue 2098)

        Fixed python deprecations.  (issue 1391)

        Made socket send and receive more robust and return 0 on failure.
        (Chromium issue 15719)

        Fixed GCC 4.7 (C++11) compilation.  (issue 2136)

        Set '-m32' option for host and target platforms

        Performance and stability improvements on all platforms.


2012-05-18: Version 3.11.3

        Disable optimization for functions that have scopes that cannot be
        reconstructed from the context chain. (issue 2071)

        Define V8_EXPORT to nothing for clients of v8. (Chromium issue 90078)

        Correctly check for native error objects.  (Chromium issue 2138)

        Performance and stability improvements on all platforms.


2012-05-16: Version 3.11.2

        Revert r11496. (Chromium issue 128146)

        Implement map collection for incremental marking. (issue 1465)

        Add toString method to CallSite (which describes a frame of the
        stack trace).


2012-05-15: Version 3.11.1

        Added a readbuffer function to d8 that reads a file into an ArrayBuffer.

        Fix freebsd build. (V8 issue 2126)

        Performance and stability improvements on all platforms.


2012-05-11: Version 3.11.0

        Fixed compose-discard crasher from r11524 (issue 2123).

        Activated new global semantics by default. Global variables can
        now shadow properties of the global object (ES5.1 erratum).

        Properly set ElementsKind of empty FAST_DOUBLE_ELEMENTS arrays when
        transitioning (Chromium issue 117409).

        Made Error.prototype.name writable again, as required by the spec and
        the web (Chromium issue 69187).

        Implemented map collection with incremental marking (issue 1465).

        Regexp: Fixed overflow in min-match-length calculation
        (Chromium issue 126412).

        MIPS: Fixed illegal instruction use on Loongson in code for
        Math.random() (issue 2115).

        Fixed crash bug in VisitChoice (Chromium issue 126272).

        Fixed unsigned-Smi check in MappedArgumentsLookup
        (Chromium issue 126414).

        Fixed LiveEdit for function with no locals (issue 825).

        Fixed register clobbering in LoadIC for interceptors
        (Chromium issue 125988).

        Implemented clearing of CompareICs (issue 2102).

        Performance and stability improvements on all platforms.


2012-05-03: Version 3.10.8

        Enabled MIPS cross-compilation.

        Ensured reload of elements pointer in StoreFastDoubleElement stub.
        (Chromium issue 125515)

        Fixed corner cases in truncation behavior when storing to
        TypedArrays. (issue 2110)

        Fixed failure to properly recognize and report out-of-memory
        conditions when allocating code space pages. (Chromium issue
        118625)

        Fixed idle notifications to perform a round of incremental GCs
        after context disposal. (issue 2107)

        Fixed preparser for try statement. (issue 2109)

        Performance and stability improvements on all platforms.


2012-04-30: Version 3.10.7

        Performance and stability improvements on all platforms.


2012-04-26: Version 3.10.6

        Fixed some bugs in accessing details of the last regexp match.

        Fixed source property of empty RegExp objects. (issue 1982)

        Enabled inlining some V8 API functions.

        Performance and stability improvements on all platforms.


2012-04-23: Version 3.10.5

        Put new global var semantics behind a flag until WebKit tests are
        cleaned up.

        Enabled stepping into callback passed to builtins.
        (Chromium issue 109564)

        Performance and stability improvements on all platforms.


2012-04-19: Version 3.10.4

        Fixed issues when stressing compaction with WeakMaps.

        Fixed missing GVN flag for new-space promotion. (Chromium issue 123919)

        Simplify invocation sequence at monomorphic function invocation sites.
        (issue 2079)

        Performance and stability improvements on all platforms.


2012-04-17: Version 3.10.3

        Fixed several bugs in heap profiles (including issue 2078).

        Throw syntax errors on illegal escape sequences.

        Implemented rudimentary module linking (behind --harmony flag)

        Implemented ES5 erratum: Global declarations should shadow
        inherited properties.

        Made handling of const more consistent when combined with 'eval'
        and 'with'.

        Fixed V8 on MinGW-x64 (issue 2026).

        Performance and stability improvements on all platforms.


2012-04-13: Version 3.10.2

        Fixed native ARM build (issues 1744, 539)

        Return LOOKUP variable instead of CONTEXT for non-context allocated
        outer scope parameters (Chromium issue 119609).

        Fixed regular and ElementsKind transitions interfering with each other
        (Chromium issue 122271).

        Improved performance of keyed loads/stores which have a HeapNumber
        index (issues 1388, 1295).

        Fixed WeakMap processing for evacuation candidates (issue 2060).

        Bailout on possible direct eval calls (Chromium issue 122681).

        Do not assume that names of function expressions are context-allocated
        (issue 2051).

        Performance and stability improvements on all platforms.


2012-04-10: Version 3.10.1

        Fixed bug with arguments object in inlined functions (issue 2045).

        Fixed performance bug with lazy initialization (Chromium issue
        118686).

        Added suppport for Mac OS X 64bit builds with GYP.
        (Patch contributed by Filipe David Manana )

        Fixed bug with hidden properties (issue 2034).

        Fixed a performance bug when reloading pages (Chromium issue 117767,
        V8 issue 1902).

        Fixed bug when optimizing throw in top-level code (issue 2054).

        Fixed two bugs with array literals (issue 2055, Chromium issue 121407).

        Fixed bug with Math.min/Math.max with NaN inputs (issue 2056).

        Fixed a bug with the new runtime profiler (Chromium issue 121147).

        Fixed compilation of V8 using uClibc.

        Optimized boot-up memory use.

        Optimized regular expressions.


2012-03-30: Version 3.10.0

        Fixed store IC writability check in strict mode
        (Chromium issue 120099).

        Resynchronize timers if the Windows system time was changed.
        (Chromium issue 119815)

        Removed "-mfloat-abi=hard" from host compiler cflags when building for
        hardfp ARM
        (https://code.google.com/p/chrome-os-partner/issues/detail?id=8539)

        Fixed edge case for case independent regexp character classes
        (issue 2032).

        Reset function info counters after context disposal.
        (Chromium issue 117767, V8 issue 1902)

        Fixed missing write barrier in CopyObjectToObjectElements.
        (Chromium issue 119926)

        Fixed missing bounds check in HasElementImpl.
        (Chromium issue 119925)

        Performance and stability improvements on all platforms.


2012-03-23: Version 3.9.24

        Activated count-based profiler for ARM.

        Fixed use of proxies as f.prototype properties. (issue 2021)

        Enabled snapshots on MIPS.

        Performance and stability improvements on all platforms.


2012-03-21: Version 3.9.23

        Use correct arguments adaptation environment when inlining function
        containing arguments. (Issue 2014)

        Performance and stability improvements on all platforms.


2012-03-20: Version 3.9.22

        Enabled count-based profiler by default.

        Implemented a hash based look-up to speed up address checks
        in large object space (issue 853).

        Performance and stability improvements on all platforms.


2012-03-19: Version 3.9.21

        Fixed push-to-trunk script (and re-push).

        Added API call that identifies strings that are guaranteed only to
        contain ASCII characters.


2012-03-19: Version 3.9.20

        Fixed declarations escaping global strict eval. (Issue 1624)

        Fixed wrapping of receiver for non-strict callbacks. (Issue 1973)

        Fixed function declarations overwriting read-only global properties.
        (Chromium issue 115452)

        Fixed --use-strict flag in combination with --harmony[-scoping].

        Debugger: naive implementation of "step into Function.prototype.bind".

        Debugger: added ability to set script source from within OnBeforeCompile

        Added flag to always call DebugBreak on abort.

        Re-enabled constructor inlining and inline === comparison with boolean
        constants. (Issue 2009)

        Don't use an explicit s0 in ClampDoubleToUint8. (Issue 2004)

        Performance and stability improvements on all platforms.


2012-03-14: Version 3.9.19

        Ensure there is a smi check of the receiver for global load and call
        ICs (Chromium issue 117794).

        Performance and stability improvements on all platforms.


2012-03-13: Version 3.9.18

        Ensure consistency of Math.sqrt on Intel platforms.

        Remove static initializers in v8. (issue 1859)

        Add explicit dependency on v8_base in the GYP-based build.

        Performance and stability improvements on all platforms.


2012-03-12: Version 3.9.17

        Fixed VFP detection through compiler defines. (issue 1996)

        Add Code-related fields to postmortem metadata.

        Performance and stability improvements on all platforms.


2012-03-09: Version 3.9.16

        Added basic interface inference for modules (behind the --harmony flag).

        Added Object.is, Number.isFinite, Number.isNaN.

        Updated the Unicode tables to Unicode version 6.1.0.

        Performance and stability improvements on all platforms.


2012-03-06: Version 3.9.15

        Fix the heap profiler crash caused by memory layout changes between
        passes.

        Fix Error.prototype.toString to throw TypeError. (issue 1980)

        Fix double-rounding in strtod for MinGW. (issue 1062)

        Fix corrupted snapshot serializaton on ia32. (Chromium issue v8/1985)

        Performance and stability improvements on all platforms.


2012-03-01: Version 3.9.14

        Performance and stability improvements on all platforms.


2012-02-29: Version 3.9.13

        Added code kind check before preparing for OSR. (issue 1900, 115073)

        Fixed issue 1802: Pass zone explicitly to zone-allocation on x64 and
        ARM.

        Ported string construct stub to x64. (issue 849)

        Performance and stability improvements on all platforms.


2012-02-28: Version 3.9.12

        Fixed the negative lookup stub to handle deleted entries in a
        dictionary. (issue 1964)

        Added a new API where the host can supply a callback function. The
        callback function can resolve the location of a return address on stack
        to the location where a return-address rewriting profiler stashed the
        original return address.

        Fixed Chromium issue http://crbug.com/115646: When compiling for-in
        pass correct context value to the increment instruction.

        Fixed issue 1853: Update breakpoints set with partial file name after
        compile.


2012-02-27: Version 3.9.11

        Made 'module' a context-sensitive keyword (V8 issue 1957).


2012-02-24: Version 3.9.10

        Fixed V8 issues 1322, 1772 and 1969.

        Conformance improvements.

        Performance and stability improvements on all platforms.


2012-02-23: Version 3.9.9

        Supported fast case for-in in Crankshaft.

        Sped up heap snapshot serialization and dominators construction.

        Randomized allocation addresses on windows. (Chromium issue 115151)

        Fixed compilation with MinGW-w64. (issue 1943)

        Fixed incorrect value of assignments to non-extensible properties.

        Fixed a crash bug in generated code on ia32.

        Performance and stability improvements on all platforms.


2012-02-21: Version 3.9.8

        Fixed memory leak and missing #include in StartupDataDecompressor
        (issue 1960).

        Renamed static methods to avoid shadowing virtual methods and fix Clang
        C++11 compile error.

        Fixed sequence of element access in array builtins (issue 1790).

        Performance and stability improvements on all platforms.


2012-02-16: Version 3.9.7

        Fixed V8 issues 1322, 1878, 1942, 1945 and Chromium issue 113924.

        Fixed GCC-4.7 warnings.

        Added Navier-Stokes benchmark.

        Performance and stability improvements on all platforms.


2012-02-14: Version 3.9.6

        Fixed template-related linker error. (issue 1936)

        Allowed inlining of functions containing object literals.  (issue 1322)

        Added --call-graph-size option to tickprocessor.  (issue 1937)

        Heap Snapshot maximum size limit is too low for really big apps. At the
        moment the limit is 256MB.  (Chromium issue 113015)

        Performance and stability improvements on all platforms.


2012-02-09: Version 3.9.5

        Removed unused command line flags.

        Performance and stability improvements on all platforms.


2012-02-08: Version 3.9.4

        Properly initialize element-transitioning array literals on ARM.
        (issue 1930)

        Bug fixes on all platforms.


2012-02-07: Version 3.9.3

        When rethrowing an exception, print the stack trace of its original
        site instead of rethrow site (Chromium issue 60240).

        Increased size of small stacks from 32k to 64k to avoid hitting limits
        in Chromium (Chromium issue 112843).


2012-02-06: Version 3.9.2

        Added timestamp to --trace-gc output. (issue 1932)

        Heap profiler reports implicit references.

        Optionally export metadata with libv8 to enable debuggers to inspect V8
        state.


2012-02-02: Version 3.9.1

        Fixed memory leak in NativeObjectsExplorer::FindOrAddGroupInfo
        (Chromium issue 112315).

        Fixed a crash in dev tools (Chromium issue 107996).

        Added 'dependencies_traverse': 1 to v8 GYP target.

        Performance and stability improvements on all platforms.


2012-02-01: Version 3.9.0

        Reduced memory use immediately after starting V8.

        Stability fixes and performance improvements on all platforms.


2012-01-26: Version 3.8.9

        Flush number string cache on GC (issue 1605).

        Provide access to function inferred name with
	v8::Function::GetInferredName in V8 public API.

        Fix building with Clang (issue 1912).

        Reduce the space used by the stack for the profiling thread.

        Fix misleading documentation of v8::Locker (issue 542).

        Introduce readbinary function in d8 to read binary files.

        Performance and stability improvements on all platforms.


2012-01-23: Version 3.8.8

        Limited number of loop iterations in Heap::ReserveSpace
        (Chromium issue 99027).

        Fixed solaris build (VirtualMemory) (issue 1761).

        Fixed strict vs. non-strict handling of function proxies in
        higher-order array and string methods.

        Enabled asynchronous remote debugging with d8 (issue 1691).

        Stability and performance improvements on all platforms.


2012-01-19: Version 3.8.7

        Ensure that LRandom restores rsi after call to the C function on x64.
        (Chromium issue http://crbug.com/110509)

        Fixing include issues on *bsd when building with scons.
        (issue 1897)

        Provide a switch to specify -fno-strict-aliasing
        (issue 1887)

        Move WIN32 define from standalone.gypi to common.gypi
        (issue 1760)

        Fix corner-case in heap size estimation.
        (issue 1893)

        Fix and enable NEW_NON_STRICT_FAST ArgumentsAccess stub on x64.
        (issue 1903)

        Performance improvements and bug fixes.


2012-01-16: Version 3.8.6

        Add primitive WebGL array support to d8.

        Improve heap size estimation (issue 1893).

        Hash collision DOS workaround extended from string keys
        to numeric keys.

        Provide an API for iterating through all external strings referenced
        from the JS heap.

        Adjust position recorded for call expressions. http://crbug.com/109195

        Fix GC crash related to instanceof. http://crbug.com/109448

        Performance improvements and bug fixes.


2012-01-05: Version 3.8.5

        Fix broken test that assumes that no GC can clear the regexp cache (GC
        can happen at any time due to Crankshaft).

        Fix handling of bogus receivers for Harmony collections. (issue 1884)

        Add netbsd support to gyp build.

        Determine page size at runtime on posix platforms.

        Ensure that store buffer filtering hash sets are cleared after
        StoreBuffer::Filter.

        Randomize the seed used for string hashing.  This helps guard against
        CPU-eating DOS attacks against node.js servers.  Based on code from
        Bert Belder.  This version only solves the issue for those that compile
        V8 themselves or those that do not use snapshots.  A snapshot-based
        precompiled V8 will still have predictable string hash codes.

        Implement callback when script finishes running in V8 API.

        Improve performance of Math.min and Math.max for the case of two
        arguments. (issue 1325)


2012-01-02: Version 3.8.4

        Performance improvements for large Smi-only arrays.

        Fixed InternalArrays construction. (issue 1878)


2011-12-27: Version 3.8.3

        Avoid embedding new space objects into code objects in the lithium gap
        resolver. (chromium:108296)

        Bug fixes and performance optimizations on all platforms.


2011-12-21: Version 3.8.2

        Add max optimization flag to v8 gyp build to ensure V8 is always built 
        fully optimized in Chrome.

        MIPS: Bring MIPS to parity with other platforms.

        Optimizations and stability improvements on all platforms.


2011-12-19: Version 3.8.1

        Fixed GCC 4.7 warnings. Patch from Tobias Burnus.

        Stability improvements on all platforms.


2011-12-13: Version 3.8.0

        Fixed handling of arrays in DefineOwnProperty. (issue 1756)

        Sync parser and preparser on do-while and return statements. 
        (issue 1856)

        Fixed another corner case for DefineOwnProperty on arrays (issue 1756).

        Stability and performance improvements on all platforms.


2011-12-01: Version 3.7.12

        Increase tick interval for the android platform.

        Fix a bug in the register allocator. (chromium:105112)

        Fix handling of recompiling code. (chromium:105375, v8:1782)

        Start incremental marking on idle notification. (v8:1458)

        Build fixes for various platforms.

        Various performance improvements.


2011-11-29: Version 3.7.11

        Fixed bug when generating padding to ensure space for lazy
        deoptimization.
        (issue 1846)

        Further reduced pause times due to GC.

        Stability and performance improvements on all platforms.


2011-11-23: Version 3.7.10

        Set maximum length of FixedArray in terms of elements instead an
        absolute number of bytes.
        (Chromium issue 103103)

        Stability and performance improvements on all platforms.


2011-11-21: Version 3.7.9

        Removed exit-time destructors.

        Stability and performance improvements on all platforms.


2011-11-17: Version 3.7.8

        Removed hidden prototype from builtins, i.e., deleting an overridden
        function on builtins will not make the original function reappear.

        Added NetBSD support for scons build.

        Performance improvements on all platforms.


2011-11-14: Version 3.7.7

        Fix missing fast property accessors in heap snapshots.
        (issue 1818)


2011-11-11: Version 3.7.6

        Fixed filtering of store buffer for large object pages.
        (issue 1817)

        Fixed generated hash function on all platforms.
        (issue 1808)

        Fixed Heap::Shrink to ensure that it does not free pages that are
        still in use.
        (Chromium issue 100414)

        Stability and performance improvements on all platforms.


2011-11-10: Version 3.7.5

        Added initial gyp infrastructure for MIPS.

        Implemented performance improvements to the incremental garbage
        collector.

        Added optimizations and stability improvements on all platforms.


2011-11-07: Version 3.7.4

        Proper "libv8.so.3.7.4" SONAME for Linux shared library (issue 1786).

        Fix Harmony sets and maps to allow null and undefined as keys
        (still hidden behind --harmony flag) (issue 1622).

        Implement VirtualMemory on FreeBSD to fix build (issue 1807).

        Enable VFP instructions for Android.

        Fix error handling in Date.prototype.toISOString (issue 1792).

        Bug fixes and performance improvements for all platforms.

        Not officially supported but noteworthy: Crankshaft for MIPS :-)


2011-10-28: Version 3.7.3

        Slight deoptimization as a workaround for issue with jslint: Issue
        1789.


2011-10-27: Version 3.7.2

        Fix bug in deoptimization.  Known issue with jslint: Issue 1789.


2011-10-26: Version 3.7.1

        Achieved 33% speedup in debug-mode tests.

        Removed special casing of calls to RegExp test and exec methods with no
        argument.  Now matches new JSC behaviour.  crbug.com/75740.

        Return the empty string on cyclic references in toString (ES5
        conformance).

        Fixed bug triggered by JSBeautifier.  crbug.com/100409.

        Made Math.random state per-context instead of per-process (issue 864).

        Fixed stack traces to skip native functions.

        Make snapshots (new contexts) smaller and faster.

        Fixed handling of Function.apply for non-array arguments.

        Fixed evaluation order in defineProperties to match FireFox.

        Fixed handling of non-object receivers for array builtins,
        crbug.com/100702.

        Multiple fixes to improve compliance with test262.

        Fixed compatibility with older Android releases.

        Fixed compilation with gcc-4.5.3.

        Improved performance of WriteUtf8, issue 1665.

        Made native syntax an early error in the preparser.

        Fixed issues 793 and 893 relating to Function.prototype.bind.

        Improved let, const, Set and Map support and other Harmony features
        (behind the --harmony flag).

        Changed evaluation order for > and <= to match ES5 instead of ES3.

        Bug fixes and performance improvements on all platforms.


2011-10-13: Version 3.7.0

        Fixed array handling for Object.defineOwnProperty (ES5 conformance).

        Fixed issue 1757 (string slices of external strings).

        Fixed issue 1759 (ARM).

        Added flag --noclever-optimizations to disable some things that
        caused trouble in the past.

        Added flag --stress-compaction for testing.

        Added flag --harmony to activate all experimental Harmony features.


2011-10-10: Version 3.6.6

        Added a GC pause visualization tool.

        Added presubmit=no and werror=no flags to Makefile.

        ES5/Test262 conformance improvements.

        Fixed compilation issues with GCC 4.5.x (issue 1743).

        Bug fixes and performance improvements on all platforms.


2011-10-05: Version 3.6.5

        New incremental garbage collector.

        Removed the hard heap size limit (soft heap size limit is still
        700/1400Mbytes by default).

        Implemented ES5 generic Array.prototype.toString (Issue 1361).

        V8 now allows surrogate pair codes in decodeURIComponent (Issue 1415).

        Fixed x64 RegExp start-of-string bug (Issues 1746, 1748).

        Fixed propertyIsEnumerable for numeric properties (Issue 1692).

        Fixed the MinGW and Windows 2000 builds.

        Fixed "Prototype chain is not searched if named property handler does
        not set a property" (Issue 1636).

        Made the RegExp.prototype object be a RegExp object (Issue 1217).

        Disallowed future reserved words as labels in strict mode.

        Fixed string split to correctly coerce the separator to a string
        (Issue 1711).

        API: Added an optional source length field to the Extension
        constructor.

        API: Added Debug::DisableAgent to match existing Debug::EnableAgent
        (Issue 1573).

        Added "native" target to Makefile for the benefit of Linux distros.

        Fixed: debugger stops stepping outside evaluate (Issue 1639).

        More work on ES-Harmony proxies.  Still hidden behind a flag.

        Bug fixes and performance improvements on all platforms.


2011-09-15: Version 3.6.4

        Fixed d8's broken readline history.

        Removed the need for code delete events in CPU profiler (Issue 1466).

        Fixed debugger stepping next with trycatch recursion (Issue 1639).

        Fixing parallel execution in d8 (with -p) and some memory leaks.

        Support for precise stepping in functions compiled before debugging was
        started (step 1).


2011-09-13: Version 3.6.3

        Implemented better support of typed arrays in the d8 shell.

        Bug fixes and performance improvements on all platforms.


2011-09-08: Version 3.6.2

        Added "dependencies" target to top-level Makefile.

        Added ability to turn profiler on/off in d8.

        Added "soname_version" parameter to common.gypi, v8.gyp, and Makefile.

        Fixed several crash bugs.


2011-09-07: Version 3.6.1

        Fixed a bug in abrupt exit from with or catch inside finally.

        Fixed possible crash in FixedDoubleArray::Initialize() (Chromium
        issue 95113).

        Fixed a bug in Page::GetRegionMaskForSpan (Chromium issue 94425).

        Fixed a few clang warnings (which -Werror treated as errors).

        Performance improvements on all platforms.


2011-09-05: Version 3.6.0

        Fixed a bug when optimizing named function expression (issue 1647).

        Fixed a bug when optimizing f.call.apply (issue 1650).

        Made arguments and caller always be null on native functions
        (issues 1548 and 1643).

        Fixed issue 1648 (cross-compiling x64 targeting ia32).

        Fixed issue 371 (d8 printing of strings containing \0).

        Fixed order of evaluation in arguments to parseInt (issue 1649).

        Fixed a problem with large heap snapshots in Chrome DevTools
        (issue 1658, chromium issue 89268).

        Upped default maximum heap size from 512M to 700M.


2011-08-31: Version 3.5.10

        Added dependency of v8_base on WinSocket2 Windows library in
        the GYP-build.

        Various bugfixes.


2011-08-29: Version 3.5.9

        Made FromPropertyDescriptor not trigger inherited setters.

        Fixed .gyp files to work on the ARM simulator.

        Fixed shared library build warnings for MSVS.


2011-08-24: Version 3.5.8

        Added V8EXPORT attributes for v8::Array::CheckCast and
        v8::Number::CheckCast.

        Made a slight API change enabling opting out from null termination
        in String::Write*().

        Fixed arm build for gcc-4.6.


2011-08-22: Version 3.5.7

        Make scanner handle invalid unicode escapes in identifiers correctly.

        Make regexp flag parsing stricter.

        Fix several memory leaks.


2011-08-17: Version 3.5.6

        Fixed issue that could cause crashes when running with --heap-stats.

        Fixed compilation on Linux 2.6.9 and older.

        Fixed live-object-list to work with isolates.

        Fixed memory leaks in zones and isolates.

        Fixed a performance regression for TypedArrays on x64.

        Stability improvements on all platforms.


2011-08-15: Version 3.5.5

        Fixed bugs involving negative zero and the optimizing compiler.

        Fixed optimized version of Function.apply(x, arguments). (issue 1592)

        Eliminated uses of deprecated ARM instructions.

        Sped up Math.floor by using SSE 4.1 roundsd instruction on ia32.

        Removed restriction on the size of disassembled code that is printed.


2011-08-10: Version 3.5.4

        Added a preliminary implementation of ES Harmony weak maps.  Weak
        maps can be enabled by the flag --harmony-weakmaps.

        Introduced a toplevel Makefile to support GYP-based building.  GYP
        can be obtained from http://gyp.googlecode.com.

        Fixed a bug in the length property of functions created by
        Function.prototype.bind.

        Reduced malloc heap allocation on process startup.

        Several important code generation bug fixes.

        Performance improvements on all platforms.


2011-08-03: Version 3.5.3

        MIPS: Port of fix to ClassOf check from ARM.
        Patch from Paul Lind .

        Stopped using mprotect on Cygwin.
        Avoided uninitialized member warning on gcc 4.3.4
        Both patches by Bert Belder.

        Bug fixes and performance improvements on all platforms.


2011-08-01: Version 3.5.2

        Performance improvements on all platforms.


2011-07-28: Version 3.5.1

        Fixed setting the readonly flag on the prototype property using the
        API call FunctionTemplate::SetPrototypeAttributes (issue 1539).

        Changed the tools/test.py script to use d8 instead of shell for
        testing.

        Fixed crash in ToBooleanStub when GC happens during invocation.

        Enabled automatic unboxing of double arrays.

        Performance improvements on all platforms.


2011-07-25: Version 3.5.0

        Implemented Object.prototype.{hasOwnProperty, propertyIsEnumerable} for
        proxies.

        Removed logging to memory support.

        Bugfixes and performance work.


2011-07-20: Version 3.4.14

        Fix the debugger for strict-mode functions. (Chromium issue 89236)

        Add GetPropertyAttribute method for Object in the API. (Patch by
        Peter Varga)

        Fix -Wunused-but-set-variable for gcc-4.6 on x64. (Issue 1291)


2011-07-18: Version 3.4.13

        Improved debugger support to allow inspection of optimized frames (issue
        1140).

        Fixed a bug in prototype transitions cache clearing introduced by r8165.

        Fixed shortcutting bug in HInferRepresentation. Patch by Andy Wingo.

        Fixed a memory leak in sample/shell.cc (dispose semaphores).

        Simplified HClampToUint8. Patch by Andy Wingo.

        Exposed APIs for detecting boxed primitives, native errors. Patch by
        Luke Zarko.

        Added map check for COW elements to crankshaft array handling code
        (issue 1560).

        Sample shell and (a light version of) D8 links against a shared library
        now.

        Fixed bug in array filter and reduce functions (issue 1559).

        Avoid TLS load in AstNode constructor.

        Introduced a random entropy source which can optionally be provided at
        initialization. (Chromium issue 89462).


2011-07-13: Version 3.4.12

        Added --prof profiling option to d8 shell.

        Fixed a bug where reading a directory in d8 shell hangs (issue 1533).

        Fixed a potential assertion failure in const declarations.

        Fixed an assertion failure in descriptor arrays (issue 1526).

        Enabled fast thread-local storage by default on supported platforms.

        Improved reporting of source position for global variable loads
        (issue 1527).


2011-07-11: Version 3.4.11

        Fixed MinGW32 build.

        Fixed a GC bug with RegExp code flushing.

        Implemented Object.defineProperty for proxies.

        Fixed a bug in for/in iteration of arguments objects (issue 1531).

        Added debugger support for inspecting optimized frames (issue 1140).

        Allowed JSObject::PreventExtensions to work for arguments objects.

        Bugfixes and performance work.


2011-07-06: Version 3.4.10

        Fixed debugger not breaking on certain "if" statements (issue 1523).

        Fixed assertion failure in runtime profiler when running on IA32
        without snapshot (issue 1522).

        Fixed ABI for API calls on IA32 (for clang compatibility).

        Introduced code flushing of RegExp code to free memory used by
        RegExps sooner.

        Fixed linux-tick-processor built wrong version of v8 (issue 1532).

        Fixed assertion failure in v8::TryCache::StackTrace (issue 1529).

        Performance improvements on all platforms.


2011-07-04: Version 3.4.9

        Added support for debugger inspection of locals in optimized frames
        (issue 1140).

        Fixed SConstruct to pass correct defines to samples/preparser when
        building with library=shared.

        Made date parser handle ES5 Date Time Strings correctly (issue 1498).

        Fixed a bug in Object.defineProperty on the arguments object.

        Performance improvements on all platforms.


2011-06-29: Version 3.4.8

        Ensure 16-byte stack alignment on Solaris (issue 1505).

        Fix "illegal access" when calling parseInt with a radix
        that is not a smi. (issue 1246).


2011-06-27: Version 3.4.7

        Fixed 64-bit build on FreeBSD.

        Added API to set the property attributes for the prototype
        property on functions created from FunctionTemplates.

        Bugfixes and performance work.


2011-06-22: Version 3.4.6

        Lowered limit on code space for systems with low memory supply.

        Allowed compiling v8_shell with the 'host' toolset (issue 82437).

        Extended setBreakpoint API to accept partial script name (issue 1418).

        Made multi-line comments not count when deciding whether the '-->'
        comment starter is first on a line. This matches Safari.

        Made handling of non-array recievers in Array length setter correct
        (issue 1491).

        Added ability to heap profiler to iterate over snapshot's node
        (issue 1481).


2011-06-20: Version 3.4.5

        Fixed issues 794, 1097, 1215(partial), 1417, 1435, 1472, 1473,
        1476, and 1477.

        Improved code generation for !0 and !1.

        Reduced memory usage for regular expressions with nested qualifiers.
        (issue 1472)

        Fixed V8 to count line terminators in multi-line comments.
        (Chromium issue 86431)

        Fixed disassembler=on option for release-mode builds. (issue 1473)

        Performance improvements on all platforms.


2011-06-15: Version 3.4.4

        Added snapshot compression support and --stress-opt flag to d8.

        Improved performance of try/catch.

        Several GYP-related changes: Added support for building Xcode project
        files. Make the ARM simulator build with GYP again. Generate Makefiles
        for all architectures on Linux.

        Fixed Array.prototype.{reduce,reduceRight} to pass undefined as the
        receiver for strict mode callbacks. (issue 1436)

        Fixed a bug where an array load was incorrectly hoisted by GVN.

        Handle 'undefined' correctly when === has been specialized for doubles.
        (issue 1434)

        Corrected the limit of local variables in an optimized function from 64
        to 63.

        Correctly set ReadOnly flag on indexed properties when using the API Set
        method. (issue 1470)

        Give the correct error message when Object.isExtensible is called on a
        non-object. (issue 1452)

        Added GetOwnPropertyNames method for Object in the API. Patch by Peter
        Varga.

        Do not redefine properties unneccesarily in seal and freeze. (issue
        1447)

        IsExecutionTerminating has an Isolate parameter now.

        Distinguish keyed loads with a symbol key from fast elements loads,
        avoiding some useless deoptimizations. (issue 1471)


2011-06-08: Version 3.4.3

        Clear the global thread table when an isolate is disposed
        (issue 1433).

        Converted time zone name to UTF8 on Windows (issue 1290).

        Limited the number of arguments in a function call to 32766
        (issue 1413).

        Compress sources of JS libraries in addition to the snapshot.

        Fixed a bug in Lithium environment iteration.

        Performance improvements on all platforms.


2011-06-06: Version 3.4.2

        More work on ES-Harmony proxies.  Still hidden behind a flag.

        Fixed some crash bugs and improved performance.

        Fixed building with gdb debugging support.

        Do not install SIGPROF handler until it is needed.

        Added DateTimeFormat to i18n API.

        Fixed compilation on OpenBSD.

        Take the ulimit into account when sizing the heap.  OpenBSD users
        may still have to increase the default ulimit to run heavy pages in
        the browser.


2011-06-01: Version 3.4.1

        Fixed JSON stringify issue with arrays.

        Changed calls to JS builtins to be passed undefined when called with
        implicit receiver.

        Implemented the set trap for Harmony proxies. Proxies still need to
        be enabled with the --harmony-proxies flag.


2011-05-30: Version 3.4.0

        Changed calls to undefined property setters to not throw (issue 1355).

        Made RegExp objects not callable.

        Fixed issues on special case large JSON strings in new json parser
        (issues http://crbug.com/83877 and http://crbug.com/84186).

        Performance improvements on all platforms.


2011-05-25: Version 3.3.10

        Fixed calls of strict mode function with an implicit receiver.

        Fixed fast handling of arrays to properly deal with changes to the
        Object prototype (issue 1403).

        Changed strict mode poison pill to be the same type error function
        (issue 1387).

        Fixed a debug crash in arguments object handling (issue 1227).

        Fixed a bug in deoptimization on x64 (issue 1404).

        Performance improvements and bug fixes on all platforms.


2011-05-23: Version 3.3.9

        Added DateTimeFormat class to experimental i18n API.

        Extended preparser to give early errors for some strict mode
        restrictions.

        Removed legacy execScript function from V8.

        Extended isolate API with the ability to add embedder-specific
        data to an isolate.

        Added basic support for polymorphic loads from JS and external
        arrays.

        Fixed bug in handling of switch statements in the optimizing
        compiler.


2011-05-18: Version 3.3.8

        Added MarkIndependent to the persistent handle API.  Independent
        handles are independent of all other persistent handles and can be
        garbage collected more frequently.

        Implemented the get trap for Harmony proxies.  Proxies are enabled
        with the --harmony-proxies flag.

        Performance improvements and bug fixes on all platforms.


2011-05-16: Version 3.3.7

        Updated MIPS infrastructure files.

        Performance improvements and bug fixes on all platforms.


2011-05-11: Version 3.3.6

        Updated MIPS infrastructure files.

        Added method IsCallable for Object to the API.
        Patch by Peter Varga.


2011-05-09: Version 3.3.5

        Fixed build on FreeBSD. Patch by Akinori MUSHA.

        Added check that receiver is JSObject on API calls.

        Implemented CallAsConstructor method for Object in the API (Issue 1348).
        Patch by Peter Varga.

        Added CallAsFunction method to the Object class in the API (Issue 1336).
        Patch by Peter Varga.

        Added per-isolate locking and unlocking.

        Fixed bug in x64 >>> operator (Issue 1359).


2011-05-04: Version 3.3.4

        Implemented API to disallow code generation from strings for a context
        (issue 1258).

        Fixed bug with whitespaces in parseInt (issue 955).

        Fixed bug with == comparison of Date objects (issue 1356).

        Added GYP variables for ARM code generation:
        v8_can_use_vfp_instructions, v8_can_use_unaligned_accesses
        and v8_use_arm_eabi_hardfloat.


2011-05-02: Version 3.3.3

        Added support for generating Visual Studio solution and project files
        using GYP.

        Implemented support for ARM EABI calling convention variation where
        floating-point arguments are passed in registers (hardfloat).

        Added Object::HasOwnProperty() to the API.

        Added support for compressing startup data to reduce binary size. This
        includes build time support and an API for the embedder to decompress
        the startup data before initializing V8.

        Reduced the profiling hooks overhead from >400% to 25% when using
        ll_prof.

        Performance improvements and bug fixes on all platforms.


2011-04-27: Version 3.3.2

        Fixed crash bug on ARM with no VFP3 hardware.

        Fixed compilation of V8 without debugger support.

        Improved performance on JSLint.

        Added support Float64 WebGL arrays.

        Fixed crash bug in regexp replace.


2011-04-20: Version 3.3.1

        Reduced V8 binary size by removing virtual functions from hydrogen.

        Fixed crash bug on x64.

        Performance improvements on ARM and IA32.


2011-04-18: Version 3.3.0

        Fixed bug in floating point rounding in Crankshaft on ARM
        (issue 958)

        Fixed a number of issues with running without VFPv3 support on ARM
        (issue 1315)

        Introduced v8Locale.Collator, a partial implementation of Collator
        per last ECMAScript meeting + mailing list.

        Minor performance improvements and bug fixes.


2011-04-13: Version 3.2.10

        Fixed bug in external float arrays on ARM (issue 1323).

        Minor performance improvements and bug fixes.


2011-04-11: Version 3.2.9

        Removed support for ABI prior to EABI on ARM.

        Fixed multiple crash bugs.

        Added GCMole to the repository, a simple static analysis tool that
        searches for GC-unsafe evaluation order dependent callsites.

        Made preparser API be exported in shared libraries.

        Fixed multiple issues in EcmaScript 5 strict mode implementation.

        Fixed mutable __proto__ property if object is not extensible
        (Issue 1309).

        Fixed auto suspension of the sampler thread.


2011-04-06: Version 3.2.8

        Exposed WebGL typed array constructors in the shell sample.

        Performance improvements on all platforms.


2011-04-04: Version 3.2.7

        Disabled the original 'classic' V8 code generator.  Crankshaft is
        now the default on all platforms.

        Changed the heap profiler to use more descriptive names.

        Performance and stability improvements to isolates on all platforms.


2011-03-30: Version 3.2.6

        Fixed xcode build warning in shell.cc (out of order initialization).

        Fixed null-pointer dereference in the compiler when running without
        SSE3 support (Chromium issue 77654).

        Fixed x64 compilation error due to some dead code. (Issue 1286)

        Introduced scons target to build the preparser stand-alone example.

        Made FreeBSD build and pass all tests.


2011-03-28: Version 3.2.5

        Fixed build with Irregexp interpreter (issue 1266).

        Added Crankshaft support for external arrays.

        Fixed two potential crash bugs.


2011-03-23: Version 3.2.4

        Added isolates which allows several V8 instances in the same process.
        This is controlled through the new Isolate class in the API.

        Implemented more of EcmaScript 5 strict mode.

        Reduced the time it takes to make detailed heap snapshot.

        Added a number of commands to the ARM simulator and enhanced the ARM
        disassembler.


2011-03-17: Version 3.2.3

        Fixed a number of crash bugs.

        Fixed Array::New(length) to return an array with a length (issue 1256).

        Fixed FreeBSD build.

        Changed __defineGetter__ to not throw (matching the behavior of Safari).

        Implemented more of EcmaScript 5 strict mode.

        Improved Crankshaft performance on all platforms.


2011-03-14: Version 3.2.2

        Fixed a number of crash and correctness bugs.

        Improved Crankshaft performance on all platforms.

        Fixed Crankshaft on Solaris/Illumos.


2011-03-10: Version 3.2.1

        Fixed a number of crash bugs.

        Improved Crankshaft for x64 and ARM.

        Implemented more of EcmaScript 5 strict mode.


2011-03-07: Version 3.2.0

        Fixed a number of crash bugs.

        Turned on Crankshaft by default on x64 and ARM.

        Improved Crankshaft for x64 and ARM.

        Implemented more of EcmaScript 5 strict mode.


2011-03-02: Version 3.1.8

        Fixed a number of crash bugs.

        Improved Crankshaft for x64 and ARM.

        Implemented more of EcmaScript 5 strict mode.

        Fixed issue with unaligned reads and writes on ARM.

        Improved heap profiler support.


2011-02-28: Version 3.1.7

        Fixed a number of crash bugs.

        Improved Crankshaft for x64 and ARM.

        Fixed implementation of indexOf/lastIndexOf for sparse
        arrays (http://crbug.com/73940).

        Fixed bug in map space compaction (http://crbug.com/59688).

        Added support for direct getter accessors calls on ARM.


2011-02-24: Version 3.1.6

        Fixed a number of crash bugs.

        Added support for Cygwin (issue 64).

        Improved Crankshaft for x64 and ARM.

        Added Crankshaft support for stores to pixel arrays.

        Fixed issue in CPU profiler with Crankshaft.


2011-02-16: Version 3.1.5

        Change RegExp parsing to disallow /(*)/.

        Added GDB JIT support for ARM.

        Fixed several crash bugs.

        Performance improvements on the IA32 platform.


2011-02-14: Version 3.1.4

        Fixed incorrect compare of prototypes of the global object (issue
        1082).

        Fixed a bug in optimizing calls to global functions (issue 1106).

        Made optimized Function.prototype.apply safe for non-JSObject first
        arguments (issue 1128).

        Fixed an error related to element accessors on Object.prototype and
        parser errors (issue 1130).

        Fixed a bug in sorting an array with large array indices (issue 1131).

        Properly treat exceptions thrown while compiling (issue 1132).

        Fixed bug in register requirements for function.apply (issue 1133).

        Fixed a representation change bug in the Hydrogen graph construction
        (issue 1134).

        Fixed the semantics of delete on parameters (issue 1136).

        Fixed a optimizer bug related to moving instructions with side effects
        (issue 1138).

        Added support for the global object in Object.keys (issue 1150).

        Fixed incorrect value for Math.LOG10E
        (issue http://code.google.com/p/chromium/issues/detail?id=72555)

        Performance improvements on the IA32 platform.

        Implement assignment to undefined reference in ES5 Strict Mode.


2011-02-09: Version 3.1.3

        Fixed a bug triggered by functions with huge numbers of declared
        arguments.

        Fixed zap value aliasing a real object - debug mode only (issue 866).

        Fixed issue where Array.prototype.__proto__ had been set to null
        (issue 1121).

        Fixed stability bugs in Crankshaft for x86.


2011-02-07: Version 3.1.2

        Added better security checks when accessing properties via
        Object.getOwnPropertyDescriptor.

        Fixed bug in Object.defineProperty and related access bugs (issues
        992, 1083 and 1092).

        Added LICENSE.v8, LICENSE.strongtalk and LICENSE.valgrind to ease
        copyright notice generation for embedders.


2011-02-02: Version 3.1.1

        Perform security checks before fetching the value in
        Object.getOwnPropertyDescriptor.

        Fixed a bug in Array.prototype.splice triggered by passing no
        arguments.

        Fixed bugs in -0 in arithmetic and in Math.pow.

        Fixed bugs in the register allocator and in switching from optimized
        to unoptimized code.


2011-01-31: Version 3.1.0

        Performance improvements on all platforms.


2011-01-28: Version 3.0.12

        Added support for strict mode parameter and object property
        validation.

        Fixed a couple of crash bugs.


2011-01-25: Version 3.0.11

        Fixed a bug in deletion of lookup slots that could cause global
        variables to be accidentally deleted (http://crbug.com/70066).

        Added support for strict mode octal literal verification.

        Fixed a couple of crash bugs (issues 1070 and 1071).


2011-01-24: Version 3.0.10

        Fixed External::Wrap for 64-bit addresses (issue 1037).

        Fixed incorrect .arguments variable proxy handling in the full
        code generator (issue 1060).

        Introduced partial strict mode support.

        Changed formatting of recursive error messages to match Firefox and
        Safari (issue http://crbug.com/70334).

        Fixed incorrect rounding for float-to-integer conversions for external
        array types, which implement the Typed Array spec
        (issue http://crbug.com/50972).

        Performance improvements on the IA32 platform.


2011-01-19: Version 3.0.9

        Added basic GDB JIT Interface integration.

        Make invalid break/continue statements a syntax error instead of a
        runtime error.


2011-01-17: Version 3.0.8

        Exposed heap size limit to the heap statistics gathered by
        the GetHeapStatistics API.

        Wrapped external pointers more carefully (issue 1037).

        Hardened the implementation of error objects to avoid setters
        intercepting the properties set then throwing an error.

        Avoided trashing the FPSCR when calculating Math.floor on ARM.

        Performance improvements on the IA32 platform.


2011-01-10: Version 3.0.7

        Stopped calling inherited setters when creating object literals
        (issue 1015).

        Changed interpretation of malformed \c? escapes in RegExp to match
        JSC.

        Enhanced the command-line debugger interface and fixed some minor
        bugs in the debugger.

        Performance improvements on the IA32 platform.


2011-01-05: Version 3.0.6

        Allowed getters and setters on JSArray elements (issue 900).

        Stopped JSON objects from hitting inherited setters (part of
        issue 1015).

        Allowed numbers and strings as names of getters/setters in object
        initializer (issue 820).

        Added use_system_v8 option to gyp (off by default), to make it easier
        for Linux distributions to ship with system-provided V8 library.

        Exported external array data accessors (issue 1016).

        Added labelled thread names to help with debugging (on Linux).


2011-01-03: Version 3.0.5

        Fixed a couple of cast errors for gcc-3.4.3.

        Performance improvements in GC and IA32 code generator.


2010-12-21: Version 3.0.4

        Added Date::ResetCache() to the API so that the cached values in the
        Date object can be reset to allow live DST / timezone changes.

        Extended existing support for printing (while debugging) the contents
        of objects.  Added support for printing objects from release builds.

        Fixed V8 issues 989, 1006, and 1007.


2010-12-17: Version 3.0.3

        Reapplied all changes for version 3.0.1.

        Improved debugger protocol for remote debugging.

        Added experimental support for using gyp to generate build files
        for V8.

        Fixed implementation of String::Write in the API (issue 975).


2010-12-15: Version 3.0.2

        Revert version 3.0.1 and patch 3.0.1.1.


2010-12-13: Version 3.0.1

        Added support for an experimental internationalization API as an
        extension.  This extension is disabled by default but can be enabled
        when building V8.  The ECMAScript internationalization strawman is
        at http://wiki.ecmascript.org/doku.php?id=strawman:i18n_api.

        Made RegExp character class parsing stricter.  This mirrors a change
        to RegExp parsing in WebKit.

        Fixed a bug in Object.defineProperty when used to change attributes
        of an existing property.  It incorrectly set the property value to
        undefined (issue 965).

        Fixed several different compilation failures on various platforms
        caused by the 3.0.0 release.

        Optimized Math.pow so it can work on unboxed doubles.

        Sped up quoting of JSON strings by removing one traversal of the
        string.


2010-12-07: Version 3.0.0

        Improved performance by (partially) addressing issue 957 on
        IA-32. Still needs more work for the other architectures.


2010-11-29: Version 2.5.9

        Fixed crashes during GC caused by partially initialize heap
        objects.

        Fixed bug in process sample that caused memory leaks.

        Improved performance on ARM by implementing missing stubs and
        inlining.

        Improved heap profiler support.

        Added separate seeding on Windows of the random number generator
        used internally by the compiler (issue 936).

        Exposed API for getting the name of the function used to construct
        an object.

        Fixed date parser to handle one and two digit millisecond
        values (issue 944).

        Fixed number parsing to disallow space between sign and
        digits (issue 946).


2010-11-23: Version 2.5.8

        Removed dependency on Gay's dtoa.

        Improved heap profiler precision and speed.

        Reduced overhead of callback invocations on ARM.


2010-11-18: Version 2.5.7

        Fixed obscure evaluation order bug (issue 931).

        Split the random number state between JavaScript and the private API.

        Fixed performance bug causing GCs when generating stack traces on
        code from very large scripts.

        Fixed bug in parser that allowed (foo):42 as a labelled statement
        (issue 918).

        Provide more accurate results about used heap size via
        GetHeapStatistics.

        Allow build-time customization of the max semispace size.

        Made String.prototype.split honor limit when separator is empty
        (issue 929).

        Added missing failure check after expecting an identifier in
        preparser (Chromium issue 62639).


2010-11-10: Version 2.5.6

        Added support for VFP rounding modes to the ARM simulator.

        Fixed multiplication overflow bug (issue 927).

        Added a limit for the amount of executable memory (issue 925).


2010-11-08: Version 2.5.5

        Added more aggressive GC of external objects in near out-of-memory
        situations.

        Fixed a bug that gave the incorrect result for String.split called
        on the empty string (issue 924).


2010-11-03: Version 2.5.4

        Improved V8 VFPv3 runtime detection to address issue 914.


2010-11-01: Version 2.5.3

        Fixed a bug that prevents constants from overwriting function values
        in object literals (issue 907).

        Fixed a bug with reporting of impossible nested calls of DOM functions
        (issue http://crbug.com/60753).


2010-10-27: Version 2.5.2

        Improved sampler resolution on Linux.

        Allowed forcing the use of a simulator from the build script
        independently of the host architecture.

        Fixed FreeBSD port (issue 912).

        Made windows-tick-processor respect D8_PATH.

        Implemented --noinline-new flag fully on IA32, X64 and ARM platforms.


2010-10-20: Version 2.5.1

        Fixed bug causing spurious out of memory exceptions
        (issue http://crbug.com/54580).

        Fixed compilation error on Solaris platform (issue 901).

        Fixed error in strtod (string to floating point number conversion)
        due to glibc's use of 80-bit floats in the FPU on 32-bit linux.

        Adjusted randomized allocations of executable memory to have 64k
        granularity (issue http://crbug.com/56036).

        Supported profiling using kernel perf_events on linux.  Added ll_prof
        script to tools and --ll-prof flag to V8.


2010-10-18: Version 2.5.0

        Fixed bug in cache handling of lastIndex on global regexps
        (issue http://crbug.com/58740).

        Added USE_SIMULATOR macro that explicitly indicates that we wish to use
        the simulator as the execution engine (by Mark Lam 
        from Hewlett-Packard Development Company, LP).

        Fixed compilation error on ARM with gcc 4.4 (issue 894).


2010-10-13: Version 2.4.9

        Fixed a bug in the handling of conditional expressions in test
        contexts in compiler for top-level code.

        Added "//@ sourceURL" information to the StackTrace API.

        Exposed RegExp construction through the API.


2010-10-04: Version 2.4.8

        Fixed a bug in ResumeProfilerEx causing it to not always write out the
        whole snapshot (issue 868).

        Performance improvements on all platforms.


2010-09-30: Version 2.4.7

        Changed the command-line flag --max-new-space-size to be in kB and the
        flag --max-old-space-size to be in MB (previously they were in bytes).

        Added Debug::CancelDebugBreak to the debugger API.

        Fixed a bug in getters for negative numeric property names
        (https://bugs.webkit.org/show_bug.cgi?id=46689).

        Performance improvements on all platforms.


2010-09-27: Version 2.4.6

        Fixed assertion failure related to copy-on-write arrays (issue 876).

        Fixed build failure of 64-bit V8 on Windows.

        Fixed a bug in RegExp (issue http://crbug.com/52801).

        Improved the profiler's coverage to cover more functions (issue 858).

        Fixed error in shift operators on 64-bit V8
        (issue http://crbug.com/54521).


2010-09-22: Version 2.4.5

        Changed the RegExp benchmark to exercise the regexp engine on different
        inputs by scrambling the input strings.

        Fixed a bug in keyed loads on strings.

        Fixed a bug with loading global function prototypes.

        Fixed a bug with profiling RegExp calls (issue http://crbug.com/55999).

        Performance improvements on all platforms.


2010-09-15: Version 2.4.4

        Fixed bug with hangs on very large sparse arrays.

        Now tries harder to free up memory when running out of space.

        Added heap snapshots to JSON format to API.

        Recalibrated benchmarks.


2010-09-13: Version 2.4.3

        Made Date.parse properly handle TZ offsets (issue 857).

        Performance improvements on all platforms.


2010-09-08: Version 2.4.2

        Fixed GC crash bug.

        Fixed stack corruption bug.

        Fixed compilation for newer C++ compilers that found Operand(0)
        ambiguous.


2010-09-06: Version 2.4.1

        Added the ability for an embedding application to receive a callback
        when V8 allocates (V8::AddMemoryAllocationCallback) or deallocates
        (V8::RemoveMemoryAllocationCallback) from the OS.

        Fixed several JSON bugs (including issue 855).

        Fixed memory overrun crash bug triggered during V8's tick-based
        profiling.

        Performance improvements on all platforms.


2010-09-01: Version 2.4.0

        Fixed bug in Object.freeze and Object.seal when Array.prototype or
        Object.prototype are changed (issue 842).

        Updated Array.splice to follow Safari and Firefox when called
        with zero arguments.

        Fixed a missing live register when breaking at keyed loads on ARM.

        Performance improvements on all platforms.


2010-08-25: Version 2.3.11

        Fixed bug in RegExp related to copy-on-write arrays.

        Refactored tools/test.py script, including the introduction of
        VARIANT_FLAGS that allows specification of sets of flags with which
        all tests should be run.

        Fixed a bug in the handling of debug breaks in CallIC.

        Performance improvements on all platforms.


2010-08-23: Version 2.3.10

        Fixed bug in bitops on ARM.

        Build fixes for unusual compilers.

        Track high water mark for RWX memory.

        Performance improvements on all platforms.


2010-08-18: Version 2.3.9

        Fixed compilation for ARMv4 on OpenBSD/FreeBSD.

        Removed specialized handling of GCC 4.4 (issue 830).

        Fixed DST cache to take into account the suspension of DST in
        Egypt during the 2010 Ramadan (issue http://crbug.com/51855).

        Performance improvements on all platforms.


2010-08-16: Version 2.3.8

        Fixed build with strict aliasing on GCC 4.4 (issue 463).

        Fixed issue with incorrect handling of custom valueOf methods on
        string wrappers (issue 760).

        Fixed compilation for ARMv4 (issue 590).

        Improved performance.


2010-08-11: Version 2.3.7

        Reduced size of heap snapshots produced by heap profiler (issue 783).

        Introduced v8::Value::IsRegExp method.

        Fixed CPU profiler crash in start / stop sequence when non-existent
        name is passed (issue http://crbug.com/51594).

        Introduced new indexed property query callbacks API (issue 816). This
        API is guarded by USE_NEW_QUERY_CALLBACK define and is disabled
        by default.

        Removed support for object literal get/set with number/string
        property name.

        Fixed handling of JSObject::elements in CalculateNetworkSize
        (issue 822).

        Allowed compiling with strict aliasing enabled on GCC 4.4 (issue 463).


2010-08-09: Version 2.3.6

        RegExp literals create a new object every time they are evaluated
        (issue 704).

        Object.seal and Object.freeze return the modified object (issue 809).

        Fixed building using GCC 4.4.4.


2010-08-04: Version 2.3.5

        Added support for ES5 property names. Object initialisers and
        dot-notation property access now allows keywords. Also allowed
        non-identifiers after "get" or "set" in an object initialiser.

        Randomized the addresses of allocated executable memory on Windows.


2010-08-02: Version 2.3.4

        Fixed problems in implementation of ES5 function.prototype.bind.

        Fixed error when using apply with arguments object on ARM (issue 784).

        Added setting of global flags to debugger protocol.

        Fixed an error affecting cached results of sin and cos (issue 792).

        Removed memory leak from a boundary case where V8 is not initialized.

        Fixed issue where debugger could set breakpoints outside the body
        of a function.

        Fixed issue in debugger when using both live edit and step in features.

        Added Number-letter (Nl) category to Unicode tables.  These characters
        can now be used in identifiers.

        Fixed an assert failure on X64 (issue 806).

        Performance improvements on all platforms.


2010-07-26: Version 2.3.3

        Fixed error when building the d8 shell in a fresh checkout.

        Implemented Function.prototype.bind (ES5 15.3.4.5).

        Fixed an error in inlined stores on ia32.

        Fixed an error when setting a breakpoint at the end of a function
        that does not end with a newline character.

        Performance improvements on all platforms.


2010-07-21: Version 2.3.2

        Fixed compiler warnings when building with LLVM.

        Fixed a bug with for-in applied to strings (issue 785).

        Performance improvements on all platforms.


2010-07-19: Version 2.3.1

        Fixed compilation and linking with V8_INTERPRETED_REGEXP flag.

        Fixed bug related to code flushing while compiling a lazy
        compilable function (issue http://crbug.com/49099).

        Performance improvements on all platforms.


2010-07-15: Version 2.3.0

        Added ES5 Object.seal and Object.isSealed.

        Added debugger API for scheduling debugger commands from a
        separate thread.


2010-07-14: Version 2.2.24

        Added API for capturing stack traces for uncaught exceptions.

        Fixed crash bug when preparsing from a non-external V8 string
        (issue 775).

        Fixed JSON.parse bug causing input not to be converted to string
        (issue 764).

        Added ES5 Object.freeze and Object.isFrozen.

        Performance improvements on all platforms.


2010-07-07: Version 2.2.23

        API change: Convert Unicode code points outside the basic multilingual
        plane to the replacement character.  Previous behavior was to silently
        truncate the value to 16 bits.

        Fixed crash: handle all flat string types in regexp replace.

        Prevent invalid pre-parsing data passed in through the API from
        crashing V8.

        Performance improvements on all platforms.


2010-07-05: Version 2.2.22

        Added ES5 Object.isExtensible and Object.preventExtensions.

        Enabled building V8 as a DLL.

        Fixed a bug in date code where -0 was not interpreted as 0
        (issue 736).

        Performance improvements on all platforms.


2010-06-30: Version 2.2.21

        Fixed bug in externalizing some ASCII strings (Chromium issue 47824).

        Updated JSON.stringify to floor the space parameter (issue 753).

        Updated the Mozilla test expectations to the newest version.

        Updated the ES5 Conformance Test expectations to the latest version.

        Updated the V8 benchmark suite.

        Provide actual breakpoints locations in response to setBreakpoint
        and listBreakpoints requests.


2010-06-28: Version 2.2.20

        Fixed bug with for-in on x64 platform (issue 748).

        Fixed crash bug on x64 platform (issue 756).

        Fixed bug in Object.getOwnPropertyNames. (chromium issue 41243).

        Fixed a bug on ARM that caused the result of 1 << x to be
        miscalculated for some inputs.

        Performance improvements on all platforms.


2010-06-23: Version 2.2.19

        Fixed bug that causes the build to break when profillingsupport=off
        (issue 738).

        Added expose-externalize-string flag for testing extensions.

        Resolve linker issues with using V8 as a DLL causing a number of
        problems with unresolved symbols.

        Fixed build failure for cctests when ENABLE_DEBUGGER_SUPPORT is not
        defined.

        Performance improvements on all platforms.


2010-06-16: Version 2.2.18

        Added API functions to retrieve information on indexed properties
        managed by the embedding layer.  Fixes bug 737.

        Made ES5 Object.defineProperty support array elements.  Fixes bug 619.

        Added heap profiling to the API.

        Removed old named property query from the API.

        Incremental performance improvements.


2010-06-14: Version 2.2.17

        Improved debugger support for stepping out of functions.

        Incremental performance improvements.


2010-06-09: Version 2.2.16

        Removed the SetExternalStringDiposeCallback API. Changed the
        disposal of external string resources to call a virtual Dispose
        method on the resource.

        Added support for more precise break points when debugging and
        stepping.

        Memory usage improvements on all platforms.


2010-06-07: Version 2.2.15

        Added an API to control the disposal of external string resources.

        Added missing initialization of a couple of variables which makes
        some compilers complaint when compiling with -Werror.

        Improved performance on all platforms.


2010-06-02: Version 2.2.14

        Fixed a crash in code generated for String.charCodeAt.

        Fixed a compilation issue with some GCC versions (issue 727).

        Performance optimizations on x64 and ARM platforms.


2010-05-31: Version 2.2.13

        Implemented Object.getOwnPropertyDescriptor for element indices and
        strings (issue 599).

        Fixed bug for windows 64 bit C calls from generated code.

        Added new scons flag unalignedaccesses for arm builds.

        Performance improvements on all platforms.


2010-05-26: Version 2.2.12

        Allowed accessors to be defined on objects rather than just object
        templates.

        Changed the ScriptData API.


2010-05-21: Version 2.2.11

        Fixed crash bug in liveedit on 64 bit.

        Use 'full compiler' when debugging is active.  This should increase
        the density of possible break points, making single step more fine
        grained.  This will only take effect for functions compiled after
        debugging has been started, so recompilation of all functions is
        required to get the full effect.  IA32 and x64 only for now.

        Misc. fixes to the Solaris build.

        Added new flags --print-cumulative-gc-stat and --trace-gc-nvp.

        Added filtering of CPU profiles by security context.

        Fixed crash bug on ARM when running without VFP2 or VFP3.

        Incremental performance improvements in all backends.


2010-05-17: Version 2.2.10

        Performance improvements in the x64 and ARM backends.


2010-05-10: Version 2.2.9

        Allowed Object.create to be called with a function (issue 697).

        Fixed bug with Date.parse returning a non-NaN value when called on a
        non date string (issue 696).

        Allowed unaligned memory accesses on ARM targets that support it (by
        Subrato K De of CodeAurora ).

        C++ API for retrieving JavaScript stack trace information.


2010-05-05: Version 2.2.8

        Performance improvements in the x64 and ARM backends.


2010-05-03: Version 2.2.7

        Added support for ES5 date time string format to Date.parse.

        Performance improvements in the x64 backend.


2010-04-28: Version 2.2.6

        Added "amd64" as recognized architecture in scons build script
        (by Ryan Dahl ).

        Fixed bug in String search and replace with very simple RegExps.

        Fixed bug in RegExp containing "\b^".

        Performance improvements on all platforms.


2010-04-26: Version 2.2.5

        Various performance improvements (especially for ARM and x64)

        Fixed bug in CPU profiling (http://crbug.com/42137)

        Fixed a bug with the natives cache.

        Fixed two bugs in the ARM code generator that can cause
        wrong calculations.

        Fixed a bug that may cause a wrong result for shift operations.


2010-04-21: Version 2.2.4

        Fixed warnings on arm on newer GCC versions.

        Fixed a number of minor bugs.

        Performance improvements on all platforms.


2010-04-14: Version 2.2.3

        Added stack command and mem command to ARM simulator debugger.

        Fixed scons snapshot and ARM build, and Windows X64 build issues.

        Performance improvements on all platforms.


2010-04-12: Version 2.2.2

        Introduced new profiler API.

        Fixed random number generator to produce full 32 random bits.


2010-04-06: Version 2.2.1

        Debugger improvements.

        Fixed minor bugs.


2010-03-29: Version 2.2.0

        Fixed a few minor bugs.

        Performance improvements for string operations.


2010-03-26: Version 2.1.10

        Fixed scons build issues.

        Fixed a couple of minor bugs.


2010-03-25: Version 2.1.9

        Added API support for reattaching a global object to a context.

        Extended debugger API with access to the internal debugger context.

        Fixed Chromium crashes (issues http://crbug.com/39128 and
        http://crbug.com/39160)


2010-03-24: Version 2.1.8

        Added fine-grained garbage collection callbacks to the API.

        Performance improvements on all platforms.


2010-03-22: Version 2.1.7

        Fixed issue 650.

        Fixed a bug where __proto__ was sometimes enumerated (issue 646).

        Performance improvements for arithmetic operations.

        Performance improvements for string operations.

        Print script name and line number information in stack trace.


2010-03-17: Version 2.1.6

        Performance improvements for arithmetic operations.

        Performance improvements for string operations.


2010-03-10: Version 2.1.4

        Fixed code cache lookup for keyed IC's (issue http://crbug.com/37853).

        Performance improvements on all platforms.


2010-03-10: Version 2.1.3

        Added API method for context-disposal notifications.

        Added API method for accessing elements by integer index.

        Added missing implementation of Uint32::Value and Value::IsUint32
        API methods.

        Added IsExecutionTerminating API method.

        Disabled strict aliasing for GCC 4.4.

        Fixed string-concatenation bug (issue 636).

        Performance improvements on all platforms.


2010-02-23: Version 2.1.2

        Fixed a crash bug caused by wrong assert.

        Fixed a bug with register names on 64-bit V8 (issue 615).

        Performance improvements on all platforms.


2010-02-19: Version 2.1.1

        [ES5] Implemented Object.defineProperty.

        Improved profiler support.

        Added SetPrototype method in the public V8 API.

        Added GetScriptOrigin and GetScriptLineNumber methods to Function
        objects in the API.

        Performance improvements on all platforms.


2010-02-03: Version 2.1.0

        Values are now always wrapped in objects when used as a receiver.
        (issue 223).

        [ES5] Implemented Object.getOwnPropertyNames.

        [ES5] Restrict JSON.parse to only accept strings that conforms to the
        JSON grammar.

        Improvement of debugger agent (issue 549 and 554).

        Fixed problem with skipped stack frame in profiles (issue 553).

        Solaris support by Erich Ocean  and Ryan Dahl
        .

        Fixed a bug that Math.round() returns incorrect results for huge
        integers.

        Fixed enumeration order for objects created from some constructor
        functions (isue http://crbug.com/3867).

        Fixed arithmetic on some integer constants (issue 580).

        Numerous performance improvements including porting of previous IA-32
        optimizations to x64 and ARM architectures.


2010-01-14: Version 2.0.6

        Added ES5 Object.getPrototypeOf, GetOwnPropertyDescriptor,
        GetOwnProperty, FromPropertyDescriptor.

        Fixed Mac x64 build errors.

        Improved performance of some math and string operations.

        Improved performance of some regexp operations.

        Improved performance of context creation.

        Improved performance of hash tables.


2009-12-18: Version 2.0.5

        Extended to upper limit of map space to allow for 7 times as many map
        to be allocated (issue 524).

        Improved performance of code using closures.

        Improved performance of some binary operations involving doubles.


2009-12-16: Version 2.0.4

        Added ECMAScript 5 Object.create.

        Improved performance of Math.max and Math.min.

        Optimized adding of strings on 64-bit platforms.

        Improved handling of external strings by using a separate table
        instead of weak handles.  This improves garbage collection
        performance and uses less memory.

        Changed code generation for object and array literals in toplevel
        code to be more compact by doing more work in the runtime.

        Fixed a crash bug triggered when garbage collection happened during
        generation of a callback load inline cache stub.

        Fixed crash bug sometimes triggered when local variables shadowed
        parameters in functions that used the arguments object.


2009-12-03: Version 2.0.3

        Optimized handling and adding of strings, for-in and Array.join.

        Heap serialization is now non-destructive.

        Improved profiler support with information on time spend in C++
        callbacks registered through the API.

        Added commands to the debugger protocol for starting/stopping
        profiling.

        Enabled the non-optimizing compiler for top-level code.

        Changed the API to only allow strings to be set as data objects on
        Contexts and scripts to avoid potentially keeping global objects
        around for too long (issue 528).

        OpenBSD support patch by Peter Valchev .

        Fixed bugs.


2009-11-24: Version 2.0.2

        Improved profiler support.

        Fixed bug that broke compilation of d8 with readline support.


2009-11-20: Version 2.0.1

        Fixed crash bug in String.prototype.replace.

        Reverted a change which caused Chromium interactive ui test
        failures.


2009-11-18: Version 2.0.0

        Added support for VFP on ARM.

        Added TryCatch::ReThrow method to the API.

        Reduced the size of snapshots and improved the snapshot load time.

        Improved heap profiler support.

        64-bit version now supported on Windows.

        Fixed a number of debugger issues.

        Fixed bugs.


2009-10-29: Version 1.3.18

        Reverted a change which caused crashes in RegExp replace.

        Reverted a change which caused Chromium ui_tests failure.


2009-10-28: Version 1.3.17

        Added API method to get simple heap statistics.

        Improved heap profiler support.

        Fixed the implementation of the resource constraint API so it
        works when using snapshots.

        Fixed a number of issues in the Windows 64-bit version.

        Optimized calls to API getters.

        Added valgrind notification on code modification to the 64-bit version.

        Fixed issue where we logged shared library addresses on Windows at
        startup and never used them.


2009-10-16: Version 1.3.16

        X64: Convert smis to holding 32 bits of payload.

        Introduced v8::Integer::NewFromUnsigned method.

        Added missing null check in Context::GetCurrent.

        Added trim, trimLeft and trimRight methods to String
        Patch by Jan de Mooij 

        Implement ES5 Array.isArray
        Patch by Jan de Mooij 

        Skip access checks for hidden properties.

        Added String::Concat(Handle left, Handle right) to the
        V8 API.

        Fixed GYP-based builds of V8.


2009-10-07: Version 1.3.15

        Expanded the maximum size of the code space to 512MB for 64-bit mode.

        Fixed a crash bug happening when starting profiling (issue
        http://crbug.com/23768).


2009-10-07: Version 1.3.14

        Added GetRealNamedProperty to the API to lookup real properties
        located on the object or in the prototype chain skipping any
        interceptors.

        Fixed the stack limits setting API to work correctly with threads. The
        stack limit now needs to be set to each thread thich is used with V8.

        Removed the high-priority flag from IdleNotification()

        Ensure V8 is initialized before locking and unlocking threads.

        Implemented a new JavaScript minifier for compressing the source of
        the built-in JavaScript. This removes non-Open Source code from Douglas
        Crockford from the project.

        Added a missing optimization in StringCharAt.

        Fixed some flaky socket tests.

        Change by Alexander Botero-Lowry to fix profiler sampling on FreeBSD
        in 64-bit mode.

        Fixed memory leaks in the thread management code.

        Fixed the result of assignment to a pixel array. The assigned value
        is now the result.

        Error reporting for invalid left-hand sides in for-in statements, pre-
        and postfix count expressions, and assignments now matches the JSC
        behavior in Safari 4.

        Follow the spec in disallowing function declarations without a name.

        Always allocate code objects within a 2 GB range. On x64 architecture
        this is used to use near calls (32-bit displacement) in Code objects.

        Optimized array construction ported to x64 and ARM architectures.

        [ES5] Changed Object.keys to return strings for element indices.


2009-09-23: Version 1.3.13

        Fixed uninitialized memory problem.

        Improved heap profiler support.


2009-09-22: Version 1.3.12

        Changed behavior of |function|.toString() on built-in functions to
        be compatible with other implementations.  Patch by Jan de Mooij.

        Added Object::IsDirty in the API.

        Optimized array construction; it is now handled purely in native
        code.

        [ES5] Made properties of the arguments array enumerable.

        [ES5] Added test suite adapter for the es5conform test suite.

        [ES5] Added Object.keys function.


2009-09-15: Version 1.3.11

        Fixed crash in error reporting during bootstrapping.

        Optimized generated IA32 math code by using SSE2 instructions when
        available.

        Implemented missing pieces of debugger infrastructure on ARM.  The
        debugger is now fully functional on ARM.

        Made 'hidden' the default visibility for gcc.


2009-09-09: Version 1.3.10

        Fixed profiler on Mac in 64-bit mode.

        Optimized creation of objects from simple constructor functions on
        ARM.

        Fixed a number of debugger issues.

        Reduced the amount of memory consumed by V8.


2009-09-02: Version 1.3.9

        Optimized stack guard checks on ARM.

        Optimized API operations by inlining more in the API.

        Optimized creation of objects from simple constructor functions.

        Enabled a number of missing optimizations in the 64-bit port.

        Implemented native-code support for regular expressions on ARM.

        Stopped using the 'sahf' instruction on 64-bit machines that do
        not support it.

        Fixed a bug in the support for forceful termination of JavaScript
        execution.


2009-08-26: Version 1.3.8

        Changed the handling of idle notifications to allow idle
        notifications when V8 has not yet been initialized.

        Fixed ARM simulator compilation problem on Windows.


2009-08-25: Version 1.3.7

        Reduced the size of generated code on ARM platforms by reducing
        the size of constant pools.

        Changed build files to not include the 'ENV' user environment
        variable in the build environment.

        Changed the handling of idle notifications.


2009-08-21: Version 1.3.6

        Added support for forceful termination of JavaScript execution.

        Added low memory notification to the API. The embedding host can signal
        a low memory situation to V8.

        Changed the handling of global handles (persistent handles in the API
        sense) to avoid issues regarding allocation of new global handles
        during weak handle callbacks.

        Changed the growth policy of the young space.

        Fixed a GC issue introduced in version 1.3.5.


2009-08-19: Version 1.3.5

        Optimized initialization of some arrays in the builtins.

        Fixed mac-nm script to support filenames with spaces.

        Support for using the V8 profiler when V8 is embedded in a Windows DLL.

        Changed typeof RegExp from 'object' to 'function' for compatibility.
        Fixed bug where regexps were not callable across contexts.

        Added context independent script compilation to the API.

        Added API call to get the stack trace for an exception.

        Added API for getting object mirrors.

        Made sure that SSE3 instructions are used whenever possible even when
        running off a snapshot generated without using SSE3 instructions.

        Tweaked the handling of the initial size and growth policy of the heap.

        Added native code generation for RegExp to 64-bit version.

        Added JavaScript debugger support to 64-bit version.


2009-08-13: Version 1.3.4

        Added a readline() command to the d8 shell.

        Fixed bug in json parsing.

        Added idle notification to the API and reduced memory on idle
        notifications.


2009-08-12: Version 1.3.3

        Fixed issue 417: incorrect %t placeholder expansion.

        Added .gitignore file similar to Chromium's one.

        Fixed SConstruct file to build with new logging code for Android.

        API: added function to find instance of template in prototype
        chain.  Inlined Object::IsInstanceOf.

        Land change to notify valgrind when we modify code on x86.

        Added api call to determine whether a string can be externalized.

        Added a write() command to d8.


2009-08-05: Version 1.3.2

        Started new compiler infrastructure for two-pass compilation using a
        control flow graph constructed from the AST.

        Profiler stack sampling for X64.

        Safe handling of NaN to Posix platform-dependent time functions.

        Added a new profiler control API to unify controlling various aspects
        of profiling.

        Fixed issue 392.


2009-07-30: Version 1.3.1

        Speed improvements to accessors and interceptors.

        Added support for capturing stack information on custom errors.

        Added support for morphing an object into a pixel array where its
        indexed properties are stored in an external byte array. Values written
        are always clamped to the 0..255 interval.

        Profiler on x64 now handles C/C++ functions from shared libraries.

        Changed the debugger to avoid stepping into function.call/apply if the
        function is a built-in.

        Initial implementation of constructor heap profile for JS objects.

        More fine grained control of profiling aspects through the API.

        Optimized the called as constructor check for API calls.


2009-07-27: Version 1.3.0

        Allowed RegExp objects to be called as functions (issue 132).

        Fixed issue where global property cells would escape after
        detaching the global object; see http://crbug.com/16276.

        Added support for stepping into setters and getters in the
        debugger.

        Changed the debugger to avoid stopping in its own JavaScript code
        and in the code of built-in functions.

        Fixed issue 345 by avoiding duplicate escaping labels.

        Fixed ARM code generator crash in short-circuited boolean
        expressions and added regression tests.

        Added an external allocation limit to avoid issues where small V8
        objects would hold on to large amounts of external memory without
        causing garbage collections.

        Finished more of the inline caching stubs for x64 targets.


2009-07-13: Version 1.2.14

        Added separate paged heap space for global property cells and
        avoid updating the write barrier when storing into them.

        Improved peep-hole optimization on ARM platforms by not emitting
        unnecessary debug information.

        Re-enabled ICs for loads and calls that skip a global object
        during lookup through the prototype chain.

        Allowed access through global proxies to use ICs.

        Fixed issue 401.


2009-07-09: Version 1.2.13

        Fixed issue 397, issue 398, and issue 399.

        Added support for breakpoint groups.

        Fixed bugs introduced with the new global object representation.

        Fixed a few bugs in the ARM code generator.


2009-07-06: Version 1.2.12

        Added stack traces collection to Error objects accessible through
        the e.stack property.

        Changed RegExp parser to use a recursive data structure instead of
        stack-based recursion.

        Optimized Date object construction and string concatenation.

        Improved performance of div, mod, and mul on ARM platforms.


2009-07-02: Version 1.2.11

        Improved performance on IA-32 and ARM.

        Fixed profiler sampler implementation on Mac OS X.

        Changed the representation of global objects to improve
        performance of adding a lot of new properties.


2009-06-29: Version 1.2.10

        Improved debugger support.

        Fixed bug in exception message reporting (issue 390).

        Improved overall performance.


2009-06-23: Version 1.2.9

        Improved math performance on ARM.

        Fixed profiler name-inference bug.

        Fixed handling of shared libraries in the profiler tick processor
        scripts.

        Fixed handling of tests that time out in the test scripts.

        Fixed compilation on MacOS X version 10.4.

        Fixed two bugs in the regular expression engine.

        Fixed a bug in the string type inference.

        Fixed a bug in the handling of 'constant function' properties.

        Improved overall performance.


2009-06-16: Version 1.2.8

        Optimized math on ARM platforms.

        Fixed two crash bugs in the handling of getters and setters.

        Improved the debugger support by adding scope chain information.

        Improved the profiler support by compressing log data transmitted
        to clients.

        Improved overall performance.


2009-06-08: Version 1.2.7

        Improved debugger and profiler support.

        Reduced compilation time by improving the handling of deferred
        code.

        Optimized interceptor accesses where the property is on the object
        on which the interceptors is attached.

        Fixed compilation problem on GCC 4.4 by changing the stack
        alignment to 16 bytes.

        Fixed handle creation to follow stric aliasing rules.

        Fixed compilation on FreeBSD.

        Introduced API for forcing the deletion of a property ignoring
        interceptors and attributes.


2009-05-29: Version 1.2.6

        Added a histogram recording hit rates at different levels of the
        compilation cache.

        Added stack overflow check for the RegExp analysis phase. Previously a
        very long regexp graph could overflow the stack with recursive calls.

        Use a dynamic buffer when collecting log events in memory.

        Added start/stop events to the profiler log.

        Fixed infinite loop which could happen when setting a debug break while
        executing a RegExp compiled to native code.

        Fixed handling of lastIndexOf called with negative index (issue 351).

        Fixed irregular crash in profiler test (issue 358).

        Fixed compilation issues with some versions of gcc.


2009-05-26: Version 1.2.5

        Fixed bug in initial boundary check for Boyer-Moore text
        search (issue 349).

        Fixed compilation issues with MinGW and gcc 4.3+ and added support
        for armv7 and cortex-a8 architectures.  Patches by Lei Zhang and
        Craig Schlenter.

        Added a script cache to the debugger.

        Optimized compilation performance by improving internal data
        structures and avoiding expensive property load optimizations for
        code that's infrequently executed.

        Exposed the calling JavaScript context through the static API
        function Context::GetCalling().


2009-05-18: Version 1.2.4

        Improved performance of floating point number allocation for ARM
        platforms.

        Fixed crash when using the instanceof operator on functions with
        number values in their prototype chain (issue 341).

        Optimized virtual frame operations in the code generator to speed
        up compilation time and allocated the frames in the zone.

        Made the representation of virtual frames and jump targets in the
        code generator much more compact.

        Avoided linear search for non-locals in scope code when resolving
        variables inside with and eval scopes.

        Optimized lexical scanner by dealing with whitespace as part of
        the token scanning instead of as a separate step before it.

        Changed the scavenging collector so that promoted objects do not
        reside in the old generation while their remembered set is being
        swept for pointers into the young generation.

        Fixed numeric overflow handling when compiling count operations.


2009-05-11: Version 1.2.3

        Fixed bug in reporting of out-of-memory situations.

        Introduced hidden prototypes on certain builtin prototype objects
        such as String.prototype to emulate JSC's behavior of restoring
        the original function when deleting functions from those prototype
        objects.

        Fixed crash bug in the register allocator.


2009-05-04: Version 1.2.2

        Fixed bug in array sorting for sparse arrays (issue 326).

        Added support for adding a soname when building a shared library
        on Linux (issue 151).

        Fixed bug caused by morphing internal ASCII strings to external
        two-byte strings.  Slices over ASCII strings have to forward ASCII
        checks to the underlying buffer string.

        Allowed API call-as-function handlers to be called as
        constructors.

        Fixed a crash bug where an external string was disposed but a
        slice of the external string survived as a symbol.


2009-04-27: Version 1.2.1

        Added EcmaScript 5 JSON object.

        Fixed bug in preemption support on ARM.


2009-04-23: Version 1.2.0

        Optimized floating-point operations on ARM.

        Added a number of extensions to the debugger API.

        Changed the enumeration order for unsigned integer keys to always
        be numerical order.

        Added a "read" extension to the shell sample.

        Added support for Array.prototype.reduce and
        Array.prototype.reduceRight.

        Added an option to the SCons build to control Microsoft Visual C++
        link-time code generation.

        Fixed a number of bugs (in particular issue 315, issue 316,
        issue 317 and issue 318).


2009-04-15: Version 1.1.10

        Fixed crash bug that occurred when loading a const variable in the
        presence of eval.

        Allowed using with and eval in registered extensions in debug mode
        by fixing bogus assert.

        Fixed the source position for function returns to enable the
        debugger to break there.


2009-04-14: Version 1.1.9

        Made the stack traversal code in the profiler robust by avoiding
        to look into the heap.

        Added name inferencing for anonymous functions to facilitate
        debugging and profiling.

        Re-enabled stats timers in the developer shell (d8).

        Fixed issue 303 by avoiding to shortcut cons-symbols.


2009-04-11: Version 1.1.8

        Changed test-debug/ThreadedDebugging to be non-flaky (issue 96).

        Fixed step-in handling for Function.prototype.apply and call in
        the debugger (issue 269).

        Fixed v8::Object::DeleteHiddenValue to not bail out when there
        are no hidden properties.

        Added workaround for crash bug, where external symbol table
        entries with deleted resources would lead to NPEs when looking
        up in the symbol table.


2009-04-07: Version 1.1.7

        Added support for easily importing additional environment
        variables into the SCons build.

        Optimized strict equality checks.

        Fixed crash in indexed setters on objects without a corresponding
        getter (issue 298).

        Re-enabled script compilation cache.


2009-04-01: Version 1.1.6

        Reverted an unsafe code generator change.


2009-04-01: Version 1.1.5

        Fixed bug that caused function literals to not be optimized as
        much as other functions.

        Improved profiler support.

        Fixed a crash bug in connection with debugger unloading.

        Fixed a crash bug in the code generator caused by losing the
        information that a frame element was copied.

        Fixed an exception propagation bug that could cause non-null
        return values when exceptions were thrown.


2009-03-30: Version 1.1.4

        Optimized String.prototype.match.

        Improved the stack information in profiles.

        Fixed bug in ARM port making it possible to compile the runtime
        system for thumb mode again.

        Implemented a number of optimizations in the code generator.

        Fixed a number of memory leaks in tests.

        Fixed crash bug in connection with script source code and external
        strings.


2009-03-24: Version 1.1.3

        Fixed assertion failures in compilation of loop conditions.

        Removed STL dependency from developer shell (d8).

        Added infrastructure for protecting the V8 heap from corruption
        caused by memory modifications from the outside.


2009-03-24: Version 1.1.2

        Improved frame merge code generated by the code generator.

        Optimized String.prototype.replace.

        Implemented __defineGetter__ and __defineSetter__ for properties
        with integer keys on non-array objects.

        Improved debugger and profiler support.

        Fixed a number of portability issues to allow compilation for
        smaller ARM devices.

        Exposed object cloning through the API.

        Implemented hidden properties.  This is used to expose an identity
        hash for objects through the API.

        Implemented restarting of regular expressions if their input
        string changes representation during preemption.

        Fixed a code generator bug that could cause assignments in loops
        to be ignored if using continue to break out of the loop (issue
        284).


2009-03-12: Version 1.1.1

        Fixed an assertion in the new compiler to take stack overflow
        exceptions into account.

        Removed exception propagation code that could cause crashes.

        Fixed minor bug in debugger line number computations.

        8-byte align the C stack on Linux and Windows to speed up floating
        point computations.


2009-03-12: Version 1.1.0

        Improved code generation infrastructure by doing simple register
        allocation and constant folding and propagation.

        Optimized regular expression matching by avoiding to create
        intermediate string arrays and by flattening nested array
        representations of RegExp data.

        Traverse a few stack frames when recording profiler samples to
        include partial call graphs in the profiling output.

        Added support for using OProfile to profile generated code.

        Added remote debugging support to the D8 developer shell.

        Optimized creation of nested literals like JSON objects.

        Fixed a bug in garbage collecting unused maps and turned it on by
        default (--collect-maps).

        Added support for running tests under Valgrind.


2009-02-27: Version 1.0.3

        Optimized double-to-integer conversions in bit operations by using
        SSE3 instructions if available.

        Optimized initialization sequences that store to multiple
        properties of the same object.

        Changed the D8 debugger frontend to use JSON messages.

        Force garbage collections when disposing contexts.

        Align code objects at 32-byte boundaries.


2009-02-25: Version 1.0.2

        Improved profiling support by performing simple call stack
        sampling for ticks and by fixing a bug in the logging of code
        addresses.

        Fixed a number of debugger issues.

        Optimized code that uses eval.

        Fixed a couple of bugs in the regular expression engine.

        Reduced the size of generated code for certain regular expressions.

        Removed JSCRE completely.

        Fixed issue where test could not be run if there was a dot in the
        checkout path.


2009-02-13: Version 1.0.1

        Fixed two crash-bugs in irregexp (issue 231 and 233).

        Fixed a number of minor bugs (issue 87, 227 and 228).

        Added support for morphing strings to external strings on demand
        to avoid having to create copies in the embedding code.

        Removed experimental support for external symbol callbacks.


2009-02-09: Version 1.0.0

        Fixed crash-bug in the code generation for case independent 16 bit
        backreferences.

        Made shells more robust in the presence of string conversion
        failures (issue 224).

        Fixed a potential infinite loop when attempting to resolve
        eval (issue 221).

        Miscellaneous fixes to the new regular expression engine.

        Reduced binary by stripping unneeded text from JavaScript library and
        minifying some JavaScript files.


2009-01-27: Version 0.4.9

        Enabled new regular expression engine.

        Made a number of changes to the debugger protocol.

        Fixed a number of bugs in the preemption support.

        Added -p option to the developer shell to run files in parallel
        using preemption.

        Fixed a number of minor bugs (including issues 176, 187, 189, 192,
        193, 198 and 201).

        Fixed a number of bugs in the serialization/deserialization
        support for the ARM platform.


2009-01-19: Version 0.4.8.1

        Minor patch to debugger support.


2009-01-16: Version 0.4.8

        Fixed string length bug on ARM (issue 171).

        Made most methods in the API const.

        Optimized object literals by improving data locality.

        Fixed bug that caused incomplete functions to be cached in case of
        stack overflow exceptions.

        Fixed bugs that caused catch variables and variables introduced by
        eval to behave incorrectly when using accessors (issues 186, 190
        and 191).


2009-01-06: Version 0.4.7

        Minor bugfixes and optimizations.

        Added command line debugger to D8 shell.

        Fixed subtle bug that caused the wrong 'this' to be used when
        calling a caught function in a catch clause.

        Inline array loads within loops directly in the code instead of
        always calling a stub.


2008-12-11: Version 0.4.6

        Fixed exception reporting bug where certain exceptions were
        incorrectly reported as uncaught.

        Improved the memory allocation strategy used during compilation to
        make running out of memory when compiling huge scripts less
        likely.

        Optimized String.replace by avoiding the construction of certain
        sub strings.

        Fixed bug in code generation for large switch statements on ARM.

        Fixed bug that caused V8 to change the global object template
        passed in by the user.

        Changed the API for creating object groups used during garbage
        collection.  Entire object groups are now passed to V8 instead of
        individual members of the groups.


2008-12-03: Version 0.4.5

        Added experimental API support for allocating V8 symbols as
        external strings.

        Fixed bugs in debugging support on ARM.

        Changed eval implementation to correctly detect whether or not a
        call to eval is aliased.

        Fixed bug caused by a combination of the compilation cache and
        dictionary probing in native code.  The bug caused us to sometimes
        call functions that had not yet been compiled.

        Added platform support for FreeBSD.

        Added support for building V8 on Windows with either the shared or
        static version of MSVCRT

        Added the v8::jscre namespace around the jscre functions to avoid
        link errors (duplicate symbols) when building Google Chrome.

        Added support for calling a JavaScript function with the current
        debugger execution context as its argument to the debugger
        interface.

        Changed the type of names of counters from wchar_t to char.

        Changed the Windows system call used to compute daylight savings
        time.  The system call that we used to use became four times
        slower on WinXP SP3.

        Added support in the d8 developer shell for memory-mapped counters
        and added a stats-viewer tool.

        Fixed bug in upper/lower case mappings (issue 149).


2008-11-17: Version 0.4.4

        Reduced code size by using shorter instruction encoding when
        possible.

        Added a --help option to the shell sample and to the d8 shell.

        Added visual studio project files for building the ARM simulator.

        Fixed a number of ARM simulator issues.

        Fixed bug in out-of-memory handling on ARM.

        Implemented shell support for passing arguments to a script from
        the command line.

        Fixed bug in date code that made certain date functions return -0
        instead of 0 for dates before the epoch.

        Restricted applications of eval so it can only be used in the
        context of the associated global object.

        Treat byte-order marks as whitespace characters.


2008-11-04: Version 0.4.3

        Added support for API accessors that prohibit overwriting by
        accessors defined in JavaScript code by using __defineGetter__ and
        __defineSetter__.

        Improved handling of conditionals in test status files.

        Introduced access control in propertyIsEnumerable.

        Improved performance of some string operations by caching
        information about the type of the string between operations.

        Fixed bug in fast-case code for switch statements that only have
        integer labels.


2008-10-30: Version 0.4.2

        Improved performance of Array.prototype.concat by moving the
        implementation to C++ (issue 123).

        Fixed heap growth policy to avoid growing old space to its maximum
        capacity before doing a garbage collection and fixed issue that
        would lead to artificial out of memory situations (issue 129).

        Fixed Date.prototype.toLocaleDateString to return the date in the
        same format as WebKit.

        Added missing initialization checks to debugger API.

        Added removing of unused maps during GC.


2008-10-28: Version 0.4.1

        Added caching of RegExp data in compilation cache.

        Added Visual Studio project file for d8 shell.

        Fixed function call performance regression introduced in version
        0.4.0 when splitting the global object in two parts (issue 120).

        Fixed issue 131 by checking for empty handles before throwing and
        reporting exceptions.


2008-10-23: Version 0.4.0

        Split the global object into two parts: The state holding global
        object and the global object proxy.

        Fixed bug that affected the value of an assignment to an element
        in certain cases (issue 116).

        Added GetPropertyNames functionality (issue 33) and extra Date
        functions (issue 77) to the API.

        Changed WeakReferenceCallback to take a Persistent instead
        of a Persistent (issue 101).

        Fixed issues with message reporting for exceptions in try-finally
        blocks (issues 73 and 75).

        Optimized flattening of strings and string equality checking.

        Improved Boyer-Moore implementation for faster indexOf operations.

        Added development shell (d8) which includes counters and
        completion support.

        Fixed problem with the receiver passed to functions called from
        eval (issue 124).


2008-10-16: Version 0.3.5

        Improved string hash-code distribution by excluding bit-field bits
        from the hash-code.

        Changed string search algorithm used in indexOf from KMP to
        Boyer-Moore.

        Improved the generated code for the instanceof operator.

        Improved performance of slow-case string equality checks by
        specializing the code based on the string representation.

        Improve the handling of out-of-memory situations (issue 70).

        Improved performance of strict equality checks.

        Improved profiler output to make it easier to see anonymous
        functions.

        Improved performance of slow-case keyed loads.

        Improved property access performance by allocating a number of
        properties in the front object.

        Changed the toString behavior on the built-in object constructors
        to print [native code] instead of the actual source.  Some web
        applications do not like constructors with complex toString
        results.


2008-10-06: Version 0.3.4

        Changed Array.prototype.sort to use quick sort.

        Fixed code generation issue where leaving a finally block with
        break or continue would accumulate elements on the expression
        stack (issue 86).

        Made sure that the name accessor on functions returns the expected
        names for builtin JavaScript functions and C++ callback functions.

        Added fast case code for extending the property storage array of
        JavaScript objects.

        Ported switch statement optimizations introduced in version 0.3.3
        to the ARM code generator.

        Allowed GCC to use strict-aliasing rules when compiling.

        Improved performance of arguments object allocation by taking care
        of arguments adaptor frames in the generated code.

        Updated the V8 benchmark suite to version 2.


2008-09-25: Version 0.3.3

        Improved handling of relocation information to enable more
        peep-hole optimizations.

        Optimized switch statements where all labels are constant small
        integers.

        Optimized String.prototype.indexOf for common cases.

        Fixed more build issues (issue 80).

        Fixed a couple of profiler issues.

        Fixed bug where the body of a function created using the Function
        constructor was not allowed to end with a single-line comment
        (issue 85).

        Improved handling of object literals by canonicalizing object
        literal maps.  This will allow JSON objects with the same set of
        properties to share the same map making inline caching work better
        for JSON objects.


2008-09-17: Version 0.3.2

        Generalized the EvalCache into a CompilationCache and enabled it
        for scripts too.  The current strategy is to retire all entries
        whenever a mark-sweep collection is started.

        Fixed bug where switch statements containing only a default case
        would lead to an unbalanced stack (issue 69).

        Fixed bug that made access to the function in a named function
        expression impossible in certain situations (issue 24).

        Fixed even more build issues.

        Optimized calling conventions on ARM.  The conventions on ARM and
        IA-32 now match.

        Removed static initializers for flags and counters.

        Improved inline caching behavior for uncommon cases where lazily
        loading Date and RegExp code could force certain code paths go
        megamorphic.

        Removed arguments adaption for builtins written in C++.  This
        makes Array.prototype.push and Array.prototype.pop slightly
        faster.


2008-09-11: Version 0.3.1

        Fixed a number of build issues.

        Fixed problem with missing I-cache flusing on ARM.

        Changed space layout in memory management by splitting up
        code space into old data space and code space.

        Added utf-8 conversion support to the API (issue 57).

        Optimized repeated calls to eval with the same strings.  These
        repeated calls are common in web applications.

        Added Xcode project file.

        Optimized a couple of Array operation.

        Fixed parser bug by checking for end-of-string when parsing break
        and continue (issue 35).

        Fixed problem where asian characters were not categorized as
        letters.

        Fixed bug that disallowed calling functions fetched from an array
        using a string as an array index (issue 32).

        Fixed bug where the internal field count on object templates were
        sometimes ignored (issue 54).

        Added -f option to the shell sample for compatibility with other
        engines (issue 18).

        Added source info to TryCatches in the API.

        Fixed problem where the seed for the random number generator was
        clipped in a double to unsigned int conversion.

        Fixed bug where cons string symbols were sometimes converted to
        non-symbol flat strings during GC.

        Fixed bug in error reporting when attempting to convert null to an
        object.


2008-09-04: Version 0.3.0

        Added support for running tests on the ARM simulator.

        Fixed bug in the 'in' operator where negative indices were not
        treated correctly.

        Fixed build issues on gcc-4.3.1.

        Changed Date.prototype.toLocaleTimeString to not print the
        timezone part of the time.

        Renamed debug.h to v8-debug.h to reduce the risk of name conflicts
        with user code.


2008-09-02: Version 0.2.5

        Renamed the top level directory 'public' to 'include'.

        Added 'env' option to the SCons build scripts to support
        overriding the ENV part of the build environment.  This is mostly
        to support Windows builds in cases where SCons cannot find the
        correct paths to the Windows SDK, as these paths cannot be passed
        through shell environment variables.

        Enabled "Buffer Security Check" on for the Windows SCons build and
        added the linker option /OPT:ICF as an optimization.

        Added the V8 benchmark suite to the repository.


2008-09-01: Version 0.2.4

        Included mjsunit JavaScript test suite and C++ unit tests.

        Changed the shell sample to not print the result of executing a
        script provided on the command line.

        Fixed issue when building samples on Windows using a shared V8
        library.  Added visibility option on Linux build which makes the
        generated library 18% smaller.

        Changed build system to accept multiple build modes in one build
        and generate separate objects, libraries and executables for each
        mode.

        Removed deferred negation optimization (a * -b => -(a * b)) since
        this visibly changes operand conversion order.

        Improved parsing performance by introducing stack guard in
        preparsing.  Without a stack guard preparsing always bails out
        with stack overflow.

        Changed shell sample to take flags directly from the command-line.
        Added API call that implements this.

        Added load, quit and version functions to the shell sample so it's
        easier to run benchmarks and tests.

        Fixed issue with building samples and cctests on 64-bit machines.

        Fixed bug in the runtime system where the prototype chain was not
        always searched for a setter when setting a property that does not
        exist locally.


2008-08-14: Version 0.2.3

        Improved performance of garbage collection by moving the
        function that updates pointers during compacting collection
        into the updating visitor.  This gives the compiler a better
        chance to inline and avoid a function call per (potential)
        pointer.

        Extended the shell sample with a --runtime-flags option.

        Added Visual Studio project files for the shell.cc and
        process.cc samples.


2008-08-13: Version 0.2.2

        Improved performance of garbage collection by changing the way
        we use the marking stack in the event of stack overflow during
        full garbage collection and by changing the way we mark roots.

        Cleaned up ARM version by removing top of stack caching and by
        introducing push/pop elimination.

        Cleaned up the way runtime functions are called to allow
        runtime calls with no arguments.

        Changed Windows build options to make sure that exceptions are
        disabled and that optimization flags are enabled.

        Added first version of Visual Studio project files.


2008-08-06: Version 0.2.1

        Improved performance of unary addition by avoiding runtime calls.

        Fixed the handling of '>' and '<=' to use right-to-left conversion
        and left-to-right evaluation as specified by ECMA-262.

        Fixed a branch elimination bug on the ARM platform where incorrect
        code was generated because of overly aggressive branch
        elimination.

        Improved performance of code that repeatedly assigns the same
        function to the same property of different objects with the same
        map.

        Untangled DEBUG and ENABLE_DISASSEMBLER defines.  The disassembler
        no longer expects DEBUG to be defined.

        Added platform-nullos.cc to serve as the basis for new platform
        implementations.


2008-07-30: Version 0.2.0

        Changed all text files to have native svn:eol-style.

        Added a few samples and support for building them. The samples
        include a simple shell that can be used to benchmark and test V8.

        Changed V8::GetVersion to return the version as a string.

        Added source for lazily loaded scripts to snapshots and made
        serialization non-destructive.

        Improved ARM support by fixing the write barrier code to use
        aligned loads and stores and by removing premature locals
        optimization that relied on broken support for callee-saved
        registers (removed).

        Refactored the code for marking live objects during garbage
        collection and the code for allocating objects in paged
        spaces. Introduced an abstraction for the map word of a heap-
        allocated object and changed the memory allocator to allocate
        executable memory only for spaces that may contain code objects.

        Moved StringBuilder to utils.h and ScopedLock to platform.h, where
        they can be used by debugging and logging modules. Added
        thread-safe message queues for dealing with debugger events.

        Fixed the source code reported by toString for certain builtin
        empty functions and made sure that the prototype property of a
        function is enumerable.

        Improved performance of converting values to condition flags in
        generated code.

        Merged disassembler-{arch} files.


2008-07-28: Version 0.1.4

        Added support for storing JavaScript stack traces in a stack
        allocated buffer to make it visible in shallow core dumps.
        Controlled by the --preallocate-message-memory flag which is
        disabled by default.


2008-07-25: Version 0.1.3

        Fixed bug in JSObject::GetPropertyAttributePostInterceptor where
        map transitions would count as properties.

        Allowed aliased eval invocations by treating them as evals in the
        global context. This may change in the future.

        Added support for accessing the last entered context through the
        API and renamed Context::Current to Context::GetCurrent and
        Context::GetSecurityContext to Context::GetCurrentSecurityContext.

        Fixed bug in the debugger that would cause the debugger scripts to
        be recursively loaded and changed all disabling of interrupts to
        be block-structured.

        Made snapshot data read-only to allow it to be more easily shared
        across multiple users of V8 when linked as a shared library.


2008-07-16: Version 0.1.2

        Fixed building on Mac OS X by recognizing i386 and friends as
        IA-32 platforms.

        Added propagation of stack overflow exceptions that occur while
        compiling nested functions.

        Improved debugger with support for recursive break points and
        handling of exceptions that occur in the debugger JavaScript code.

        Renamed GetInternal to GetInternalField and SetInternal to
        SetInternalField in the API and moved InternalFieldCount and
        SetInternalFieldCount from FunctionTemplate to ObjectTemplate.


2008-07-09: Version 0.1.1

        Fixed bug in stack overflow check code for IA-32 targets where a
        non-tagged value in register eax was pushed to the stack.

        Fixed potential quadratic behavior when converting strings to
        numbers.

        Fixed bug where the return value from Object::SetProperty could
        end up being the property holder instead of the written value.

        Improved debugger support by allowing nested break points and by
        dealing with stack-overflows when compiling functions before
        setting break points in them.


2008-07-03: Version 0.1.0

        Initial export.

# Local Variables:
# mode:text
# End:
node-v4.2.6/deps/v8/codereview.settings000644 000766 000024 00000000464 12650222324 020156 0ustar00iojsstaff000000 000000 CODE_REVIEW_SERVER: https://codereview.chromium.org
CC_LIST: v8-reviews@googlegroups.com
VIEW_VC: https://chromium.googlesource.com/v8/v8/+/
STATUS: http://v8-status.appspot.com/status
TRY_ON_UPLOAD: False
TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try-v8
PROJECT: v8
PENDING_REF_PREFIX: refs/pending/
node-v4.2.6/deps/v8/DEPS000644 000766 000024 00000007164 12650222324 014722 0ustar00iojsstaff000000 000000 # Note: The buildbots evaluate this file with CWD set to the parent
# directory and assume that the root of the checkout is in ./v8/, so
# all paths in here must match this assumption.

vars = {
  "git_url": "https://chromium.googlesource.com",
}

deps = {
  "v8/build/gyp":
    Var("git_url") + "/external/gyp.git" + "@" + "5122240c5e5c4d8da12c543d82b03d6089eb77c5",
  "v8/third_party/icu":
    Var("git_url") + "/chromium/deps/icu.git" + "@" + "c81a1a3989c3b66fa323e9a6ee7418d7c08297af",
  "v8/buildtools":
    Var("git_url") + "/chromium/buildtools.git" + "@" + "ecc8e253abac3b6186a97573871a084f4c0ca3ae",
  "v8/testing/gtest":
    Var("git_url") + "/external/googletest.git" + "@" + "23574bf2333f834ff665f894c97bef8a5b33a0a9",
  "v8/testing/gmock":
    Var("git_url") + "/external/googlemock.git" + "@" + "29763965ab52f24565299976b936d1265cb6a271",  # from svn revision 501
  "v8/tools/clang":
    Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "73ec8804ed395b0886d6edf82a9f33583f4a7902",
}

deps_os = {
  "android": {
    "v8/third_party/android_tools":
      Var("git_url") + "/android_tools.git" + "@" + "21f4bcbd6cd927e4b4227cfde7d5f13486be1236",
  },
  "win": {
    "v8/third_party/cygwin":
      Var("git_url") + "/chromium/deps/cygwin.git" + "@" + "c89e446b273697fadf3a10ff1007a97c0b7de6df",
  }
}

include_rules = [
  # Everybody can use some things.
  "+include",
  "+unicode",
  "+third_party/fdlibm",
]

# checkdeps.py shouldn't check for includes in these directories:
skip_child_includes = [
  "build",
  "third_party",
]

hooks = [
  {
    # This clobbers when necessary (based on get_landmines.py). It must be the
    # first hook so that other things that get/generate into the output
    # directory will not subsequently be clobbered.
    'name': 'landmines',
    'pattern': '.',
    'action': [
        'python',
        'v8/build/landmines.py',
    ],
  },
  # Pull clang-format binaries using checked-in hashes.
  {
    "name": "clang_format_win",
    "pattern": ".",
    "action": [ "download_from_google_storage",
                "--no_resume",
                "--platform=win32",
                "--no_auth",
                "--bucket", "chromium-clang-format",
                "-s", "v8/buildtools/win/clang-format.exe.sha1",
    ],
  },
  {
    "name": "clang_format_mac",
    "pattern": ".",
    "action": [ "download_from_google_storage",
                "--no_resume",
                "--platform=darwin",
                "--no_auth",
                "--bucket", "chromium-clang-format",
                "-s", "v8/buildtools/mac/clang-format.sha1",
    ],
  },
  {
    "name": "clang_format_linux",
    "pattern": ".",
    "action": [ "download_from_google_storage",
                "--no_resume",
                "--platform=linux*",
                "--no_auth",
                "--bucket", "chromium-clang-format",
                "-s", "v8/buildtools/linux64/clang-format.sha1",
    ],
  },
  # Pull binutils for linux, enabled debug fission for faster linking /
  # debugging when used with clang on Ubuntu Precise.
  # https://code.google.com/p/chromium/issues/detail?id=352046
  {
    'name': 'binutils',
    'pattern': 'v8/third_party/binutils',
    'action': [
        'python',
        'v8/third_party/binutils/download.py',
    ],
  },
  {
    # Pull clang if needed or requested via GYP_DEFINES.
    # Note: On Win, this should run after win_toolchain, as it may use it.
    'name': 'clang',
    'pattern': '.',
    'action': ['python', 'v8/tools/clang/scripts/update.py', '--if-needed'],
  },
  {
    # A change to a .gyp, .gypi, or to GYP itself should run the generator.
    "pattern": ".",
    "action": ["python", "v8/build/gyp_v8"],
  },
]
node-v4.2.6/deps/v8/include/000755 000766 000024 00000000000 12650222324 015657 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/infra/000755 000766 000024 00000000000 12650222324 015333 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/LICENSE000644 000766 000024 00000005541 12650222324 015246 0ustar00iojsstaff000000 000000 This license applies to all parts of V8 that are not externally
maintained libraries.  The externally maintained libraries used by V8
are:

  - PCRE test suite, located in
    test/mjsunit/third_party/regexp-pcre/regexp-pcre.js.  This is based on the
    test suite from PCRE-7.3, which is copyrighted by the University
    of Cambridge and Google, Inc.  The copyright notice and license
    are embedded in regexp-pcre.js.

  - Layout tests, located in test/mjsunit/third_party/object-keys.  These are
    based on layout tests from webkit.org which are copyrighted by
    Apple Computer, Inc. and released under a 3-clause BSD license.

  - Strongtalk assembler, the basis of the files assembler-arm-inl.h,
    assembler-arm.cc, assembler-arm.h, assembler-ia32-inl.h,
    assembler-ia32.cc, assembler-ia32.h, assembler-x64-inl.h,
    assembler-x64.cc, assembler-x64.h, assembler-mips-inl.h,
    assembler-mips.cc, assembler-mips.h, assembler.cc and assembler.h.
    This code is copyrighted by Sun Microsystems Inc. and released
    under a 3-clause BSD license.

  - Valgrind client API header, located at third_party/valgrind/valgrind.h
    This is release under the BSD license.

These libraries have their own licenses; we recommend you read them,
as their terms may differ from the terms below.

Further license information can be found in LICENSE files located in 
sub-directories.

Copyright 2014, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of Google Inc. nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
node-v4.2.6/deps/v8/LICENSE.strongtalk000644 000766 000024 00000002712 12650222324 017432 0ustar00iojsstaff000000 000000 Copyright (c) 1994-2006 Sun Microsystems Inc.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

- Redistribution in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

- Neither the name of Sun Microsystems or the names of contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
node-v4.2.6/deps/v8/LICENSE.v8000644 000766 000024 00000002767 12650222324 015611 0ustar00iojsstaff000000 000000 Copyright 2006-2011, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.
    * Neither the name of Google Inc. nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
node-v4.2.6/deps/v8/LICENSE.valgrind000644 000766 000024 00000004016 12650222324 017047 0ustar00iojsstaff000000 000000 ----------------------------------------------------------------

Notice that the following BSD-style license applies to this one
file (valgrind.h) only.  The rest of Valgrind is licensed under the
terms of the GNU General Public License, version 2, unless
otherwise indicated.  See the COPYING file in the source
distribution for details.

----------------------------------------------------------------

This file is part of Valgrind, a dynamic binary instrumentation
framework.

Copyright (C) 2000-2007 Julian Seward.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

2. The origin of this software must not be misrepresented; you must 
   not claim that you wrote the original software.  If you use this 
   software in a product, an acknowledgment in the product 
   documentation would be appreciated but is not required.

3. Altered source versions must be plainly marked as such, and must
   not be misrepresented as being the original software.

4. The name of the author may not be used to endorse or promote 
   products derived from this software without specific prior written 
   permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
node-v4.2.6/deps/v8/Makefile000644 000766 000024 00000042344 12650222324 015703 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


# Variable default definitions. Override them by exporting them in your shell.
OUTDIR ?= out
TESTJOBS ?=
GYPFLAGS ?=
TESTFLAGS ?=
ANDROID_NDK_HOST_ARCH ?=
ANDROID_V8 ?= /data/local/tmp/v8
NACL_SDK_ROOT ?=

# Special build flags. Use them like this: "make library=shared"

# library=shared || component=shared_library
ifeq ($(library), shared)
  GYPFLAGS += -Dcomponent=shared_library
endif
ifdef component
  GYPFLAGS += -Dcomponent=$(component)
endif
# console=readline
ifdef console
  GYPFLAGS += -Dconsole=$(console)
endif
# disassembler=on
ifeq ($(disassembler), on)
  GYPFLAGS += -Dv8_enable_disassembler=1
endif
# objectprint=on
ifeq ($(objectprint), on)
  GYPFLAGS += -Dv8_object_print=1
endif
# verifyheap=on
ifeq ($(verifyheap), on)
  GYPFLAGS += -Dv8_enable_verify_heap=1
endif
# tracemaps=on
ifeq ($(tracemaps), on)
  GYPFLAGS += -Dv8_trace_maps=1
endif
# backtrace=off
ifeq ($(backtrace), off)
  GYPFLAGS += -Dv8_enable_backtrace=0
else
  GYPFLAGS += -Dv8_enable_backtrace=1
endif
# verifypredictable=on
ifeq ($(verifypredictable), on)
  GYPFLAGS += -Dv8_enable_verify_predictable=1
endif
# snapshot=off
ifeq ($(snapshot), off)
  GYPFLAGS += -Dv8_use_snapshot='false'
endif
ifeq ($(snapshot), external)
  GYPFLAGS += -Dv8_use_external_startup_data=1
endif
# extrachecks=on/off
ifeq ($(extrachecks), on)
  GYPFLAGS += -Ddcheck_always_on=1 -Dv8_enable_handle_zapping=1
endif
ifeq ($(extrachecks), off)
  GYPFLAGS += -Ddcheck_always_on=0 -Dv8_enable_handle_zapping=0
endif
# slowdchecks=on/off
ifeq ($(slowdchecks), on)
  GYPFLAGS += -Dv8_enable_slow_dchecks=1
endif
ifeq ($(slowdchecks), off)
  GYPFLAGS += -Dv8_enable_slow_dchecks=0
endif
# debugsymbols=on
ifeq ($(debugsymbols), on)
  GYPFLAGS += -Drelease_extra_cflags=-ggdb3
endif
# gdbjit=on/off
ifeq ($(gdbjit), on)
  GYPFLAGS += -Dv8_enable_gdbjit=1
endif
ifeq ($(gdbjit), off)
  GYPFLAGS += -Dv8_enable_gdbjit=0
endif
# vtunejit=on
ifeq ($(vtunejit), on)
  GYPFLAGS += -Dv8_enable_vtunejit=1
endif
# unalignedaccess=on
ifeq ($(unalignedaccess), on)
  GYPFLAGS += -Dv8_can_use_unaligned_accesses=true
endif
# randomseed=12345, disable random seed via randomseed=0
ifdef randomseed
  GYPFLAGS += -Dv8_random_seed=$(randomseed)
endif
# soname_version=1.2.3
ifdef soname_version
  GYPFLAGS += -Dsoname_version=$(soname_version)
endif
# werror=no
ifeq ($(werror), no)
  GYPFLAGS += -Dwerror=''
endif
# presubmit=no
ifeq ($(presubmit), no)
  TESTFLAGS += --no-presubmit
endif
# strictaliasing=off (workaround for GCC-4.5)
ifeq ($(strictaliasing), off)
  GYPFLAGS += -Dv8_no_strict_aliasing=1
endif
# regexp=interpreted
ifeq ($(regexp), interpreted)
  GYPFLAGS += -Dv8_interpreted_regexp=1
endif
# i18nsupport=off
ifeq ($(i18nsupport), off)
  GYPFLAGS += -Dv8_enable_i18n_support=0
  TESTFLAGS += --noi18n
endif
# deprecationwarnings=on
ifeq ($(deprecationwarnings), on)
  GYPFLAGS += -Dv8_deprecation_warnings=1
endif
# imminentdeprecationwarnings=on
ifeq ($(imminentdeprecationwarnings), on)
  GYPFLAGS += -Dv8_imminent_deprecation_warnings=1
endif
# asan=on
ifeq ($(asan), on)
  GYPFLAGS += -Dasan=1 -Dclang=1
  TESTFLAGS += --asan
  ifeq ($(lsan), on)
    GYPFLAGS += -Dlsan=1
  endif
endif
ifdef embedscript
  GYPFLAGS += -Dembed_script=$(embedscript)
endif

# arm specific flags.
# arm_version=
ifneq ($(strip $(arm_version)),)
  GYPFLAGS += -Darm_version=$(arm_version)
else
# Deprecated (use arm_version instead): armv7=false/true
ifeq ($(armv7), false)
  GYPFLAGS += -Darm_version=6
else
ifeq ($(armv7), true)
  GYPFLAGS += -Darm_version=7
endif
endif
endif
# hardfp=on/off. Deprecated, use armfloatabi
ifeq ($(hardfp),on)
  GYPFLAGS += -Darm_float_abi=hard
else
ifeq ($(hardfp),off)
  GYPFLAGS += -Darm_float_abi=softfp
endif
endif
# fpu: armfpu=xxx
# xxx: vfp, vfpv3-d16, vfpv3, neon.
ifeq ($(armfpu),)
  GYPFLAGS += -Darm_fpu=default
else
  GYPFLAGS += -Darm_fpu=$(armfpu)
endif
# float abi: armfloatabi=softfp/hard
ifeq ($(armfloatabi),)
ifeq ($(hardfp),)
  GYPFLAGS += -Darm_float_abi=default
endif
else
  GYPFLAGS += -Darm_float_abi=$(armfloatabi)
endif
# armthumb=on/off
ifeq ($(armthumb), off)
  GYPFLAGS += -Darm_thumb=0
else
ifeq ($(armthumb), on)
  GYPFLAGS += -Darm_thumb=1
endif
endif
# arm_test_noprobe=on
# With this flag set, by default v8 will only use features implied
# by the compiler (no probe). This is done by modifying the default
# values of enable_armv7, enable_vfp3, enable_32dregs and enable_neon.
# Modifying these flags when launching v8 will enable the probing for
# the specified values.
ifeq ($(arm_test_noprobe), on)
  GYPFLAGS += -Darm_test_noprobe=on
endif

# ----------------- available targets: --------------------
# - "grokdump": rebuilds heap constants lists used by grokdump
# - any arch listed in ARCHES (see below)
# - any mode listed in MODES
# - every combination ., e.g. "ia32.release"
# - "native": current host's architecture, release mode
# - any of the above with .check appended, e.g. "ia32.release.check"
# - "android": cross-compile for Android/ARM
# - "nacl" : cross-compile for Native Client (ia32 and x64)
# - default (no target specified): build all DEFAULT_ARCHES and MODES
# - "check": build all targets and run all tests
# - ".clean" for any  in ARCHES
# - "clean": clean all ARCHES

# ----------------- internal stuff ------------------------

# Architectures and modes to be compiled. Consider these to be internal
# variables, don't override them (use the targets instead).
ARCHES = ia32 x64 x32 arm arm64 mips mipsel mips64el x87 ppc ppc64
DEFAULT_ARCHES = ia32 x64 arm
MODES = release debug optdebug
DEFAULT_MODES = release debug
ANDROID_ARCHES = android_ia32 android_x64 android_arm android_arm64 \
		 android_mipsel android_x87
NACL_ARCHES = nacl_ia32 nacl_x64

# List of files that trigger Makefile regeneration:
GYPFILES = third_party/icu/icu.gypi third_party/icu/icu.gyp \
	   build/shim_headers.gypi build/features.gypi build/standalone.gypi \
	   build/toolchain.gypi build/all.gyp build/mac/asan.gyp \
	   test/cctest/cctest.gyp \
	   test/unittests/unittests.gyp tools/gyp/v8.gyp \
	   tools/parser-shell.gyp testing/gmock.gyp testing/gtest.gyp \
	   buildtools/third_party/libc++abi/libc++abi.gyp \
	   buildtools/third_party/libc++/libc++.gyp samples/samples.gyp \
	   src/third_party/vtune/v8vtune.gyp src/d8.gyp

# If vtunejit=on, the v8vtune.gyp will be appended.
ifeq ($(vtunejit), on)
  GYPFILES += src/third_party/vtune/v8vtune.gyp
endif
# Generates all combinations of ARCHES and MODES, e.g. "ia32.release".
BUILDS = $(foreach mode,$(MODES),$(addsuffix .$(mode),$(ARCHES)))
ANDROID_BUILDS = $(foreach mode,$(MODES), \
                   $(addsuffix .$(mode),$(ANDROID_ARCHES)))
NACL_BUILDS = $(foreach mode,$(MODES), \
                   $(addsuffix .$(mode),$(NACL_ARCHES)))
# Generates corresponding test targets, e.g. "ia32.release.check".
CHECKS = $(addsuffix .check,$(BUILDS))
QUICKCHECKS = $(addsuffix .quickcheck,$(BUILDS))
ANDROID_CHECKS = $(addsuffix .check,$(ANDROID_BUILDS))
NACL_CHECKS = $(addsuffix .check,$(NACL_BUILDS))
# File where previously used GYPFLAGS are stored.
ENVFILE = $(OUTDIR)/environment

.PHONY: all check clean builddeps dependencies $(ENVFILE).new native \
        qc quickcheck $(QUICKCHECKS) turbocheck \
        $(addsuffix .quickcheck,$(MODES)) $(addsuffix .quickcheck,$(ARCHES)) \
        $(ARCHES) $(MODES) $(BUILDS) $(CHECKS) $(addsuffix .clean,$(ARCHES)) \
        $(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES)) \
        $(ANDROID_ARCHES) $(ANDROID_BUILDS) $(ANDROID_CHECKS) \
        $(NACL_ARCHES) $(NACL_BUILDS) $(NACL_CHECKS) \
        must-set-NACL_SDK_ROOT

# Target definitions. "all" is the default.
all: $(DEFAULT_MODES)

# Special target for the buildbots to use. Depends on $(OUTDIR)/Makefile
# having been created before.
buildbot:
	$(MAKE) -C "$(OUTDIR)" BUILDTYPE=$(BUILDTYPE) \
	        builddir="$(abspath $(OUTDIR))/$(BUILDTYPE)"

# Compile targets. MODES and ARCHES are convenience targets.
.SECONDEXPANSION:
$(MODES): $(addsuffix .$$@,$(DEFAULT_ARCHES))

$(ARCHES): $(addprefix $$@.,$(DEFAULT_MODES))

# Defines how to build a particular target (e.g. ia32.release).
$(BUILDS): $(OUTDIR)/Makefile.$$@
	@$(MAKE) -C "$(OUTDIR)" -f Makefile.$@ \
	         BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
	                     python -c "print \
	                     raw_input().replace('opt', '').capitalize()") \
	         builddir="$(shell pwd)/$(OUTDIR)/$@"

native: $(OUTDIR)/Makefile.native
	@$(MAKE) -C "$(OUTDIR)" -f Makefile.native \
	         BUILDTYPE=Release \
	         builddir="$(shell pwd)/$(OUTDIR)/$@"

$(ANDROID_ARCHES): $(addprefix $$@.,$(MODES))

$(ANDROID_BUILDS): $(GYPFILES) $(ENVFILE) Makefile.android
	@$(MAKE) -f Makefile.android $@ \
	        ARCH="$(basename $@)" \
	        MODE="$(subst .,,$(suffix $@))" \
	        OUTDIR="$(OUTDIR)" \
	        GYPFLAGS="$(GYPFLAGS)"

$(NACL_ARCHES): $(addprefix $$@.,$(MODES))

$(NACL_BUILDS): $(GYPFILES) $(ENVFILE) \
		   Makefile.nacl must-set-NACL_SDK_ROOT
	@$(MAKE) -f Makefile.nacl $@ \
	        ARCH="$(basename $@)" \
	        MODE="$(subst .,,$(suffix $@))" \
	        OUTDIR="$(OUTDIR)" \
	        GYPFLAGS="$(GYPFLAGS)"

# Test targets.
check: all
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch=$(shell echo $(DEFAULT_ARCHES) | sed -e 's/ /,/g') \
	    $(TESTFLAGS)

$(addsuffix .check,$(MODES)): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --mode=$(basename $@) $(TESTFLAGS)

$(addsuffix .check,$(ARCHES)): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch=$(basename $@) $(TESTFLAGS)

$(CHECKS): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(basename $@) $(TESTFLAGS)

$(addsuffix .quickcheck,$(MODES)): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --mode=$(basename $@) $(TESTFLAGS) --quickcheck

$(addsuffix .quickcheck,$(ARCHES)): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch=$(basename $@) $(TESTFLAGS) --quickcheck

$(QUICKCHECKS): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(basename $@) $(TESTFLAGS) --quickcheck

$(addsuffix .sync, $(ANDROID_BUILDS)): $$(basename $$@)
	@tools/android-sync.sh $(basename $@) $(OUTDIR) \
	                       $(shell pwd) $(ANDROID_V8)

$(addsuffix .check, $(ANDROID_BUILDS)): $$(basename $$@).sync
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	     --arch-and-mode=$(basename $@) \
	     --timeout=600 \
	     --command-prefix="tools/android-run.py" $(TESTFLAGS)

$(addsuffix .check, $(ANDROID_ARCHES)): \
                $(addprefix $$(basename $$@).,$(MODES)).check

$(addsuffix .check, $(NACL_BUILDS)): $$(basename $$@)
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	     --arch-and-mode=$(basename $@) \
	     --timeout=600 --nopresubmit --noi18n \
	     --command-prefix="tools/nacl-run.py"

$(addsuffix .check, $(NACL_ARCHES)): \
                $(addprefix $$(basename $$@).,$(MODES)).check

native.check: native
	@tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR)/native \
	    --arch-and-mode=. $(TESTFLAGS)

SUPERFASTTESTMODES = ia32.release
FASTTESTMODES = $(SUPERFASTTESTMODES),x64.release,ia32.optdebug,x64.optdebug,arm.optdebug,arm64.release
FASTCOMPILEMODES = $(FASTTESTMODES),arm64.optdebug

COMMA = ,
EMPTY =
SPACE = $(EMPTY) $(EMPTY)
quickcheck: $(subst $(COMMA),$(SPACE),$(FASTCOMPILEMODES))
	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(SUPERFASTTESTMODES) $(TESTFLAGS) --quickcheck \
	    --download-data mozilla webkit
	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(FASTTESTMODES) $(TESTFLAGS) --quickcheck
qc: quickcheck

turbocheck: $(subst $(COMMA),$(SPACE),$(FASTCOMPILEMODES))
	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(SUPERFASTTESTMODES) $(TESTFLAGS) \
	    --quickcheck --variants=turbofan --download-data mozilla webkit
	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
	    --arch-and-mode=$(FASTTESTMODES) $(TESTFLAGS) \
	    --quickcheck --variants=turbofan
tc: turbocheck

# Clean targets. You can clean each architecture individually, or everything.
$(addsuffix .clean, $(ARCHES) $(ANDROID_ARCHES) $(NACL_ARCHES)):
	rm -f $(OUTDIR)/Makefile.$(basename $@)*
	rm -rf $(OUTDIR)/$(basename $@).release
	rm -rf $(OUTDIR)/$(basename $@).debug
	rm -rf $(OUTDIR)/$(basename $@).optdebug
	find $(OUTDIR) -regex '.*\(host\|target\)\.$(basename $@).*\.mk' -delete

native.clean:
	rm -f $(OUTDIR)/Makefile.native
	rm -rf $(OUTDIR)/native
	find $(OUTDIR) -regex '.*\(host\|target\)\.native\.mk' -delete

clean: $(addsuffix .clean, $(ARCHES) $(ANDROID_ARCHES) $(NACL_ARCHES)) native.clean gtags.clean

# GYP file generation targets.
OUT_MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(BUILDS))
$(OUT_MAKEFILES): $(GYPFILES) $(ENVFILE)
	$(eval CXX_TARGET_ARCH:=$(shell $(CXX) -v 2>&1 | grep ^Target: | \
	        cut -f 2 -d " " | cut -f 1 -d "-" ))
	$(eval CXX_TARGET_ARCH:=$(subst aarch64,arm64,$(CXX_TARGET_ARCH)))
	$(eval CXX_TARGET_ARCH:=$(subst x86_64,x64,$(CXX_TARGET_ARCH)))
	$(eval V8_TARGET_ARCH:=$(subst .,,$(suffix $(basename $@))))
	PYTHONPATH="$(shell pwd)/tools/generate_shim_headers:$(shell pwd)/build:$(PYTHONPATH):$(shell pwd)/build/gyp/pylib:$(PYTHONPATH)" \
	GYP_GENERATORS=make \
	build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
	              -Ibuild/standalone.gypi --depth=. \
	              -Dv8_target_arch=$(V8_TARGET_ARCH) \
	              $(if $(findstring $(CXX_TARGET_ARCH),$(V8_TARGET_ARCH)), \
	              -Dtarget_arch=$(V8_TARGET_ARCH),) \
	              $(if $(findstring optdebug,$@),-Dv8_optimized_debug=1,) \
	              -S$(suffix $(basename $@))$(suffix $@) $(GYPFLAGS)

$(OUTDIR)/Makefile.native: $(GYPFILES) $(ENVFILE)
	PYTHONPATH="$(shell pwd)/tools/generate_shim_headers:$(shell pwd)/build:$(PYTHONPATH):$(shell pwd)/build/gyp/pylib:$(PYTHONPATH)" \
	GYP_GENERATORS=make \
	build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \
	              -Ibuild/standalone.gypi --depth=. -S.native $(GYPFLAGS)

# Note that NACL_SDK_ROOT must be set to point to an appropriate
# Native Client SDK before using this makefile. You can download
# an SDK here:
#   https://developers.google.com/native-client/sdk/download
# The path indicated by NACL_SDK_ROOT will typically end with
# a folder for a pepper version such as "pepper_25" that should
# have "tools" and "toolchain" subdirectories.
must-set-NACL_SDK_ROOT:
ifndef NACL_SDK_ROOT
	  $(error NACL_SDK_ROOT must be set)
endif

# Replaces the old with the new environment file if they're different, which
# will trigger GYP to regenerate Makefiles.
$(ENVFILE): $(ENVFILE).new
	@if test -r $(ENVFILE) && cmp $(ENVFILE).new $(ENVFILE) > /dev/null; \
	    then rm $(ENVFILE).new; \
	    else mv $(ENVFILE).new $(ENVFILE); fi

# Stores current GYPFLAGS in a file.
$(ENVFILE).new:
	$(eval CXX_TARGET_ARCH:=$(shell $(CXX) -v 2>&1 | grep ^Target: | \
	        cut -f 2 -d " " | cut -f 1 -d "-" ))
	$(eval CXX_TARGET_ARCH:=$(subst aarch64,arm64,$(CXX_TARGET_ARCH)))
	$(eval CXX_TARGET_ARCH:=$(subst x86_64,x64,$(CXX_TARGET_ARCH)))
	@mkdir -p $(OUTDIR); echo "GYPFLAGS=$(GYPFLAGS) -Dtarget_arch=$(CXX_TARGET_ARCH)" > $(ENVFILE).new;

# Heap constants for grokdump.
DUMP_FILE = tools/v8heapconst.py
grokdump: ia32.release
	@cat $(DUMP_FILE).tmpl > $(DUMP_FILE)
	@$(OUTDIR)/ia32.release/d8 --dump-heap-constants >> $(DUMP_FILE)

# Support for the GNU GLOBAL Source Code Tag System.
gtags.files: $(GYPFILES) $(ENVFILE)
	@find include src test -name '*.h' -o -name '*.cc' -o -name '*.c' > $@

# We need to manually set the stack limit here, to work around bugs in
# gmake-3.81 and global-5.7.1 on recent 64-bit Linux systems.
GPATH GRTAGS GSYMS GTAGS: gtags.files $(shell cat gtags.files 2> /dev/null)
	@bash -c 'ulimit -s 10240 && GTAGSFORCECPP=yes gtags -i -q -f $<'

gtags.clean:
	rm -f gtags.files GPATH GRTAGS GSYMS GTAGS

dependencies builddeps:
	$(error Use 'gclient sync' instead)
node-v4.2.6/deps/v8/Makefile.android000644 000766 000024 00000006376 12650222324 017327 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Those definitions should be consistent with the main Makefile
ANDROID_ARCHES = android_ia32 android_x64 android_arm android_arm64 \
		 android_mipsel android_x87
MODES = release debug

# Generates all combinations of ANDROID ARCHES and MODES,
# e.g. "android_ia32.release" or "android_arm.release"
ANDROID_BUILDS = $(foreach mode,$(MODES), \
                   $(addsuffix .$(mode),$(ANDROID_ARCHES)))

ifeq ($(ARCH), android_arm)
  DEFINES  = target_arch=arm v8_target_arch=arm
else ifeq ($(ARCH), android_arm64)
  DEFINES  = target_arch=arm64 v8_target_arch=arm64
else ifeq ($(ARCH), android_mipsel)
  DEFINES  = target_arch=mipsel v8_target_arch=mipsel
else ifeq ($(ARCH), android_ia32)
  DEFINES = target_arch=ia32 v8_target_arch=ia32
else ifeq ($(ARCH), android_x64)
  DEFINES = target_arch=x64 v8_target_arch=x64
else ifeq ($(ARCH), android_x87)
  DEFINES = target_arch=ia32 v8_target_arch=x87
else
  $(error Target architecture "${ARCH}" is not supported)
endif

# Common flags.
DEFINES += OS=android

.SECONDEXPANSION:
$(ANDROID_BUILDS): $(OUTDIR)/Makefile.$$@
	@$(MAKE) -C "$(OUTDIR)" -f Makefile.$@ \
	          BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
	                      python -c "print raw_input().capitalize()") \
	          builddir="$(shell pwd)/$(OUTDIR)/$@"

# Android GYP file generation targets.
ANDROID_MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(ANDROID_BUILDS))
$(ANDROID_MAKEFILES):
	GYP_GENERATORS=make-android \
	GYP_DEFINES="${DEFINES}" \
	PYTHONPATH="$(shell pwd)/tools/generate_shim_headers:$(shell pwd)/build:$(PYTHONPATH)" \
	build/gyp/gyp --generator-output="${OUTDIR}" build/all.gyp \
	              -Ibuild/standalone.gypi --depth=. \
	              -S$(suffix $(basename $@))$(suffix $@) ${GYPFLAGS}
node-v4.2.6/deps/v8/Makefile.nacl000644 000766 000024 00000010237 12650222324 016613 0ustar00iojsstaff000000 000000 #
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Those definitions should be consistent with the main Makefile
NACL_ARCHES = nacl_ia32 nacl_x64
MODES = release debug

# Generates all combinations of NACL ARCHES and MODES,
# e.g. "nacl_ia32.release" or "nacl_x64.release"
NACL_BUILDS = $(foreach mode,$(MODES), \
                   $(addsuffix .$(mode),$(NACL_ARCHES)))

HOST_OS = $(shell uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')
TOOLCHAIN_PATH = $(realpath ${NACL_SDK_ROOT}/toolchain)
NACL_TOOLCHAIN ?= ${TOOLCHAIN_PATH}/linux_pnacl

ifeq ($(wildcard $(NACL_TOOLCHAIN)),)
  $(error Cannot find Native Client toolchain in "${NACL_TOOLCHAIN}")
endif

ifeq ($(ARCH), nacl_ia32)
  GYPENV = nacl_target_arch=nacl_ia32 v8_target_arch=arm v8_host_arch=ia32
  NACL_CC = "$(NACL_TOOLCHAIN)/bin/pnacl-clang"
  NACL_CXX = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++"
  NACL_LINK = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++ --pnacl-allow-native -arch x86-32"
else
  ifeq ($(ARCH), nacl_x64)
    GYPENV = nacl_target_arch=nacl_x64 v8_target_arch=arm v8_host_arch=ia32
    NACL_CC = "$(NACL_TOOLCHAIN)/bin/pnacl-clang"
    NACL_CXX = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++"
    NACL_LINK = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++ --pnacl-allow-native -arch x86-64"
  else
    $(error Target architecture "${ARCH}" is not supported)
  endif
endif

# For mksnapshot host generation.
GYPENV += host_os=${HOST_OS}

# ICU doesn't support NaCl.
GYPENV += v8_enable_i18n_support=0

# Disable strict aliasing - v8 code often relies on undefined behavior of C++.
GYPENV += v8_no_strict_aliasing=1

NACL_MAKEFILES = $(addprefix $(OUTDIR)/Makefile.,$(NACL_BUILDS))
.SECONDEXPANSION:
# For some reason the $$(basename $$@) expansion didn't work here...
$(NACL_BUILDS): $(NACL_MAKEFILES)
	@$(MAKE) -C "$(OUTDIR)" -f Makefile.$@ \
	            CC=${NACL_CC} \
	            CXX=${NACL_CXX} \
	            AR="$(NACL_TOOLCHAIN)/bin/pnacl-ar" \
	            RANLIB="$(NACL_TOOLCHAIN)/bin/pnacl-ranlib" \
	            LD="$(NACL_TOOLCHAIN)/bin/pnacl-ld" \
	            LINK=${NACL_LINK} \
	            BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
	                        python -c "print raw_input().capitalize()") \
	            builddir="$(shell pwd)/$(OUTDIR)/$@"

# NACL GYP file generation targets.
$(NACL_MAKEFILES):
	GYP_GENERATORS=make \
	GYP_DEFINES="${GYPENV}" \
	CC=${NACL_CC} \
	CXX=${NACL_CXX} \
	LINK=${NACL_LINK} \
	PYTHONPATH="$(shell pwd)/tools/generate_shim_headers:$(shell pwd)/build:$(PYTHONPATH)" \
	build/gyp/gyp --generator-output="${OUTDIR}" build/all.gyp \
	              -Ibuild/standalone.gypi --depth=. \
	              -S$(suffix $(basename $@))$(suffix $@) $(GYPFLAGS) \
                      -Dwno_array_bounds=-Wno-array-bounds
node-v4.2.6/deps/v8/OWNERS000644 000766 000024 00000000742 12650222324 015177 0ustar00iojsstaff000000 000000 adamk@chromium.org
arv@chromium.org
bmeurer@chromium.org
danno@chromium.org
dcarney@chromium.org
dslomov@chromium.org
hpayer@chromium.org
ishell@chromium.org
jarin@chromium.org
jkummerow@chromium.org
jochen@chromium.org
machenbach@chromium.org
marja@chromium.org
mstarzinger@chromium.org
mvstanton@chromium.org
rmcilroy@chromium.org
rossberg@chromium.org
svenpanne@chromium.org
titzer@chromium.org
ulan@chromium.org
verwaest@chromium.org
vogelheim@chromium.org
yangguo@chromium.org
node-v4.2.6/deps/v8/PRESUBMIT.py000644 000766 000024 00000024543 12650222324 016170 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Top-level presubmit script for V8.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""

import sys


_EXCLUDED_PATHS = (
    r"^test[\\\/].*",
    r"^testing[\\\/].*",
    r"^third_party[\\\/].*",
    r"^tools[\\\/].*",
)


# Regular expression that matches code only used for test binaries
# (best effort).
_TEST_CODE_EXCLUDED_PATHS = (
    r'.+-unittest\.cc',
    # Has a method VisitForTest().
    r'src[\\\/]compiler[\\\/]ast-graph-builder\.cc',
    # Test extension.
    r'src[\\\/]extensions[\\\/]gc-extension\.cc',
)


_TEST_ONLY_WARNING = (
    'You might be calling functions intended only for testing from\n'
    'production code.  It is OK to ignore this warning if you know what\n'
    'you are doing, as the heuristics used to detect the situation are\n'
    'not perfect.  The commit queue will not block on this warning.')


def _V8PresubmitChecks(input_api, output_api):
  """Runs the V8 presubmit checks."""
  import sys
  sys.path.append(input_api.os_path.join(
        input_api.PresubmitLocalPath(), 'tools'))
  from presubmit import CppLintProcessor
  from presubmit import SourceProcessor
  from presubmit import CheckRuntimeVsNativesNameClashes
  from presubmit import CheckExternalReferenceRegistration
  from presubmit import CheckAuthorizedAuthor

  results = []
  if not CppLintProcessor().Run(input_api.PresubmitLocalPath()):
    results.append(output_api.PresubmitError("C++ lint check failed"))
  if not SourceProcessor().Run(input_api.PresubmitLocalPath()):
    results.append(output_api.PresubmitError(
        "Copyright header, trailing whitespaces and two empty lines " \
        "between declarations check failed"))
  if not CheckRuntimeVsNativesNameClashes(input_api.PresubmitLocalPath()):
    results.append(output_api.PresubmitError(
        "Runtime/natives name clash check failed"))
  if not CheckExternalReferenceRegistration(input_api.PresubmitLocalPath()):
    results.append(output_api.PresubmitError(
        "External references registration check failed"))
  results.extend(CheckAuthorizedAuthor(input_api, output_api))
  return results


def _CheckUnwantedDependencies(input_api, output_api):
  """Runs checkdeps on #include statements added in this
  change. Breaking - rules is an error, breaking ! rules is a
  warning.
  """
  # We need to wait until we have an input_api object and use this
  # roundabout construct to import checkdeps because this file is
  # eval-ed and thus doesn't have __file__.
  original_sys_path = sys.path
  try:
    sys.path = sys.path + [input_api.os_path.join(
        input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
    import checkdeps
    from cpp_checker import CppChecker
    from rules import Rule
  finally:
    # Restore sys.path to what it was before.
    sys.path = original_sys_path

  added_includes = []
  for f in input_api.AffectedFiles():
    if not CppChecker.IsCppFile(f.LocalPath()):
      continue

    changed_lines = [line for line_num, line in f.ChangedContents()]
    added_includes.append([f.LocalPath(), changed_lines])

  deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())

  error_descriptions = []
  warning_descriptions = []
  for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
      added_includes):
    description_with_path = '%s\n    %s' % (path, rule_description)
    if rule_type == Rule.DISALLOW:
      error_descriptions.append(description_with_path)
    else:
      warning_descriptions.append(description_with_path)

  results = []
  if error_descriptions:
    results.append(output_api.PresubmitError(
        'You added one or more #includes that violate checkdeps rules.',
        error_descriptions))
  if warning_descriptions:
    results.append(output_api.PresubmitPromptOrNotify(
        'You added one or more #includes of files that are temporarily\n'
        'allowed but being removed. Can you avoid introducing the\n'
        '#include? See relevant DEPS file(s) for details and contacts.',
        warning_descriptions))
  return results


def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
  """Attempts to prevent use of functions intended only for testing in
  non-testing code. For now this is just a best-effort implementation
  that ignores header files and may have some false positives. A
  better implementation would probably need a proper C++ parser.
  """
  # We only scan .cc files, as the declaration of for-testing functions in
  # header files are hard to distinguish from calls to such functions without a
  # proper C++ parser.
  file_inclusion_pattern = r'.+\.cc'

  base_function_pattern = r'[ :]test::[^\s]+|ForTest(ing)?|for_test(ing)?'
  inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern)
  comment_pattern = input_api.re.compile(r'//.*(%s)' % base_function_pattern)
  exclusion_pattern = input_api.re.compile(
    r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % (
      base_function_pattern, base_function_pattern))

  def FilterFile(affected_file):
    black_list = (_EXCLUDED_PATHS +
                  _TEST_CODE_EXCLUDED_PATHS +
                  input_api.DEFAULT_BLACK_LIST)
    return input_api.FilterSourceFile(
      affected_file,
      white_list=(file_inclusion_pattern, ),
      black_list=black_list)

  problems = []
  for f in input_api.AffectedSourceFiles(FilterFile):
    local_path = f.LocalPath()
    for line_number, line in f.ChangedContents():
      if (inclusion_pattern.search(line) and
          not comment_pattern.search(line) and
          not exclusion_pattern.search(line)):
        problems.append(
          '%s:%d\n    %s' % (local_path, line_number, line.strip()))

  if problems:
    return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
  else:
    return []


def _CommonChecks(input_api, output_api):
  """Checks common to both upload and commit."""
  results = []
  results.extend(input_api.canned_checks.CheckOwners(
      input_api, output_api, source_file_filter=None))
  results.extend(input_api.canned_checks.CheckPatchFormatted(
      input_api, output_api))
  results.extend(_V8PresubmitChecks(input_api, output_api))
  results.extend(_CheckUnwantedDependencies(input_api, output_api))
  results.extend(
      _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
  return results


def _SkipTreeCheck(input_api, output_api):
  """Check the env var whether we want to skip tree check.
     Only skip if include/v8-version.h has been updated."""
  src_version = 'include/v8-version.h'
  FilterFile = lambda file: file.LocalPath() == src_version
  if not input_api.AffectedSourceFiles(
      lambda file: file.LocalPath() == src_version):
    return False
  return input_api.environ.get('PRESUBMIT_TREE_CHECK') == 'skip'


def _CheckChangeLogFlag(input_api, output_api):
  """Checks usage of LOG= flag in the commit message."""
  results = []
  if input_api.change.BUG and not 'LOG' in input_api.change.tags:
    results.append(output_api.PresubmitError(
        'An issue reference (BUG=) requires a change log flag (LOG=). '
        'Use LOG=Y for including this commit message in the change log. '
        'Use LOG=N or leave blank otherwise.'))
  return results


def CheckChangeOnUpload(input_api, output_api):
  results = []
  results.extend(_CommonChecks(input_api, output_api))
  results.extend(_CheckChangeLogFlag(input_api, output_api))
  return results


def CheckChangeOnCommit(input_api, output_api):
  results = []
  results.extend(_CommonChecks(input_api, output_api))
  results.extend(_CheckChangeLogFlag(input_api, output_api))
  results.extend(input_api.canned_checks.CheckChangeHasDescription(
      input_api, output_api))
  if not _SkipTreeCheck(input_api, output_api):
    results.extend(input_api.canned_checks.CheckTreeIsOpen(
        input_api, output_api,
        json_url='http://v8-status.appspot.com/current?format=json'))
  return results


def GetPreferredTryMasters(project, change):
  return {
    'tryserver.v8': {
      'v8_linux_rel': set(['defaulttests']),
      'v8_linux_dbg': set(['defaulttests']),
      'v8_linux_nodcheck_rel': set(['defaulttests']),
      'v8_linux_gcc_compile_rel': set(['defaulttests']),
      'v8_linux64_rel': set(['defaulttests']),
      'v8_linux64_asan_rel': set(['defaulttests']),
      'v8_linux64_avx2_rel': set(['defaulttests']),
      'v8_win_rel': set(['defaulttests']),
      'v8_win_compile_dbg': set(['defaulttests']),
      'v8_win_nosnap_shared_compile_rel': set(['defaulttests']),
      'v8_win64_rel': set(['defaulttests']),
      'v8_mac_rel': set(['defaulttests']),
      'v8_linux_arm_rel': set(['defaulttests']),
      'v8_linux_arm64_rel': set(['defaulttests']),
      'v8_linux_mipsel_compile_rel': set(['defaulttests']),
      'v8_linux_mips64el_compile_rel': set(['defaulttests']),
      'v8_android_arm_compile_rel': set(['defaulttests']),
      'v8_linux_chromium_gn_rel': set(['defaulttests']),
    },
  }
node-v4.2.6/deps/v8/README.md000644 000766 000024 00000001512 12650222324 015512 0ustar00iojsstaff000000 000000 V8 JavaScript Engine
=============

V8 is Google's open source JavaScript engine.

V8 implements ECMAScript as specified in ECMA-262.

V8 is written in C++ and is used in Google Chrome, the open source
browser from Google.

V8 can run standalone, or can be embedded into any C++ application.

V8 Project page: https://code.google.com/p/v8/


Getting the Code
=============

Checkout [depot tools](http://www.chromium.org/developers/how-tos/install-depot-tools), and run

        fetch v8

This will checkout V8 into the directory `v8` and fetch all of its dependencies.
To stay up to date, run

        git pull origin
        gclient sync

For fetching all branches, add the following into your remote
configuration in `.git/config`:

        fetch = +refs/branch-heads/*:refs/remotes/branch-heads/*
        fetch = +refs/tags/*:refs/tags/*
node-v4.2.6/deps/v8/src/000755 000766 000024 00000000000 12650222324 015023 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/testing/000755 000766 000024 00000000000 12650222326 015713 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/000755 000766 000024 00000000000 12650222331 015372 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/WATCHLISTS000644 000766 000024 00000004326 12650222324 015651 0ustar00iojsstaff000000 000000 # Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Watchlist Rules
# Refer: http://dev.chromium.org/developers/contributing-code/watchlists

# IMPORTANT: The regular expression filepath is tested against each path using
# re.search, so it is not usually necessary to add .*.

{
  'WATCHLIST_DEFINITIONS': {
    'public_api': {
      'filepath': 'include/',
    },
    'snapshot': {
      'filepath': 'src/snapshot/',
    },
    'debugger': {
      'filepath': 'src/debug\.(cc|h)|src/.*-debugger\.js|src/runtime/runtime-debug\.cc',
    },
  },

  'WATCHLISTS': {
    'public_api': [
      'phajdan.jr@chromium.org',
    ],
    'snapshot': [
      'yangguo@chromium.org',
    ],
    'debugger': [
      'yangguo@chromium.org',
    ],
  },
}
node-v4.2.6/deps/v8/tools/android-build.sh000755 000766 000024 00000000000 12650222326 020440 0ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/android-ll-prof.sh000755 000766 000024 00000005663 12650222326 020740 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Runs d8 with the given arguments on the device under 'perf' and
# processes the profiler trace and v8 logs using ll_prof.py.
# 
# Usage:
# > ./tools/android-ll-prof.sh (debug|release) "args to d8" "args to ll_prof.py"
#
# The script creates deploy directory deploy/data/local/tmp/v8, copies there
# the d8 binary either from out/android_arm.release or out/android_arm.debug,
# and then sync the deploy directory with /data/local/tmp/v8 on the device.
# You can put JS files in the deploy directory before running the script.
# Note: $ANDROID_NDK_ROOT must be set.

MODE=$1
RUN_ARGS=$2
LL_PROF_ARGS=$3

BASE=`cd $(dirname "$0")/..; pwd`
DEPLOY="$BASE/deploy"

set +e
mkdir -p "$DEPLOY/data/local/tmp/v8"

cp "$BASE/out/android_arm.$MODE/d8" "$DEPLOY/data/local/tmp/v8/d8"

adb -p "$DEPLOY" sync data

adb shell "cd /data/local/tmp/v8;\
           perf record -R -e cycles -c 10000 -f -i \
           ./d8 --ll_prof --gc-fake-mmap=/data/local/tmp/__v8_gc__ $RUN_ARGS"

adb pull /data/local/tmp/v8/v8.log .
adb pull /data/local/tmp/v8/v8.log.ll .
adb pull /data/perf.data .

ARCH=arm-linux-androideabi-4.6
TOOLCHAIN="${ANDROID_NDK_ROOT}/toolchains/$ARCH/prebuilt/linux-x86/bin"

$BASE/tools/ll_prof.py --host-root="$BASE/deploy" \
                       --gc-fake-mmap=/data/local/tmp/__v8_gc__ \
                       --objdump="$TOOLCHAIN/arm-linux-androideabi-objdump" \
                       $LL_PROF_ARGS
node-v4.2.6/deps/v8/tools/android-run.py000755 000766 000024 00000010073 12650222326 020176 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
#
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This script executes the passed command line on Android device
# using 'adb shell' command. Unfortunately, 'adb shell' always
# returns exit code 0, ignoring the exit code of executed command.
# Since we need to return non-zero exit code if the command failed,
# we augment the passed command line with exit code checking statement
# and output special error string in case of non-zero exit code.
# Then we parse the output of 'adb shell' and look for that error string.

import os
from os.path import join, dirname, abspath
import subprocess
import sys
import tempfile

def Check(output, errors):
  failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID')
                for s in output.split('\n')])
  return 1 if failed else 0

def Execute(cmdline):
  (fd_out, outname) = tempfile.mkstemp()
  (fd_err, errname) = tempfile.mkstemp()
  process = subprocess.Popen(
    args=cmdline,
    shell=True,
    stdout=fd_out,
    stderr=fd_err,
  )
  exit_code = process.wait()
  os.close(fd_out)
  os.close(fd_err)
  output = file(outname).read()
  errors = file(errname).read()
  os.unlink(outname)
  os.unlink(errname)
  sys.stdout.write(output)
  sys.stderr.write(errors)
  return exit_code or Check(output, errors)

def Escape(arg):
  def ShouldEscape():
    for x in arg:
      if not x.isalnum() and x != '-' and x != '_':
        return True
    return False

  return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"'))

def WriteToTemporaryFile(data):
  (fd, fname) = tempfile.mkstemp()
  os.close(fd)
  tmp_file = open(fname, "w")
  tmp_file.write(data)
  tmp_file.close()
  return fname

def Main():
  if (len(sys.argv) == 1):
    print("Usage: %s " % sys.argv[0])
    return 1
  workspace = abspath(join(dirname(sys.argv[0]), '..'))
  android_workspace = os.getenv("ANDROID_V8", "/data/local/tmp/v8")
  args = [Escape(arg) for arg in sys.argv[1:]]
  script = (" ".join(args) + "\n"
            "case $? in\n"
            "  0) ;;\n"
            "  *) echo \"ANDROID: Error returned by test\";;\n"
            "esac\n")
  script = script.replace(workspace, android_workspace)
  script_file = WriteToTemporaryFile(script)
  android_script_file = android_workspace + "/" + script_file
  command =  ("adb push '%s' %s;" % (script_file, android_script_file) +
              "adb shell 'sh %s';" % android_script_file +
              "adb shell 'rm %s'" % android_script_file)
  error_code = Execute(command)
  os.unlink(script_file)
  return error_code

if __name__ == '__main__':
  sys.exit(Main())
node-v4.2.6/deps/v8/tools/android-sync.sh000755 000766 000024 00000006706 12650222326 020340 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This script pushes android binaries and test data to the device.
# The first argument can be either "android.release" or "android.debug".
# The second argument is a relative path to the output directory with binaries.
# The third argument is the absolute path to the V8 directory on the host.
# The fourth argument is the absolute path to the V8 directory on the device.

if [ ${#@} -lt 4 ] ; then
  echo "$0: Error: need 4 arguments"
  exit 1
fi

ARCH_MODE=$1
OUTDIR=$2
HOST_V8=$3
ANDROID_V8=$4

function LINUX_MD5 {
  local HASH=$(md5sum $1)
  echo ${HASH%% *}
}

function DARWIN_MD5 {
  local HASH=$(md5 $1)
  echo ${HASH} | cut -f2 -d "=" | cut -f2 -d " "
}

host_os=$(uname -s)
case "${host_os}" in
  "Linux")
    MD5=LINUX_MD5
    ;;
  "Darwin")
    MD5=DARWIN_MD5
    ;;
  *)
    echo "$0: Host platform ${host_os} is not supported" >& 2
    exit 1
esac

function sync_file {
  local FILE=$1
  local ANDROID_HASH=$(adb shell "md5 \"$ANDROID_V8/$FILE\"")
  local HOST_HASH=$($MD5 "$HOST_V8/$FILE")
  if [ "${ANDROID_HASH%% *}" != "${HOST_HASH}" ]; then
    adb push "$HOST_V8/$FILE" "$ANDROID_V8/$FILE" &> /dev/null
  fi
  echo -n "."
}

function sync_dir {
  local DIR=$1
  echo -n "sync to $ANDROID_V8/$DIR"
  for FILE in $(find "$HOST_V8/$DIR" -not -path "*.svn*" -type f); do
    local RELATIVE_FILE=${FILE:${#HOST_V8}}
    sync_file "$RELATIVE_FILE"
  done
  echo ""
}

echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
sync_file "$OUTDIR/$ARCH_MODE/cctest"
sync_file "$OUTDIR/$ARCH_MODE/d8"
sync_file "$OUTDIR/$ARCH_MODE/unittests"
echo ""
echo -n "sync to $ANDROID_V8/tools"
sync_file tools/consarray.js
sync_file tools/codemap.js
sync_file tools/csvparser.js
sync_file tools/profile.js
sync_file tools/splaytree.js
sync_file tools/profile_view.js
sync_file tools/logreader.js
sync_file tools/tickprocessor.js
echo ""
sync_dir tools/profviz
sync_dir test/intl
sync_dir test/message
sync_dir test/mjsunit
sync_dir test/preparser
node-v4.2.6/deps/v8/tools/bash-completion.sh000755 000766 000024 00000004536 12650222326 021031 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Inspired by and based on:
# http://src.chromium.org/viewvc/chrome/trunk/src/tools/bash-completion

# Flag completion rule for bash.
# To load in your shell, "source path/to/this/file".

v8_source=$(readlink -f $(dirname $BASH_SOURCE)/..)

_v8_flag() {
  local cur defines targets
  cur="${COMP_WORDS[COMP_CWORD]}"
  defines=$(cat $v8_source/src/flag-definitions.h \
    | grep "^DEFINE" \
    | grep -v "DEFINE_implication" \
    | sed -e 's/_/-/g')
  targets=$(echo "$defines" \
    | sed -ne 's/^DEFINE-[^(]*(\([^,]*\).*/--\1/p'; \
    echo "$defines" \
    | sed -ne 's/^DEFINE-bool(\([^,]*\).*/--no\1/p'; \
    cat $v8_source/src/d8.cc \
    | grep "strcmp(argv\[i\]" \
    | sed -ne 's/^[^"]*"--\([^"]*\)".*/--\1/p')
  COMPREPLY=($(compgen -W "$targets" -- "$cur"))
  return 0
}

complete -F _v8_flag -f d8
node-v4.2.6/deps/v8/tools/blink_tests/000755 000766 000024 00000000000 12650222326 017717 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/check-name-clashes.py000755 000766 000024 00000005532 12650222326 021373 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import js2c
import os
import re
import sys

FILENAME = "src/runtime/runtime.h"
LISTHEAD = re.compile(r"#define\s+(FOR_EACH_\w+)\((\w+)\)")
LISTBODY = re.compile(r".*\\$")


class Function(object):
  def __init__(self, match):
    self.name = match.group(1).strip()

def ListMacroRe(list):
  macro = LISTHEAD.match(list[0]).group(2)
  re_string = "\s*%s\((\w+)" % macro
  return re.compile(re_string)


def FindLists(filename):
  lists = []
  current_list = []
  mode = "SEARCHING"
  with open(filename, "r") as f:
    for line in f:
      if mode == "SEARCHING":
        match = LISTHEAD.match(line)
        if match:
          mode = "APPENDING"
          current_list.append(line)
      else:
        current_list.append(line)
        match = LISTBODY.match(line)
        if not match:
          mode = "SEARCHING"
          lists.append(current_list)
          current_list = []
  return lists


# Detects runtime functions by parsing FILENAME.
def FindRuntimeFunctions():
  functions = []
  lists = FindLists(FILENAME)
  for list in lists:
    function_re = ListMacroRe(list)
    for line in list:
      match = function_re.match(line)
      if match:
        functions.append(Function(match))
  return functions


class Builtin(object):
  def __init__(self, match):
    self.name = match.group(1)


def FindJSNatives():
  PATH = "src"
  fileslist = []
  for (root, dirs, files) in os.walk(PATH):
    for f in files:
      if f.endswith(".js"):
        fileslist.append(os.path.join(root, f))
  natives = []
  regexp = re.compile("^function (\w+)\s*\((.*?)\) {")
  matches = 0
  for filename in fileslist:
    with open(filename, "r") as f:
      file_contents = f.read()
    file_contents = js2c.ExpandInlineMacros(file_contents)
    lines = file_contents.split("\n")
    partial_line = ""
    for line in lines:
      if line.startswith("function") and not '{' in line:
        partial_line += line.rstrip()
        continue
      if partial_line:
        partial_line += " " + line.strip()
        if '{' in line:
          line = partial_line
          partial_line = ""
        else:
          continue
      match = regexp.match(line)
      if match:
        natives.append(Builtin(match))
  return natives


def Main():
  functions = FindRuntimeFunctions()
  natives = FindJSNatives()
  errors = 0
  runtime_map = {}
  for f in functions:
    runtime_map[f.name] = 1
  for b in natives:
    if b.name in runtime_map:
      print("JS_Native/Runtime_Function name clash: %s" % b.name)
      errors += 1

  if errors > 0:
    return 1
  print("Runtime/Natives name clashes: checked %d/%d functions, all good." %
        (len(functions), len(natives)))
  return 0


if __name__ == "__main__":
  sys.exit(Main())
node-v4.2.6/deps/v8/tools/check-static-initializers.sh000755 000766 000024 00000004551 12650222326 023010 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Checks that the number of compilation units having at least one static
# initializer in d8 matches the one defined below.

# Allow:
#  - _GLOBAL__I__ZN2v810LineEditor6first_E
#  - _GLOBAL__I__ZN2v88internal32AtomicOps_Internalx86CPUFeaturesE
expected_static_init_count=2

v8_root=$(readlink -f $(dirname $BASH_SOURCE)/../)

if [ -n "$1" ] ; then
  d8="${v8_root}/$1"
else
  d8="${v8_root}/d8"
fi

if [ ! -f "$d8" ]; then
  echo "d8 binary not found: $d8"
  exit 1
fi

static_inits=$(nm "$d8" | grep _GLOBAL_ | grep _I_ | awk '{ print $NF; }')

static_init_count=$(echo "$static_inits" | wc -l)

if [ $static_init_count -gt $expected_static_init_count ]; then
  echo "Too many static initializers."
  echo "$static_inits"
  exit 1
else
  echo "Static initializer check passed ($static_init_count initializers)."
  exit 0
fi
node-v4.2.6/deps/v8/tools/codemap.js000644 000766 000024 00000017463 12650222326 017357 0ustar00iojsstaff000000 000000 // Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


/**
 * Constructs a mapper that maps addresses into code entries.
 *
 * @constructor
 */
function CodeMap() {
  /**
   * Dynamic code entries. Used for JIT compiled code.
   */
  this.dynamics_ = new SplayTree();

  /**
   * Name generator for entries having duplicate names.
   */
  this.dynamicsNameGen_ = new CodeMap.NameGenerator();

  /**
   * Static code entries. Used for statically compiled code.
   */
  this.statics_ = new SplayTree();

  /**
   * Libraries entries. Used for the whole static code libraries.
   */
  this.libraries_ = new SplayTree();

  /**
   * Map of memory pages occupied with static code.
   */
  this.pages_ = [];
};


/**
 * The number of alignment bits in a page address.
 */
CodeMap.PAGE_ALIGNMENT = 12;


/**
 * Page size in bytes.
 */
CodeMap.PAGE_SIZE =
    1 << CodeMap.PAGE_ALIGNMENT;


/**
 * Adds a dynamic (i.e. moveable and discardable) code entry.
 *
 * @param {number} start The starting address.
 * @param {CodeMap.CodeEntry} codeEntry Code entry object.
 */
CodeMap.prototype.addCode = function(start, codeEntry) {
  this.deleteAllCoveredNodes_(this.dynamics_, start, start + codeEntry.size);
  this.dynamics_.insert(start, codeEntry);
};


/**
 * Moves a dynamic code entry. Throws an exception if there is no dynamic
 * code entry with the specified starting address.
 *
 * @param {number} from The starting address of the entry being moved.
 * @param {number} to The destination address.
 */
CodeMap.prototype.moveCode = function(from, to) {
  var removedNode = this.dynamics_.remove(from);
  this.deleteAllCoveredNodes_(this.dynamics_, to, to + removedNode.value.size);
  this.dynamics_.insert(to, removedNode.value);
};


/**
 * Discards a dynamic code entry. Throws an exception if there is no dynamic
 * code entry with the specified starting address.
 *
 * @param {number} start The starting address of the entry being deleted.
 */
CodeMap.prototype.deleteCode = function(start) {
  var removedNode = this.dynamics_.remove(start);
};


/**
 * Adds a library entry.
 *
 * @param {number} start The starting address.
 * @param {CodeMap.CodeEntry} codeEntry Code entry object.
 */
CodeMap.prototype.addLibrary = function(
    start, codeEntry) {
  this.markPages_(start, start + codeEntry.size);
  this.libraries_.insert(start, codeEntry);
};


/**
 * Adds a static code entry.
 *
 * @param {number} start The starting address.
 * @param {CodeMap.CodeEntry} codeEntry Code entry object.
 */
CodeMap.prototype.addStaticCode = function(
    start, codeEntry) {
  this.statics_.insert(start, codeEntry);
};


/**
 * @private
 */
CodeMap.prototype.markPages_ = function(start, end) {
  for (var addr = start; addr <= end;
       addr += CodeMap.PAGE_SIZE) {
    this.pages_[addr >>> CodeMap.PAGE_ALIGNMENT] = 1;
  }
};


/**
 * @private
 */
CodeMap.prototype.deleteAllCoveredNodes_ = function(tree, start, end) {
  var to_delete = [];
  var addr = end - 1;
  while (addr >= start) {
    var node = tree.findGreatestLessThan(addr);
    if (!node) break;
    var start2 = node.key, end2 = start2 + node.value.size;
    if (start2 < end && start < end2) to_delete.push(start2);
    addr = start2 - 1;
  }
  for (var i = 0, l = to_delete.length; i < l; ++i) tree.remove(to_delete[i]);
};


/**
 * @private
 */
CodeMap.prototype.isAddressBelongsTo_ = function(addr, node) {
  return addr >= node.key && addr < (node.key + node.value.size);
};


/**
 * @private
 */
CodeMap.prototype.findInTree_ = function(tree, addr) {
  var node = tree.findGreatestLessThan(addr);
  return node && this.isAddressBelongsTo_(addr, node) ? node.value : null;
};


/**
 * Finds a code entry that contains the specified address. Both static and
 * dynamic code entries are considered.
 *
 * @param {number} addr Address.
 */
CodeMap.prototype.findEntry = function(addr) {
  var pageAddr = addr >>> CodeMap.PAGE_ALIGNMENT;
  if (pageAddr in this.pages_) {
    // Static code entries can contain "holes" of unnamed code.
    // In this case, the whole library is assigned to this address.
    return this.findInTree_(this.statics_, addr) ||
        this.findInTree_(this.libraries_, addr);
  }
  var min = this.dynamics_.findMin();
  var max = this.dynamics_.findMax();
  if (max != null && addr < (max.key + max.value.size) && addr >= min.key) {
    var dynaEntry = this.findInTree_(this.dynamics_, addr);
    if (dynaEntry == null) return null;
    // Dedupe entry name.
    if (!dynaEntry.nameUpdated_) {
      dynaEntry.name = this.dynamicsNameGen_.getName(dynaEntry.name);
      dynaEntry.nameUpdated_ = true;
    }
    return dynaEntry;
  }
  return null;
};


/**
 * Returns a dynamic code entry using its starting address.
 *
 * @param {number} addr Address.
 */
CodeMap.prototype.findDynamicEntryByStartAddress =
    function(addr) {
  var node = this.dynamics_.find(addr);
  return node ? node.value : null;
};


/**
 * Returns an array of all dynamic code entries.
 */
CodeMap.prototype.getAllDynamicEntries = function() {
  return this.dynamics_.exportValues();
};


/**
 * Returns an array of pairs of all dynamic code entries and their addresses.
 */
CodeMap.prototype.getAllDynamicEntriesWithAddresses = function() {
  return this.dynamics_.exportKeysAndValues();
};


/**
 * Returns an array of all static code entries.
 */
CodeMap.prototype.getAllStaticEntries = function() {
  return this.statics_.exportValues();
};


/**
 * Returns an array of all libraries entries.
 */
CodeMap.prototype.getAllLibrariesEntries = function() {
  return this.libraries_.exportValues();
};


/**
 * Creates a code entry object.
 *
 * @param {number} size Code entry size in bytes.
 * @param {string} opt_name Code entry name.
 * @param {string} opt_type Code entry type, e.g. SHARED_LIB, CPP.
 * @constructor
 */
CodeMap.CodeEntry = function(size, opt_name, opt_type) {
  this.size = size;
  this.name = opt_name || '';
  this.type = opt_type || '';
  this.nameUpdated_ = false;
};


CodeMap.CodeEntry.prototype.getName = function() {
  return this.name;
};


CodeMap.CodeEntry.prototype.toString = function() {
  return this.name + ': ' + this.size.toString(16);
};


CodeMap.NameGenerator = function() {
  this.knownNames_ = {};
};


CodeMap.NameGenerator.prototype.getName = function(name) {
  if (!(name in this.knownNames_)) {
    this.knownNames_[name] = 0;
    return name;
  }
  var count = ++this.knownNames_[name];
  return name + ' {' + count + '}';
};
node-v4.2.6/deps/v8/tools/compare-table-gen.js000644 000766 000024 00000007053 12650222326 021223 0ustar00iojsstaff000000 000000 // Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Generates a comparison table test case.
// Usage: d8 compare-table-gen.js -- lt|lteq|gt|gteq|eq|ne|eq|sne|min|max

var strings = ["true", "false", "null", "void 0", "0", "0.0", "-0", "\"\"", "-1", "-1.25", "1", "1.25", "-2147483648", "2147483648", "Infinity", "-Infinity", "NaN"];
var values = new Array(strings.length);
for (var i = 0; i < strings.length; i++) {
  values[i] = eval(strings[i]);
}

function test() {
  for (var i = 0; i < values.length; i++) {
    for (var j = 0; j < values.length; j++) {
      var a = values[i];
      var b = values[j];
      var x = expected[i][j];
      assertEquals(x, func(a,b));
      assertEquals(x, left_funcs[i](b));
      assertEquals(x, right_funcs[j](a));
    }
  }

  var result = matrix();
  for (var i = 0; i < values.length; i++) {
    for (var j = 0; j < values.length; j++) {
      assertEquals(expected[i][j], result[i][j]);
    }
  }
}

function expr(infix, a, cmp, b) {
  return infix ? a + " " + cmp + " " + b : cmp + "(" + a + ", " + b + ")";
}

function SpecialToString(x) {
  if ((1 / x) == -Infinity) return "-0";
  return "" + x;
}

function gen(name, cmp, infix) {

  print("// Copyright 2015 the V8 project authors. All rights reserved.");
  print("// Use of this source code is governed by a BSD-style license that can be");
  print("// found in the LICENSE file.");
  print();
  print("var values = [" + strings + "];");

  var body = "(function " + name + "(a,b) { return " + expr(infix, "a", cmp, "b") + "; })";
  var func = eval(body);

  print("var expected = [");

  for (var i = 0; i < values.length; i++) {
    var line = "  [";
    for (var j = 0; j < values.length; j++) {
      if (j > 0) line += ",";
      line += SpecialToString(func(values[i], values[j]));
    }
    line += "]";
    if (i < (values.length - 1)) line += ",";
    print(line);
  }
  print("];");

  print("var func = " + body + ";");
  print("var left_funcs = [");

  for (var i = 0; i < values.length; i++) {
    var value = strings[i];
    var body = "(function " + name + "_L" + i + "(b) { return " + expr(infix, value, cmp, "b") + "; })";
    var end = i < (values.length - 1) ? "," : "";
    print("  " + body + end);
  }
  print("];");

  print("var right_funcs = [");
  for (var i = 0; i < values.length; i++) {
    var value = strings[i];
    var body = "(function " + name + "_R" + i + "(a) { return " + expr(infix, "a", cmp, value) + "; })";
    var end = i < (values.length - 1) ? "," : "";
    print("  " + body + end);
  }
  print("];");

  print("function matrix() {");
  print("  return [");
  for (var i = 0; i < values.length; i++) {
    var line = "    [";
    for (var j = 0; j < values.length; j++) {
      if (j > 0) line += ",";
      line += expr(infix, strings[i], cmp, strings[j]);
    }
    line += "]";
    if (i < (values.length - 1)) line += ",";
    print(line);
  }
  print("  ];");
  print("}");


  print(test.toString());
  print("test();");
  print("test();");
}

switch (arguments[0]) {
  case "lt":   gen("lt",   "<", true); break;
  case "lteq": gen("lteq", "<=", true); break;
  case "gt":   gen("gt",   ">", true); break;
  case "gteq": gen("gteq", ">=", true); break;
  case "eq":   gen("eq",   "==", true); break;
  case "ne":   gen("ne",   "!=", true); break;
  case "seq":  gen("seq",  "===", true); break;
  case "sne":  gen("sne",  "!==", true); break;
  case "min":  gen("min",  "Math.min", false); break;
  case "max":  gen("max",  "Math.max", false); break;
}
node-v4.2.6/deps/v8/tools/concatenate-files.py000644 000766 000024 00000005516 12650222326 021343 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
#
# Copyright 2014 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This utility concatenates several files into one. On Unix-like systems
# it is equivalent to:
#   cat file1 file2 file3 ...files... > target
#
# The reason for writing a seperate utility is that 'cat' is not available
# on all supported build platforms, but Python is, and hence this provides
# us with an easy and uniform way of doing this on all platforms.

import optparse


def Concatenate(filenames):
  """Concatenate files.

  Args:
    files: Array of file names.
           The last name is the target; all earlier ones are sources.

  Returns:
    True, if the operation was successful.
  """
  if len(filenames) < 2:
    print "An error occured generating %s:\nNothing to do." % filenames[-1]
    return False

  try:
    with open(filenames[-1], "wb") as target:
      for filename in filenames[:-1]:
        with open(filename, "rb") as current:
          target.write(current.read())
    return True
  except IOError as e:
    print "An error occured when writing %s:\n%s" % (filenames[-1], e)
    return False


def main():
  parser = optparse.OptionParser()
  parser.set_usage("""Concatenate several files into one.
      Equivalent to: cat file1 ... > target.""")
  (options, args) = parser.parse_args()
  exit(0 if Concatenate(args) else 1)


if __name__ == "__main__":
  main()
node-v4.2.6/deps/v8/tools/consarray.js000644 000766 000024 00000006227 12650222326 017744 0ustar00iojsstaff000000 000000 // Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


/**
 * Constructs a ConsArray object. It is used mainly for tree traversal.
 * In this use case we have lots of arrays that we need to iterate
 * sequentally. The internal Array implementation is horribly slow
 * when concatenating on large (10K items) arrays due to memory copying.
 * That's why we avoid copying memory and insead build a linked list
 * of arrays to iterate through.
 *
 * @constructor
 */
function ConsArray() {
  this.tail_ = new ConsArray.Cell(null, null);
  this.currCell_ = this.tail_;
  this.currCellPos_ = 0;
};


/**
 * Concatenates another array for iterating. Empty arrays are ignored.
 * This operation can be safely performed during ongoing ConsArray
 * iteration.
 *
 * @param {Array} arr Array to concatenate.
 */
ConsArray.prototype.concat = function(arr) {
  if (arr.length > 0) {
    this.tail_.data = arr;
    this.tail_ = this.tail_.next = new ConsArray.Cell(null, null);
  }
};


/**
 * Whether the end of iteration is reached.
 */
ConsArray.prototype.atEnd = function() {
  return this.currCell_ === null ||
      this.currCell_.data === null ||
      this.currCellPos_ >= this.currCell_.data.length;
};


/**
 * Returns the current item, moves to the next one.
 */
ConsArray.prototype.next = function() {
  var result = this.currCell_.data[this.currCellPos_++];
  if (this.currCellPos_ >= this.currCell_.data.length) {
    this.currCell_ = this.currCell_.next;
    this.currCellPos_ = 0;
  }
  return result;
};


/**
 * A cell object used for constructing a list in ConsArray.
 *
 * @constructor
 */
ConsArray.Cell = function(data, next) {
  this.data = data;
  this.next = next;
};
node-v4.2.6/deps/v8/tools/cpu.sh000755 000766 000024 00000002325 12650222326 016526 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

CPUPATH=/sys/devices/system/cpu

MAXID=$(cat $CPUPATH/present | awk -F- '{print $NF}')

set_governor() {
  echo "Setting CPU frequency governor to \"$1\""
  for (( i=0; i<=$MAXID; i++ )); do
    echo "$1" > $CPUPATH/cpu$i/cpufreq/scaling_governor
  done
}

dual_core() {
  echo "Switching to dual-core mode"
  for (( i=2; i<=$MAXID; i++ )); do
    echo 0 > $CPUPATH/cpu$i/online
  done
}

single_core() {
  echo "Switching to single-core mode"
  for (( i=1; i<=$MAXID; i++ )); do
    echo 0 > $CPUPATH/cpu$i/online
  done
}


all_cores() {
  echo "Reactivating all CPU cores"
  for (( i=1; i<=$MAXID; i++ )); do
    echo 1 > $CPUPATH/cpu$i/online
  done
}

case "$1" in
  fast | performance)
    set_governor "performance"
    ;;
  slow | powersave)
    set_governor "powersave"
    ;;
  default | ondemand)
    set_governor "ondemand"
    ;;
  dualcore | dual)
    dual_core
    ;;
  singlecore | single)
    single_core
    ;;
  allcores | all)
    all_cores
    ;;
  *)
    echo "Usage: $0 fast|slow|default|singlecore|dualcore|all"
    exit 1
    ;;
esac 
node-v4.2.6/deps/v8/tools/cross_build_gcc.sh000755 000766 000024 00000004576 12650222326 021075 0ustar00iojsstaff000000 000000 #!/bin/sh
#
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

if [ "$#" -lt 1 ]; then
  echo "Usage: tools/cross_build_gcc.sh  [make arguments ...]"
  exit 1
fi

export CXX=$1g++
export AR=$1ar
export RANLIB=$1ranlib
export CC=$1gcc
export LD=$1g++
export LINK=$1g++

OK=1
if [ ! -x "$CXX" ]; then
  echo "Error: $CXX does not exist or is not executable."
  OK=0
fi
if [ ! -x "$AR" ]; then
  echo "Error: $AR does not exist or is not executable."
  OK=0
fi
if [ ! -x "$RANLIB" ]; then
  echo "Error: $RANLIB does not exist or is not executable."
  OK=0
fi
if [ ! -x "$CC" ]; then
  echo "Error: $CC does not exist or is not executable."
  OK=0
fi
if [ ! -x "$LD" ]; then
  echo "Error: $LD does not exist or is not executable."
  OK=0
fi
if [ ! -x "$LINK" ]; then
  echo "Error: $LINK does not exist or is not executable."
  OK=0
fi
if [ $OK -ne 1 ]; then
  exit 1
fi

shift
make snapshot=off $@
node-v4.2.6/deps/v8/tools/csvparser.js000644 000766 000024 00000005347 12650222326 017755 0ustar00iojsstaff000000 000000 // Copyright 2009 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


/**
 * Creates a CSV lines parser.
 */
function CsvParser() {
};


/**
 * A regex for matching a CSV field.
 * @private
 */
CsvParser.CSV_FIELD_RE_ = /^"((?:[^"]|"")*)"|([^,]*)/;


/**
 * A regex for matching a double quote.
 * @private
 */
CsvParser.DOUBLE_QUOTE_RE_ = /""/g;


/**
 * Parses a line of CSV-encoded values. Returns an array of fields.
 *
 * @param {string} line Input line.
 */
CsvParser.prototype.parseLine = function(line) {
  var fieldRe = CsvParser.CSV_FIELD_RE_;
  var doubleQuoteRe = CsvParser.DOUBLE_QUOTE_RE_;
  var pos = 0;
  var endPos = line.length;
  var fields = [];
  if (endPos > 0) {
    do {
      var fieldMatch = fieldRe.exec(line.substr(pos));
      if (typeof fieldMatch[1] === "string") {
        var field = fieldMatch[1];
        pos += field.length + 3;  // Skip comma and quotes.
        fields.push(field.replace(doubleQuoteRe, '"'));
      } else {
        // The second field pattern will match anything, thus
        // in the worst case the match will be an empty string.
        var field = fieldMatch[2];
        pos += field.length + 1;  // Skip comma.
        fields.push(field);
      }
    } while (pos <= endPos);
  }
  return fields;
};
node-v4.2.6/deps/v8/tools/DEPS000644 000766 000024 00000000207 12650222326 016053 0ustar00iojsstaff000000 000000 include_rules = [
  "+src",
]

# checkdeps.py shouldn't check for includes in these directories:
skip_child_includes = [
  "gcmole",
]
node-v4.2.6/deps/v8/tools/detect-builtins.js000644 000766 000024 00000003026 12650222326 021034 0ustar00iojsstaff000000 000000 // Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

(function(global) {

  var GetProperties = function(this_name, object) {
    var result = {};
    try {
      var names = Object.getOwnPropertyNames(object);
    } catch(e) {
      return;
    }
    for (var i = 0; i < names.length; ++i) {
      var name = names[i];
      if (typeof object === "function") {
        if (name === "length" ||
            name === "name" ||
            name === "arguments" ||
            name === "caller" ||
            name === "prototype") {
          continue;
        }
      }
      // Avoid endless recursion.
      if (this_name === "prototype" && name === "constructor") continue;
      // Could get this from the parent, but having it locally is easier.
      var property = { "name": name };
      try {
        var value = object[name];
      } catch(e) {
        property.type = "getter";
        result[name] = property;
        continue;
      }
      var type = typeof value;
      property.type = type;
      if (type === "function") {
        property.length = value.length;
        property.prototype = GetProperties("prototype", value.prototype);
      }
      property.properties = GetProperties(name, value);
      result[name] = property;
    }
    return result;
  };

  var g = GetProperties("", global, "");
  print(JSON.stringify(g, undefined, 2));

})(this);  // Must wrap in anonymous closure or it'll detect itself as builtin.
node-v4.2.6/deps/v8/tools/disasm.py000644 000766 000024 00000007102 12650222326 017230 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
#
# Copyright 2011 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import os
import re
import subprocess
import tempfile


# Avoid using the slow (google-specific) wrapper around objdump.
OBJDUMP_BIN = "/usr/bin/objdump"
if not os.path.exists(OBJDUMP_BIN):
  OBJDUMP_BIN = "objdump"


_COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C"]

_DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$")
_DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):\s*(\S.*)")

# Keys must match constants in Logger::LogCodeInfo.
_ARCH_MAP = {
  "ia32": "-m i386",
  "x64": "-m i386 -M x86-64",
  "arm": "-m arm",  # Not supported by our objdump build.
  "mips": "-m mips",  # Not supported by our objdump build.
  "arm64": "-m aarch64"
}


def GetDisasmLines(filename, offset, size, arch, inplace, arch_flags=""):
  tmp_name = None
  if not inplace:
    # Create a temporary file containing a copy of the code.
    assert arch in _ARCH_MAP, "Unsupported architecture '%s'" % arch
    arch_flags = arch_flags + " " +  _ARCH_MAP[arch]
    tmp_name = tempfile.mktemp(".v8code")
    command = "dd if=%s of=%s bs=1 count=%d skip=%d && " \
              "%s %s -D -b binary %s %s" % (
      filename, tmp_name, size, offset,
      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
      tmp_name)
  else:
    command = "%s %s %s --start-address=%d --stop-address=%d -d %s " % (
      OBJDUMP_BIN, ' '.join(_COMMON_DISASM_OPTIONS), arch_flags,
      offset,
      offset + size,
      filename)
  process = subprocess.Popen(command,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
  out, err = process.communicate()
  lines = out.split("\n")
  header_line = 0
  for i, line in enumerate(lines):
    if _DISASM_HEADER_RE.match(line):
      header_line = i
      break
  if tmp_name:
    os.unlink(tmp_name)
  split_lines = []
  for line in lines[header_line + 1:]:
    match = _DISASM_LINE_RE.match(line)
    if match:
      line_address = int(match.group(1), 16)
      split_lines.append((line_address, match.group(2)))
  return split_lines
node-v4.2.6/deps/v8/tools/draw_instruction_graph.sh000755 000766 000024 00000010451 12650222326 022515 0ustar00iojsstaff000000 000000 #!/bin/bash
#
# Copyright 2013 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# This script reads in CSV formatted instruction data, and draws a stacked
# graph in png format.

defaultfile=arm64_inst.csv
defaultout=arm64_inst.png
gnuplot=/usr/bin/gnuplot


# File containing CSV instruction data from simulator.
file=${1:-$defaultfile}

# Output graph png file.
out=${2:-$defaultout}

# Check input file exists.
if [ ! -e $file ]; then
  echo "Input file not found: $file."
  echo "Usage: draw_instruction_graph.sh  "
  exit 1
fi

# Search for an error message, and if found, exit.
error=`grep -m1 '# Error:' $file`
if [ -n "$error" ]; then
  echo "Error message in input file:"
  echo " $error"
  exit 2
fi

# Sample period - period over which numbers for each category of instructions is
# counted.
sp=`grep -m1 '# sample_period=' $file | cut -d= -f2`

# Get number of counters in the CSV file.
nc=`grep -m1 '# counters=' $file | cut -d= -f2`

# Find the annotation arrows. They appear as comments in the CSV file, in the
# format:
#   # xx @ yyyyy
# Where xx is a two character annotation identifier, and yyyyy is the
# position in the executed instruction stream that generated the annotation.
# Turn these locations into labelled arrows.
arrows=`sed '/^[^#]/ d' $file | \
        perl -pe "s/^# .. @ (\d+)/set arrow from \1, graph 0.9 to \1, $sp/"`;
labels=`sed '/^[^#]/d' $file | \
        sed -r 's/^# (..) @ (.+)/set label at \2, graph 0.9 "\1" \
                center offset 0,0.5 font "FreeSans, 8"/'`;

# Check for gnuplot, and warn if not available.
if [ ! -e $gnuplot ]; then
  echo "Can't find gnuplot at $gnuplot."
  echo "Gnuplot version 4.6.3 or later required."
  exit 3
fi

# Initialise gnuplot, and give it the data to draw.
echo | $gnuplot < 0

if __name__ == "__main__":
  sys.exit(Main())
node-v4.2.6/deps/v8/tools/find-commit-for-patch.py000755 000766 000024 00000006377 12650222326 022057 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
# Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import subprocess
import sys


def GetArgs():
  parser = argparse.ArgumentParser(
      description="Finds a commit that a given patch can be applied to. "
                  "Does not actually apply the patch or modify your checkout "
                  "in any way.")
  parser.add_argument("patch_file", help="Patch file to match")
  parser.add_argument(
      "--branch", "-b", default="origin/master", type=str,
      help="Git tree-ish where to start searching for commits, "
           "default: %(default)s")
  parser.add_argument(
      "--limit", "-l", default=500, type=int,
      help="Maximum number of commits to search, default: %(default)s")
  parser.add_argument(
      "--verbose", "-v", default=False, action="store_true",
      help="Print verbose output for your entertainment")
  return parser.parse_args()


def FindFilesInPatch(patch_file):
  files = {}
  next_file = ""
  with open(patch_file) as patch:
    for line in patch:
      if line.startswith("diff --git "):
        # diff --git a/src/objects.cc b/src/objects.cc
        words = line.split()
        assert words[2].startswith("a/") and len(words[2]) > 2
        next_file = words[2][2:]
      elif line.startswith("index "):
        # index add3e61..d1bbf6a 100644
        hashes = line.split()[1]
        old_hash = hashes.split("..")[0]
        if old_hash.startswith("0000000"): continue  # Ignore new files.
        files[next_file] = old_hash
  return files


def GetGitCommitHash(treeish):
  cmd = ["git", "log", "-1", "--format=%H", treeish]
  return subprocess.check_output(cmd).strip()


def CountMatchingFiles(commit, files):
  matched_files = 0
  # Calling out to git once and parsing the result Python-side is faster
  # than calling 'git ls-tree' for every file.
  cmd = ["git", "ls-tree", "-r", commit] + [f for f in files]
  output = subprocess.check_output(cmd)
  for line in output.splitlines():
    # 100644 blob c6d5daaa7d42e49a653f9861224aad0a0244b944      src/objects.cc
    _, _, actual_hash, filename = line.split()
    expected_hash = files[filename]
    if actual_hash.startswith(expected_hash): matched_files += 1
  return matched_files


def FindFirstMatchingCommit(start, files, limit, verbose):
  commit = GetGitCommitHash(start)
  num_files = len(files)
  if verbose: print(">>> Found %d files modified by patch." % num_files)
  for _ in range(limit):
    matched_files = CountMatchingFiles(commit, files)
    if verbose: print("Commit %s matched %d files" % (commit, matched_files))
    if matched_files == num_files:
      return commit
    commit = GetGitCommitHash("%s^" % commit)
  print("Sorry, no matching commit found. "
        "Try running 'git fetch', specifying the correct --branch, "
        "and/or setting a higher --limit.")
  sys.exit(1)


if __name__ == "__main__":
  args = GetArgs()
  files = FindFilesInPatch(args.patch_file)
  commit = FindFirstMatchingCommit(args.branch, files, args.limit, args.verbose)
  if args.verbose:
    print(">>> Matching commit: %s" % commit)
    print(subprocess.check_output(["git", "log", "-1", commit]))
    print(">>> Kthxbai.")
  else:
    print(commit)
node-v4.2.6/deps/v8/tools/find_depot_tools.py000644 000766 000024 00000002625 12650222326 021310 0ustar00iojsstaff000000 000000 # Copyright 2014 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Small utility function to find depot_tools and add it to the python path.
"""

import os
import sys


def directory_really_is_depot_tools(directory):
  return os.path.isfile(os.path.join(directory, 'gclient.py'))


def add_depot_tools_to_path():
  """Search for depot_tools and add it to sys.path."""
  # First look if depot_tools is already in PYTHONPATH.
  for i in sys.path:
    if i.rstrip(os.sep).endswith('depot_tools'):
      if directory_really_is_depot_tools(i):
        return i

  # Then look if depot_tools is in PATH, common case.
  for i in os.environ['PATH'].split(os.pathsep):
    if i.rstrip(os.sep).endswith('depot_tools'):
      if directory_really_is_depot_tools(i):
        sys.path.insert(0, i.rstrip(os.sep))
        return i
  # Rare case, it's not even in PATH, look upward up to root.
  root_dir = os.path.dirname(os.path.abspath(__file__))
  previous_dir = os.path.abspath(__file__)
  while root_dir and root_dir != previous_dir:
    if directory_really_is_depot_tools(os.path.join(root_dir, 'depot_tools')):
      i = os.path.join(root_dir, 'depot_tools')
      sys.path.insert(0, i)
      return i
    previous_dir = root_dir
    root_dir = os.path.dirname(root_dir)
  print >> sys.stderr, 'Failed to find depot_tools'
  return None
node-v4.2.6/deps/v8/tools/freebsd-tick-processor000755 000766 000024 00000000400 12650222326 021675 0ustar00iojsstaff000000 000000 #!/bin/sh

# A wrapper script to call 'linux-tick-processor'.

# Known issues on FreeBSD:
#  No ticks from C++ code.
#  You must have d8 built and in your path before calling this.

tools_path=`cd $(dirname "$0");pwd`
$tools_path/linux-tick-processor "$@"
node-v4.2.6/deps/v8/tools/fuzz-harness.sh000755 000766 000024 00000006624 12650222326 020404 0ustar00iojsstaff000000 000000 #!/bin/bash
# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# A simple harness that downloads and runs 'jsfunfuzz' against d8. This
# takes a long time because it runs many iterations and is intended for
# automated usage. The package containing 'jsfunfuzz' can be found as an
# attachment to this bug:
# https://bugzilla.mozilla.org/show_bug.cgi?id=jsfunfuzz

JSFUNFUZZ_URL="https://bugzilla.mozilla.org/attachment.cgi?id=310631"
JSFUNFUZZ_MD5="d0e497201c5cd7bffbb1cdc1574f4e32"

v8_root=$(readlink -f $(dirname $BASH_SOURCE)/../)

if [ -n "$1" ]; then
  d8="${v8_root}/$1"
else
  d8="${v8_root}/d8"
fi

if [ ! -f "$d8" ]; then
  echo "Failed to find d8 binary: $d8"
  exit 1
fi

jsfunfuzz_file="$v8_root/tools/jsfunfuzz.zip"
if [ ! -f "$jsfunfuzz_file" ]; then
  echo "Downloading $jsfunfuzz_file ..."
  wget -q -O "$jsfunfuzz_file" $JSFUNFUZZ_URL || exit 1
fi

jsfunfuzz_sum=$(md5sum "$jsfunfuzz_file" | awk '{ print $1 }')
if [ $jsfunfuzz_sum != $JSFUNFUZZ_MD5 ]; then
  echo "Failed to verify checksum!"
  exit 1
fi

jsfunfuzz_dir="$v8_root/tools/jsfunfuzz"
if [ ! -d "$jsfunfuzz_dir" ]; then
  echo "Unpacking into $jsfunfuzz_dir ..."
  unzip "$jsfunfuzz_file" -d "$jsfunfuzz_dir" || exit 1
  echo "Patching runner ..."
  cat << EOF | patch -s -p0 -d "$v8_root"
--- tools/jsfunfuzz/jsfunfuzz/multi_timed_run.py~
+++ tools/jsfunfuzz/jsfunfuzz/multi_timed_run.py
@@ -125,7 +125,7 @@
 
 def many_timed_runs():
     iteration = 0
-    while True:
+    while iteration < 100:
         iteration += 1
         logfilename = "w%d" % iteration
         one_timed_run(logfilename)
EOF
fi

flags='--debug-code --expose-gc --verify-gc'
python -u "$jsfunfuzz_dir/jsfunfuzz/multi_timed_run.py" 300 \
    "$d8" $flags "$jsfunfuzz_dir/jsfunfuzz/jsfunfuzz.js"
exit_code=$(cat w* | grep " looking good" -c)
exit_code=$((100-exit_code))
tar -cjf fuzz-results-$(date +%Y%m%d%H%M%S).tar.bz2 err-* w*
rm -f err-* w*

echo "Total failures: $exit_code"
exit $exit_code
node-v4.2.6/deps/v8/tools/gc-nvp-to-csv.py000755 000766 000024 00000001367 12650222326 020365 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
#
# Copyright 2015 the V8 project authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#
# This is an utility for generating csv files based on GC traces produced by
# V8 when run with flags --trace-gc --trace-gc-nvp.
#
# Usage: gc-nvp-to-csv.py 
#

import sys
import gc_nvp_common

def process_trace(filename):
  trace = gc_nvp_common.parse_gc_trace(filename)
  if len(trace):
    keys = trace[0].keys()
    print ', '.join(keys)
    for entry in trace:
      print ', '.join(map(lambda key: str(entry[key]), keys))


if len(sys.argv) != 2:
  print "Usage: %s " % sys.argv[0]
  sys.exit(1)

process_trace(sys.argv[1])
node-v4.2.6/deps/v8/tools/gc-nvp-trace-processor.py000755 000766 000024 00000025577 12650222326 022276 0ustar00iojsstaff000000 000000 #!/usr/bin/env python
#
# Copyright 2010 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
#       copyright notice, this list of conditions and the following
#       disclaimer in the documentation and/or other materials provided
#       with the distribution.
#     * Neither the name of Google Inc. nor the names of its
#       contributors may be used to endorse or promote products derived
#       from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

#
# This is an utility for plotting charts based on GC traces produced by V8 when
# run with flags --trace-gc --trace-gc-nvp. Relies on gnuplot for actual
# plotting.
#
# Usage: gc-nvp-trace-processor.py 
#


from __future__ import with_statement
import sys, types, subprocess, math
import gc_nvp_common

def flatten(l):
  flat = []
  for i in l: flat.extend(i)
  return flat

def gnuplot(script):
  gnuplot = subprocess.Popen(["gnuplot"], stdin=subprocess.PIPE)
  gnuplot.stdin.write(script)
  gnuplot.stdin.close()
  gnuplot.wait()

x1y1 = 'x1y1'
x1y2 = 'x1y2'
x2y1 = 'x2y1'
x2y2 = 'x2y2'

class Item(object):
  def __init__(self, title, field, axis = x1y1, **keywords):
    self.title = title
    self.axis = axis
    self.props = keywords
    if type(field) is types.ListType:
      self.field = field
    else:
      self.field = [field]

  def fieldrefs(self):
    return self.field

  def to_gnuplot(self, context):
    args = ['"%s"' % context.datafile,
            'using %s' % context.format_fieldref(self.field),
            'title "%s"' % self.title,
            'axis %s' % self.axis]
    if 'style' in self.props:
      args.append('with %s' % self.props['style'])
    if 'lc' in self.props:
      args.append('lc rgb "%s"' % self.props['lc'])
    if 'fs' in self.props:
      args.append('fs %s' % self.props['fs'])
    return ' '.join(args)

class Plot(object):
  def __init__(self, *items):
    self.items = items

  def fieldrefs(self):
    return flatten([item.fieldrefs() for item in self.items])

  def to_gnuplot(self, ctx):
    return 'plot ' + ', '.join([item.to_gnuplot(ctx) for item in self.items])

class Set(object):
  def __init__(self, value):
    self.value = value

  def to_gnuplot(self, ctx):
    return 'set ' + self.value

  def fieldrefs(self):
    return []

class Context(object):
  def __init__(self, datafile, field_to_index):
    self.datafile = datafile
    self.field_to_index = field_to_index

  def format_fieldref(self, fieldref):
    return ':'.join([str(self.field_to_index[field]) for field in fieldref])

def collect_fields(plot):
  field_to_index = {}
  fields = []

  def add_field(field):
    if field not in field_to_index:
      fields.append(field)
      field_to_index[field] = len(fields)

  for field in flatten([item.fieldrefs() for item in plot]):
    add_field(field)

  return (fields, field_to_index)

def is_y2_used(plot):
  for subplot in plot:
    if isinstance(subplot, Plot):
      for item in subplot.items:
        if item.axis == x1y2 or item.axis == x2y2:
          return True
  return False

def get_field(trace_line, field):
  t = type(field)
  if t is types.StringType:
    return trace_line[field]
  elif t is types.FunctionType:
    return field(trace_line)

def generate_datafile(datafile_name, trace, fields):
  with open(datafile_name, 'w') as datafile:
    for line in trace:
      data_line = [str(get_field(line, field)) for field in fields]
      datafile.write('\t'.join(data_line))
      datafile.write('\n')

def generate_script_and_datafile(plot, trace, datafile, output):
  (fields, field_to_index) = collect_fields(plot)
  generate_datafile(datafile, trace, fields)
  script = [
      'set terminal png',
      'set output "%s"' % output,
      'set autoscale',
      'set ytics nomirror',
      'set xtics nomirror',
      'set key below'
  ]

  if is_y2_used(plot):
    script.append('set autoscale y2')
    script.append('set y2tics')

  context = Context(datafile, field_to_index)

  for item in plot:
    script.append(item.to_gnuplot(context))

  return '\n'.join(script)

def plot_all(plots, trace, prefix):
  charts = []

  for plot in plots:
    outfilename = "%s_%d.png" % (prefix, len(charts))
    charts.append(outfilename)
    script = generate_script_and_datafile(plot, trace, '~datafile', outfilename)
    print 'Plotting %s...' % outfilename
    gnuplot(script)

  return charts

def reclaimed_bytes(row):
  return row['total_size_before'] - row['total_size_after']

def other_scope(r):
  if r['gc'] == 's':
    # there is no 'other' scope for scavenging collections.
    return 0
  return r['pause'] - r['mark'] - r['sweep'] - r['external']

def scavenge_scope(r):
  if r['gc'] == 's':
    return r['pause'] - r['external']
  return 0


def real_mutator(r):
  return r['mutator'] - r['steps_took']

plots = [
  [
    Set('style fill solid 0.5 noborder'),
    Set('style histogram rowstacked'),
    Set('style data histograms'),
    Plot(Item('Scavenge', scavenge_scope, lc = 'green'),
         Item('Marking', 'mark', lc = 'purple'),
         Item('Sweep', 'sweep', lc = 'blue'),
         Item('External', 'external', lc = '#489D43'),
         Item('Other', other_scope, lc = 'grey'),
         Item('IGC Steps', 'steps_took', lc = '#FF6347'))
  ],
  [
    Set('style fill solid 0.5 noborder'),
    Set('style histogram rowstacked'),
    Set('style data histograms'),
    Plot(Item('Scavenge', scavenge_scope, lc = 'green'),
         Item('Marking', 'mark', lc = 'purple'),
         Item('Sweep', 'sweep', lc = 'blue'),
         Item('External', 'external', lc = '#489D43'),
         Item('Other', other_scope, lc = '#ADD8E6'),
         Item('External', 'external', lc = '#D3D3D3'))
  ],

  [
    Plot(Item('Mutator', real_mutator, lc = 'black', style = 'lines'))
  ],
  [
    Set('style histogram rowstacked'),
    Set('style data histograms'),
    Plot(Item('Heap Size (before GC)', 'total_size_before', x1y2,
              fs = 'solid 0.4 noborder',
              lc = 'green'),
         Item('Total holes (after GC)', 'holes_size_before', x1y2,
              fs = 'solid 0.4 noborder',
              lc = 'red'),
         Item('GC Time', ['i', 'pause'], style = 'lines', lc = 'red'))
  ],
  [
    Set('style histogram rowstacked'),
    Set('style data histograms'),
    Plot(Item('Heap Size (after GC)', 'total_size_after', x1y2,
              fs = 'solid 0.4 noborder',
              lc = 'green'),
         Item('Total holes (after GC)', 'holes_size_after', x1y2,
              fs = 'solid 0.4 noborder',
              lc = 'red'),
         Item('GC Time', ['i', 'pause'],
              style = 'lines',
              lc = 'red'))
  ],
  [
    Set('style fill solid 0.5 noborder'),
    Set('style data histograms'),
    Plot(Item('Allocated', 'allocated'),
         Item('Reclaimed', reclaimed_bytes),
         Item('Promoted', 'promoted', style = 'lines', lc = 'black'))
  ],
]

def freduce(f, field, trace, init):
  return reduce(lambda t,r: f(t, r[field]), trace, init)

def calc_total(trace, field):
  return freduce(lambda t,v: t + long(v), field, trace, long(0))

def calc_max(trace, field):
  return freduce(lambda t,r: max(t, r), field, trace, 0)

def count_nonzero(trace, field):
  return freduce(lambda t,r: t if r == 0 else t + 1, field, trace, 0)


def process_trace(filename):
  trace = gc_nvp_common.parse_gc_trace(filename)

  marksweeps = filter(lambda r: r['gc'] == 'ms', trace)
  scavenges = filter(lambda r: r['gc'] == 's', trace)
  globalgcs = filter(lambda r: r['gc'] != 's', trace)


  charts = plot_all(plots, trace, filename)

  def stats(out, prefix, trace, field):
    n = len(trace)
    total = calc_total(trace, field)
    max = calc_max(trace, field)
    if n > 0:
      avg = total / n
    else:
      avg = 0
    if n > 1:
      dev = math.sqrt(freduce(lambda t,r: t + (r - avg) ** 2, field, trace, 0) /
                      (n - 1))
    else:
      dev = 0

    out.write('%s%d%d'
              '%d%d [dev %f]' %
              (prefix, n, total, max, avg, dev))

  def HumanReadable(size):
    suffixes = ['bytes', 'kB', 'MB', 'GB']
    power = 1
    for i in range(len(suffixes)):
      if size < power*1024:
        return "%.1f" % (float(size) / power) + " " + suffixes[i]
      power *= 1024

  def throughput(name, trace):
    total_live_after = calc_total(trace, 'total_size_after')
    total_live_before = calc_total(trace, 'total_size_before')
    total_gc = calc_total(trace, 'pause')
    if total_gc == 0:
      return
    out.write('GC %s Throughput (after): %s / %s ms = %s/ms
' % (name, HumanReadable(total_live_after), total_gc, HumanReadable(total_live_after / total_gc))) out.write('GC %s Throughput (before): %s / %s ms = %s/ms
' % (name, HumanReadable(total_live_before), total_gc, HumanReadable(total_live_before / total_gc))) with open(filename + '.html', 'w') as out: out.write('') out.write('') out.write('') out.write('') stats(out, 'Total in GC', trace, 'pause') stats(out, 'Scavenge', scavenges, 'pause') stats(out, 'MarkSweep', marksweeps, 'pause') stats(out, 'Mark', filter(lambda r: r['mark'] != 0, trace), 'mark') stats(out, 'Sweep', filter(lambda r: r['sweep'] != 0, trace), 'sweep') stats(out, 'External', filter(lambda r: r['external'] != 0, trace), 'external') out.write('
PhaseCountTime (ms)MaxAvg
') throughput('TOTAL', trace) throughput('MS', marksweeps) throughput('OLDSPACE', globalgcs) out.write('
') for chart in charts: out.write('' % chart) out.write('') print "%s generated." % (filename + '.html') if len(sys.argv) != 2: print "Usage: %s " % sys.argv[0] sys.exit(1) process_trace(sys.argv[1]) node-v4.2.6/deps/v8/tools/gc_nvp_common.py000644 000766 000024 00000001265 12650222326 020600 0ustar00iojsstaff000000 000000 # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # # Common code for parsing --trace-gc-nvp output. # from __future__ import with_statement import re def split_nvp(s): t = {} for (name, value) in re.findall(r"(\w+)=([-\w]+)", s): try: t[name] = float(value) except ValueError: t[name] = value return t def parse_gc_trace(input): trace = [] with open(input) as f: for line in f: info = split_nvp(line) if info and 'pause' in info and info['pause'] > 0: info['i'] = len(trace) trace.append(info) return trace node-v4.2.6/deps/v8/tools/gcmole/000755 000766 000024 00000000000 12650222326 016644 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/gdb-v8-support.py000644 000766 000024 00000012321 12650222326 020550 0ustar00iojsstaff000000 000000 # Copyright 2011 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. kSmiTag = 0 kSmiTagSize = 1 kSmiTagMask = (1 << kSmiTagSize) - 1 kHeapObjectTag = 1 kHeapObjectTagSize = 2 kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1 kFailureTag = 3 kFailureTagSize = 2 kFailureTagMask = (1 << kFailureTagSize) - 1 kSmiShiftSize32 = 0 kSmiValueSize32 = 31 kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32 kSmiShiftSize64 = 31 kSmiValueSize64 = 32 kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64 kAllBits = 0xFFFFFFFF kTopBit32 = 0x80000000 kTopBit64 = 0x8000000000000000 t_u32 = gdb.lookup_type('unsigned int') t_u64 = gdb.lookup_type('unsigned long long') def has_smi_tag(v): return v & kSmiTagMask == kSmiTag def has_failure_tag(v): return v & kFailureTagMask == kFailureTag def has_heap_object_tag(v): return v & kHeapObjectTagMask == kHeapObjectTag def raw_heap_object(v): return v - kHeapObjectTag def smi_to_int_32(v): v = v & kAllBits if (v & kTopBit32) == kTopBit32: return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648 else: return (v & kAllBits) >> kSmiShiftBits32 def smi_to_int_64(v): return (v >> kSmiShiftBits64) def decode_v8_value(v, bitness): base_str = 'v8[%x]' % v if has_smi_tag(v): if bitness == 32: return base_str + (" SMI(%d)" % smi_to_int_32(v)) else: return base_str + (" SMI(%d)" % smi_to_int_64(v)) elif has_failure_tag(v): return base_str + " (failure)" elif has_heap_object_tag(v): return base_str + (" H(0x%x)" % raw_heap_object(v)) else: return base_str class V8ValuePrinter(object): "Print a v8value." def __init__(self, val): self.val = val def to_string(self): if self.val.type.sizeof == 4: v_u32 = self.val.cast(t_u32) return decode_v8_value(int(v_u32), 32) elif self.val.type.sizeof == 8: v_u64 = self.val.cast(t_u64) return decode_v8_value(int(v_u64), 64) else: return 'v8value?' def display_hint(self): return 'v8value' def v8_pretty_printers(val): lookup_tag = val.type.tag if lookup_tag == None: return None elif lookup_tag == 'v8value': return V8ValuePrinter(val) return None gdb.pretty_printers.append(v8_pretty_printers) def v8_to_int(v): if v.type.sizeof == 4: return int(v.cast(t_u32)) elif v.type.sizeof == 8: return int(v.cast(t_u64)) else: return '?' def v8_get_value(vstring): v = gdb.parse_and_eval(vstring) return v8_to_int(v) class V8PrintObject (gdb.Command): """Prints a v8 object.""" def __init__ (self): super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA) def invoke (self, arg, from_tty): v = v8_get_value(arg) gdb.execute('call __gdb_print_v8_object(%d)' % v) V8PrintObject() class FindAnywhere (gdb.Command): """Search memory for the given pattern.""" MAPPING_RE = re.compile(r"^\s*\[\d+\]\s+0x([0-9A-Fa-f]+)->0x([0-9A-Fa-f]+)") LIVE_MAPPING_RE = re.compile(r"^\s+0x([0-9A-Fa-f]+)\s+0x([0-9A-Fa-f]+)") def __init__ (self): super (FindAnywhere, self).__init__ ("find-anywhere", gdb.COMMAND_DATA) def find (self, startAddr, endAddr, value): try: result = gdb.execute( "find 0x%s, 0x%s, %s" % (startAddr, endAddr, value), to_string = True) if result.find("not found") == -1: print result except: pass def invoke (self, value, from_tty): for l in gdb.execute("maint info sections", to_string = True).split('\n'): m = FindAnywhere.MAPPING_RE.match(l) if m is None: continue self.find(m.group(1), m.group(2), value) for l in gdb.execute("info proc mappings", to_string = True).split('\n'): m = FindAnywhere.LIVE_MAPPING_RE.match(l) if m is None: continue self.find(m.group(1), m.group(2), value) FindAnywhere() node-v4.2.6/deps/v8/tools/gdbinit000644 000766 000024 00000002161 12650222326 016741 0ustar00iojsstaff000000 000000 # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Print HeapObjects. define job print ((v8::internal::HeapObject*)($arg0))->Print() end document job Print a v8 JavaScript object Usage: job tagged_ptr end # Print Code objects containing given PC. define jco job (v8::internal::Isolate::Current()->FindCodeObject((v8::internal::Address)$arg0)) end document jco Print a v8 Code object from an internal code address Usage: jco pc end # Print DescriptorArray. define jda print ((v8::internal::DescriptorArray*)($arg0))->Print() end document jda Print a v8 DescriptorArray object Usage: jda tagged_ptr end # Print TransitionArray. define jta print ((v8::internal::TransitionArray*)($arg0))->Print() end document jta Print a v8 TransitionArray object Usage: jta tagged_ptr end # Print JavaScript stack trace. define jst print v8::internal::Isolate::Current()->PrintStack((FILE*) stdout, 1) end document jst Print the current JavaScript stack trace Usage: jst end set disassembly-flavor intel set disable-randomization off node-v4.2.6/deps/v8/tools/gen-postmortem-metadata.py000644 000766 000024 00000050443 12650222326 022514 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # Emits a C++ file to be compiled and linked into libv8 to support postmortem # debugging tools. Most importantly, this tool emits constants describing V8 # internals: # # v8dbg_type_CLASS__TYPE = VALUE Describes class type values # v8dbg_class_CLASS__FIELD__TYPE = OFFSET Describes class fields # v8dbg_parent_CLASS__PARENT Describes class hierarchy # v8dbg_frametype_NAME = VALUE Describes stack frame values # v8dbg_off_fp_NAME = OFFSET Frame pointer offsets # v8dbg_prop_NAME = OFFSET Object property offsets # v8dbg_NAME = VALUE Miscellaneous values # # These constants are declared as global integers so that they'll be present in # the generated libv8 binary. # import re import sys # # Miscellaneous constants, tags, and masks used for object identification. # consts_misc = [ { 'name': 'FirstNonstringType', 'value': 'FIRST_NONSTRING_TYPE' }, { 'name': 'IsNotStringMask', 'value': 'kIsNotStringMask' }, { 'name': 'StringTag', 'value': 'kStringTag' }, { 'name': 'NotStringTag', 'value': 'kNotStringTag' }, { 'name': 'StringEncodingMask', 'value': 'kStringEncodingMask' }, { 'name': 'TwoByteStringTag', 'value': 'kTwoByteStringTag' }, { 'name': 'OneByteStringTag', 'value': 'kOneByteStringTag' }, { 'name': 'StringRepresentationMask', 'value': 'kStringRepresentationMask' }, { 'name': 'SeqStringTag', 'value': 'kSeqStringTag' }, { 'name': 'ConsStringTag', 'value': 'kConsStringTag' }, { 'name': 'ExternalStringTag', 'value': 'kExternalStringTag' }, { 'name': 'SlicedStringTag', 'value': 'kSlicedStringTag' }, { 'name': 'HeapObjectTag', 'value': 'kHeapObjectTag' }, { 'name': 'HeapObjectTagMask', 'value': 'kHeapObjectTagMask' }, { 'name': 'SmiTag', 'value': 'kSmiTag' }, { 'name': 'SmiTagMask', 'value': 'kSmiTagMask' }, { 'name': 'SmiValueShift', 'value': 'kSmiTagSize' }, { 'name': 'SmiShiftSize', 'value': 'kSmiShiftSize' }, { 'name': 'PointerSizeLog2', 'value': 'kPointerSizeLog2' }, { 'name': 'OddballFalse', 'value': 'Oddball::kFalse' }, { 'name': 'OddballTrue', 'value': 'Oddball::kTrue' }, { 'name': 'OddballTheHole', 'value': 'Oddball::kTheHole' }, { 'name': 'OddballNull', 'value': 'Oddball::kNull' }, { 'name': 'OddballArgumentMarker', 'value': 'Oddball::kArgumentMarker' }, { 'name': 'OddballUndefined', 'value': 'Oddball::kUndefined' }, { 'name': 'OddballUninitialized', 'value': 'Oddball::kUninitialized' }, { 'name': 'OddballOther', 'value': 'Oddball::kOther' }, { 'name': 'OddballException', 'value': 'Oddball::kException' }, { 'name': 'prop_idx_first', 'value': 'DescriptorArray::kFirstIndex' }, { 'name': 'prop_type_field', 'value': 'DATA' }, { 'name': 'prop_type_mask', 'value': 'PropertyDetails::TypeField::kMask' }, { 'name': 'prop_index_mask', 'value': 'PropertyDetails::FieldIndexField::kMask' }, { 'name': 'prop_index_shift', 'value': 'PropertyDetails::FieldIndexField::kShift' }, { 'name': 'prop_desc_key', 'value': 'DescriptorArray::kDescriptorKey' }, { 'name': 'prop_desc_details', 'value': 'DescriptorArray::kDescriptorDetails' }, { 'name': 'prop_desc_value', 'value': 'DescriptorArray::kDescriptorValue' }, { 'name': 'prop_desc_size', 'value': 'DescriptorArray::kDescriptorSize' }, { 'name': 'elements_fast_holey_elements', 'value': 'FAST_HOLEY_ELEMENTS' }, { 'name': 'elements_fast_elements', 'value': 'FAST_ELEMENTS' }, { 'name': 'elements_dictionary_elements', 'value': 'DICTIONARY_ELEMENTS' }, { 'name': 'bit_field2_elements_kind_mask', 'value': 'Map::ElementsKindBits::kMask' }, { 'name': 'bit_field2_elements_kind_shift', 'value': 'Map::ElementsKindBits::kShift' }, { 'name': 'bit_field3_dictionary_map_shift', 'value': 'Map::DictionaryMap::kShift' }, { 'name': 'off_fp_context', 'value': 'StandardFrameConstants::kContextOffset' }, { 'name': 'off_fp_constant_pool', 'value': 'StandardFrameConstants::kConstantPoolOffset' }, { 'name': 'off_fp_marker', 'value': 'StandardFrameConstants::kMarkerOffset' }, { 'name': 'off_fp_function', 'value': 'JavaScriptFrameConstants::kFunctionOffset' }, { 'name': 'off_fp_args', 'value': 'JavaScriptFrameConstants::kLastParameterOffset' }, { 'name': 'scopeinfo_idx_nparams', 'value': 'ScopeInfo::kParameterCount' }, { 'name': 'scopeinfo_idx_nstacklocals', 'value': 'ScopeInfo::kStackLocalCount' }, { 'name': 'scopeinfo_idx_ncontextlocals', 'value': 'ScopeInfo::kContextLocalCount' }, { 'name': 'scopeinfo_idx_first_vars', 'value': 'ScopeInfo::kVariablePartIndex' }, ]; # # The following useful fields are missing accessors, so we define fake ones. # extras_accessors = [ 'HeapObject, map, Map, kMapOffset', 'JSObject, elements, Object, kElementsOffset', 'FixedArray, data, uintptr_t, kHeaderSize', 'JSTypedArray, length, Object, kLengthOffset', 'Map, instance_attributes, int, kInstanceAttributesOffset', 'Map, inobject_properties, int, kInObjectPropertiesOffset', 'Map, instance_size, int, kInstanceSizeOffset', 'Map, bit_field, char, kBitFieldOffset', 'Map, bit_field2, char, kBitField2Offset', 'Map, bit_field3, int, kBitField3Offset', 'Map, prototype, Object, kPrototypeOffset', 'NameDictionaryShape, prefix_size, int, kPrefixSize', 'NameDictionaryShape, entry_size, int, kEntrySize', 'SeededNumberDictionaryShape, prefix_size, int, kPrefixSize', 'UnseededNumberDictionaryShape, prefix_size, int, kPrefixSize', 'NumberDictionaryShape, entry_size, int, kEntrySize', 'Oddball, kind_offset, int, kKindOffset', 'HeapNumber, value, double, kValueOffset', 'ConsString, first, String, kFirstOffset', 'ConsString, second, String, kSecondOffset', 'ExternalString, resource, Object, kResourceOffset', 'SeqOneByteString, chars, char, kHeaderSize', 'SeqTwoByteString, chars, char, kHeaderSize', 'SharedFunctionInfo, code, Code, kCodeOffset', 'SlicedString, parent, String, kParentOffset', 'Code, instruction_start, uintptr_t, kHeaderSize', 'Code, instruction_size, int, kInstructionSizeOffset', ]; # # The following is a whitelist of classes we expect to find when scanning the # source code. This list is not exhaustive, but it's still useful to identify # when this script gets out of sync with the source. See load_objects(). # expected_classes = [ 'ConsString', 'FixedArray', 'HeapNumber', 'JSArray', 'JSFunction', 'JSObject', 'JSRegExp', 'JSValue', 'Map', 'Oddball', 'Script', 'SeqOneByteString', 'SharedFunctionInfo' ]; # # The following structures store high-level representations of the structures # for which we're going to emit descriptive constants. # types = {}; # set of all type names typeclasses = {}; # maps type names to corresponding class names klasses = {}; # known classes, including parents fields = []; # field declarations header = ''' /* * This file is generated by %s. Do not edit directly. */ #include "src/v8.h" #include "src/frames.h" #include "src/frames-inl.h" /* for architecture-specific frame constants */ using namespace v8::internal; extern "C" { /* stack frame constants */ #define FRAME_CONST(value, klass) \ int v8dbg_frametype_##klass = StackFrame::value; STACK_FRAME_TYPE_LIST(FRAME_CONST) #undef FRAME_CONST ''' % sys.argv[0]; footer = ''' } ''' # # Loads class hierarchy and type information from "objects.h". # def load_objects(): objfilename = sys.argv[2]; objfile = open(objfilename, 'r'); in_insttype = False; typestr = ''; # # Construct a dictionary for the classes we're sure should be present. # checktypes = {}; for klass in expected_classes: checktypes[klass] = True; # # Iterate objects.h line-by-line to collect type and class information. # For types, we accumulate a string representing the entire InstanceType # enum definition and parse it later because it's easier to do so # without the embedded newlines. # for line in objfile: if (line.startswith('enum InstanceType {')): in_insttype = True; continue; if (in_insttype and line.startswith('};')): in_insttype = False; continue; line = re.sub('//.*', '', line.rstrip().lstrip()); if (in_insttype): typestr += line; continue; match = re.match('class (\w[^\s:]*)(: public (\w[^\s{]*))?\s*{', line); if (match): klass = match.group(1); pklass = match.group(3); klasses[klass] = { 'parent': pklass }; # # Process the instance type declaration. # entries = typestr.split(','); for entry in entries: types[re.sub('\s*=.*', '', entry).lstrip()] = True; # # Infer class names for each type based on a systematic transformation. # For example, "JS_FUNCTION_TYPE" becomes "JSFunction". We find the # class for each type rather than the other way around because there are # fewer cases where one type maps to more than one class than the other # way around. # for type in types: # # Symbols and Strings are implemented using the same classes. # usetype = re.sub('SYMBOL_', 'STRING_', type); # # REGEXP behaves like REG_EXP, as in JS_REGEXP_TYPE => JSRegExp. # usetype = re.sub('_REGEXP_', '_REG_EXP_', usetype); # # Remove the "_TYPE" suffix and then convert to camel case, # except that a "JS" prefix remains uppercase (as in # "JS_FUNCTION_TYPE" => "JSFunction"). # if (not usetype.endswith('_TYPE')): continue; usetype = usetype[0:len(usetype) - len('_TYPE')]; parts = usetype.split('_'); cctype = ''; if (parts[0] == 'JS'): cctype = 'JS'; start = 1; else: cctype = ''; start = 0; for ii in range(start, len(parts)): part = parts[ii]; cctype += part[0].upper() + part[1:].lower(); # # Mapping string types is more complicated. Both types and # class names for Strings specify a representation (e.g., Seq, # Cons, External, or Sliced) and an encoding (TwoByte/OneByte), # In the simplest case, both of these are explicit in both # names, as in: # # EXTERNAL_ONE_BYTE_STRING_TYPE => ExternalOneByteString # # However, either the representation or encoding can be omitted # from the type name, in which case "Seq" and "TwoByte" are # assumed, as in: # # STRING_TYPE => SeqTwoByteString # # Additionally, sometimes the type name has more information # than the class, as in: # # CONS_ONE_BYTE_STRING_TYPE => ConsString # # To figure this out dynamically, we first check for a # representation and encoding and add them if they're not # present. If that doesn't yield a valid class name, then we # strip out the representation. # if (cctype.endswith('String')): if (cctype.find('Cons') == -1 and cctype.find('External') == -1 and cctype.find('Sliced') == -1): if (cctype.find('OneByte') != -1): cctype = re.sub('OneByteString$', 'SeqOneByteString', cctype); else: cctype = re.sub('String$', 'SeqString', cctype); if (cctype.find('OneByte') == -1): cctype = re.sub('String$', 'TwoByteString', cctype); if (not (cctype in klasses)): cctype = re.sub('OneByte', '', cctype); cctype = re.sub('TwoByte', '', cctype); # # Despite all that, some types have no corresponding class. # if (cctype in klasses): typeclasses[type] = cctype; if (cctype in checktypes): del checktypes[cctype]; if (len(checktypes) > 0): for klass in checktypes: print('error: expected class \"%s\" not found' % klass); sys.exit(1); # # For a given macro call, pick apart the arguments and return an object # describing the corresponding output constant. See load_fields(). # def parse_field(call): # Replace newlines with spaces. for ii in range(0, len(call)): if (call[ii] == '\n'): call[ii] == ' '; idx = call.find('('); kind = call[0:idx]; rest = call[idx + 1: len(call) - 1]; args = re.split('\s*,\s*', rest); consts = []; if (kind == 'ACCESSORS' or kind == 'ACCESSORS_GCSAFE'): klass = args[0]; field = args[1]; dtype = args[2]; offset = args[3]; return ({ 'name': 'class_%s__%s__%s' % (klass, field, dtype), 'value': '%s::%s' % (klass, offset) }); assert(kind == 'SMI_ACCESSORS' or kind == 'ACCESSORS_TO_SMI'); klass = args[0]; field = args[1]; offset = args[2]; return ({ 'name': 'class_%s__%s__%s' % (klass, field, 'SMI'), 'value': '%s::%s' % (klass, offset) }); # # Load field offset information from objects-inl.h. # def load_fields(): inlfilename = sys.argv[3]; inlfile = open(inlfilename, 'r'); # # Each class's fields and the corresponding offsets are described in the # source by calls to macros like "ACCESSORS" (and friends). All we do # here is extract these macro invocations, taking into account that they # may span multiple lines and may contain nested parentheses. We also # call parse_field() to pick apart the invocation. # prefixes = [ 'ACCESSORS', 'ACCESSORS_GCSAFE', 'SMI_ACCESSORS', 'ACCESSORS_TO_SMI' ]; current = ''; opens = 0; for line in inlfile: if (opens > 0): # Continuation line for ii in range(0, len(line)): if (line[ii] == '('): opens += 1; elif (line[ii] == ')'): opens -= 1; if (opens == 0): break; current += line[0:ii + 1]; continue; for prefix in prefixes: if (not line.startswith(prefix + '(')): continue; if (len(current) > 0): fields.append(parse_field(current)); current = ''; for ii in range(len(prefix), len(line)): if (line[ii] == '('): opens += 1; elif (line[ii] == ')'): opens -= 1; if (opens == 0): break; current += line[0:ii + 1]; if (len(current) > 0): fields.append(parse_field(current)); current = ''; for body in extras_accessors: fields.append(parse_field('ACCESSORS(%s)' % body)); # # Emit a block of constants. # def emit_set(out, consts): # Fix up overzealous parses. This could be done inside the # parsers but as there are several, it's easiest to do it here. ws = re.compile('\s+') for const in consts: name = ws.sub('', const['name']) value = ws.sub('', str(const['value'])) # Can be a number. out.write('int v8dbg_%s = %s;\n' % (name, value)) out.write('\n'); # # Emit the whole output file. # def emit_config(): out = file(sys.argv[1], 'w'); out.write(header); out.write('/* miscellaneous constants */\n'); emit_set(out, consts_misc); out.write('/* class type information */\n'); consts = []; keys = typeclasses.keys(); keys.sort(); for typename in keys: klass = typeclasses[typename]; consts.append({ 'name': 'type_%s__%s' % (klass, typename), 'value': typename }); emit_set(out, consts); out.write('/* class hierarchy information */\n'); consts = []; keys = klasses.keys(); keys.sort(); for klassname in keys: pklass = klasses[klassname]['parent']; if (pklass == None): continue; consts.append({ 'name': 'parent_%s__%s' % (klassname, pklass), 'value': 0 }); emit_set(out, consts); out.write('/* field information */\n'); emit_set(out, fields); out.write(footer); if (len(sys.argv) < 4): print('usage: %s output.cc objects.h objects-inl.h' % sys.argv[0]); sys.exit(2); load_objects(); load_fields(); emit_config(); node-v4.2.6/deps/v8/tools/generate-builtins-tests.py000755 000766 000024 00000010731 12650222326 022536 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import json import optparse import os import random import shutil import subprocess import sys BLACKLIST = [ # Skip special d8 functions. "load", "os", "print", "read", "readline", "quit" ] def GetRandomObject(): return random.choice([ "0", "1", "2.5", "0x1000", "\"string\"", "{foo: \"bar\"}", "[1, 2, 3]", "function() { return 0; }" ]) g_var_index = 0 def GetVars(result, num, first = []): global g_var_index variables = [] for i in range(num): variables.append("__v_%d" % g_var_index) g_var_index += 1 for var in variables: result.append("var %s = %s;" % (var, GetRandomObject())) return ", ".join(first + variables) # Wraps |string| in try..catch. def TryCatch(result, string, exception_behavior = ""): result.append("try { %s } catch(e) { %s }" % (string, exception_behavior)) def BuildTests(function, full_name, options): assert function["type"] == "function" global g_var_index g_var_index = 0 result = ["// AUTO-GENERATED BY tools/generate-builtins-tests.py.\n"] result.append("// Function call test:") length = function["length"] TryCatch(result, "%s(%s);" % (full_name, GetVars(result, length))) if "prototype" in function: proto = function["prototype"] result.append("\n// Constructor test:") TryCatch(result, "var recv = new %s(%s);" % (full_name, GetVars(result, length)), "var recv = new Object();") getters = [] methods = [] for prop in proto: proto_property = proto[prop] proto_property_type = proto_property["type"] if proto_property_type == "getter": getters.append(proto_property) result.append("recv.__defineGetter__(\"%s\", " "function() { return %s; });" % (proto_property["name"], GetVars(result, 1))) if proto_property_type == "number": result.append("recv.__defineGetter__(\"%s\", " "function() { return %s; });" % (proto_property["name"], GetVars(result, 1))) if proto_property_type == "function": methods.append(proto_property) if getters: result.append("\n// Getter tests:") for getter in getters: result.append("print(recv.%s);" % getter["name"]) if methods: result.append("\n// Method tests:") for method in methods: args = GetVars(result, method["length"], ["recv"]) call = "%s.prototype.%s.call(%s)" % (full_name, method["name"], args) TryCatch(result, call) filename = os.path.join(options.outdir, "%s.js" % (full_name)) with open(filename, "w") as f: f.write("\n".join(result)) f.write("\n") def VisitObject(obj, path, options): obj_type = obj["type"] obj_name = "%s%s" % (path, obj["name"]) if obj_type == "function": BuildTests(obj, obj_name, options) if "properties" in obj: for prop_name in obj["properties"]: prop = obj["properties"][prop_name] VisitObject(prop, "%s." % (obj_name), options) def ClearGeneratedFiles(options): if os.path.exists(options.outdir): shutil.rmtree(options.outdir) def GenerateTests(options): ClearGeneratedFiles(options) # Re-generate everything. output = subprocess.check_output( "%s %s" % (options.d8, options.script), shell=True).strip() objects = json.loads(output) os.makedirs(options.outdir) for obj_name in objects: if obj_name in BLACKLIST: continue obj = objects[obj_name] VisitObject(obj, "", options) def BuildOptions(): result = optparse.OptionParser() result.add_option("--d8", help="d8 binary to use", default="out/ia32.release/d8") result.add_option("--outdir", help="directory where to place generated tests", default="test/mjsunit/builtins-gen") result.add_option("--script", help="builtins detector script to run in d8", default="tools/detect-builtins.js") return result def Main(): parser = BuildOptions() (options, args) = parser.parse_args() if len(args) != 1 or args[0] == "help": parser.print_help() return 1 action = args[0] if action == "generate": GenerateTests(options) return 0 if action == "clear": ClearGeneratedFiles(options) return 0 print("Unknown action: %s" % action) parser.print_help() return 1 if __name__ == "__main__": sys.exit(Main()) node-v4.2.6/deps/v8/tools/generate-ten-powers.scm000644 000766 000024 00000024554 12650222326 022007 0ustar00iojsstaff000000 000000 ;; Copyright 2010 the V8 project authors. All rights reserved. ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions are ;; met: ;; ;; * Redistributions of source code must retain the above copyright ;; notice, this list of conditions and the following disclaimer. ;; * Redistributions in binary form must reproduce the above ;; copyright notice, this list of conditions and the following ;; disclaimer in the documentation and/or other materials provided ;; with the distribution. ;; * Neither the name of Google Inc. nor the names of its ;; contributors may be used to endorse or promote products derived ;; from this software without specific prior written permission. ;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ;; This is a Scheme script for the Bigloo compiler. Bigloo must be compiled with ;; support for bignums. The compilation of the script can be done as follows: ;; bigloo -static-bigloo -o generate-ten-powers generate-ten-powers.scm ;; ;; Generate approximations of 10^k. (module gen-ten-powers (static (class Cached-Fast v::bignum e::bint exact?::bool)) (main my-main)) ;;----------------bignum shifts ----------------------------------------------- (define (bit-lshbx::bignum x::bignum by::bint) (if (bignum by))))) (define (bit-rshbx::bignum x::bignum by::bint) (if (bignum by))))) ;;----------------the actual power generation ------------------------------- ;; e should be an indication. it might be too small. (define (round-n-cut n e nb-bits) (define max-container (- (bit-lshbx #z1 nb-bits) 1)) (define (round n) (case *round* ((down) n) ((up) (+bx n ;; with the -1 it will only round up if the cut off part is ;; non-zero (-bx (bit-lshbx #z1 (-fx (+fx e nb-bits) 1)) #z1))) ((round) (+bx n (bit-lshbx #z1 (-fx (+fx e nb-bits) 2)))))) (let* ((shift (-fx (+fx e nb-bits) 1)) (cut (bit-rshbx (round n) shift)) (exact? (=bx n (bit-lshbx cut shift)))) (if (<=bx cut max-container) (values cut e exact?) (round-n-cut n (+fx e 1) nb-bits)))) (define (rounded-/bx x y) (case *round* ((down) (/bx x y)) ((up) (+bx (/bx x y) #z1)) ((round) (let ((tmp (/bx (*bx #z2 x) y))) (if (zerobx? (remainderbx tmp #z2)) (/bx tmp #z2) (+bx (/bx tmp #z2) #z1)))))) (define (generate-powers from to mantissa-size) (let* ((nb-bits mantissa-size) (offset (- from)) (nb-elements (+ (- from) to 1)) (vec (make-vector nb-elements)) (max-container (- (bit-lshbx #z1 nb-bits) 1))) ;; the negative ones. 10^-1, 10^-2, etc. ;; We already know, that we can't be exact, so exact? will always be #f. ;; Basically we will have a ten^i that we will *10 at each iteration. We ;; want to create the matissa of 1/ten^i. However the mantissa must be ;; normalized (start with a 1). -> we have to shift the number. ;; We shift by multiplying with two^e. -> We encode two^e*(1/ten^i) == ;; two^e/ten^i. (let loop ((i 1) (ten^i #z10) (two^e #z1) (e 0)) (unless (< (- i) from) (if (>bx (/bx (*bx #z2 two^e) ten^i) max-container) ;; another shift would make the number too big. We are ;; hence normalized now. (begin (vector-set! vec (-fx offset i) (instantiate::Cached-Fast (v (rounded-/bx two^e ten^i)) (e (negfx e)) (exact? #f))) (loop (+fx i 1) (*bx ten^i #z10) two^e e)) (loop i ten^i (bit-lshbx two^e 1) (+fx e 1))))) ;; the positive ones 10^0, 10^1, etc. ;; start with 1.0. mantissa: 10...0 (1 followed by nb-bits-1 bits) ;; -> e = -(nb-bits-1) ;; exact? is true when the container can still hold the complete 10^i (let loop ((i 0) (n (bit-lshbx #z1 (-fx nb-bits 1))) (e (-fx 1 nb-bits))) (when (<= i to) (receive (cut e exact?) (round-n-cut n e nb-bits) (vector-set! vec (+fx i offset) (instantiate::Cached-Fast (v cut) (e e) (exact? exact?))) (loop (+fx i 1) (*bx n #z10) e)))) vec)) (define (print-c powers from to struct-type cache-name max-distance-name offset-name macro64) (define (display-power power k) (with-access::Cached-Fast power (v e exact?) (let ((tmp-p (open-output-string))) ;; really hackish way of getting the digits (display (format "~x" v) tmp-p) (let ((str (close-output-port tmp-p))) (printf " {~a(0x~a, ~a), ~a, ~a},\n" macro64 (substring str 0 8) (substring str 8 16) e k))))) (define (print-powers-reduced n) (print "static const " struct-type " " cache-name "(" n ")" "[] = {") (let loop ((i 0) (nb-elements 0) (last-e 0) (max-distance 0)) (cond ((>= i (vector-length powers)) (print " };") (print "static const int " max-distance-name "(" n ") = " max-distance ";") (print "// nb elements (" n "): " nb-elements)) (else (let* ((power (vector-ref powers i)) (e (Cached-Fast-e power))) (display-power power (+ i from)) (loop (+ i n) (+ nb-elements 1) e (cond ((=fx i 0) max-distance) ((> (- e last-e) max-distance) (- e last-e)) (else max-distance)))))))) (print "// Copyright 2010 the V8 project authors. All rights reserved.") (print "// ------------ GENERATED FILE ----------------") (print "// command used:") (print "// " (apply string-append (map (lambda (str) (string-append " " str)) *main-args*)) " // NOLINT") (print) (print "// This file is intended to be included inside another .h or .cc files\n" "// with the following defines set:\n" "// GRISU_CACHE_STRUCT: should expand to the name of a struct that will\n" "// hold the cached powers of ten. Each entry will hold a 64-bit\n" "// significand, a 16-bit signed binary exponent, and a 16-bit\n" "// signed decimal exponent. Each entry will be constructed as follows:\n" "// { significand, binary_exponent, decimal_exponent }.\n" "// GRISU_CACHE_NAME(i): generates the name for the different caches.\n" "// The parameter i will be a number in the range 1-20. A cache will\n" "// hold every i'th element of a full cache. GRISU_CACHE_NAME(1) will\n" "// thus hold all elements. The higher i the fewer elements it has.\n" "// Ideally the user should only reference one cache and let the\n" "// compiler remove the unused ones.\n" "// GRISU_CACHE_MAX_DISTANCE(i): generates the name for the maximum\n" "// binary exponent distance between all elements of a given cache.\n" "// GRISU_CACHE_OFFSET: is used as variable name for the decimal\n" "// exponent offset. It is equal to -cache[0].decimal_exponent.\n" "// GRISU_UINT64_C: used to construct 64-bit values in a platform\n" "// independent way. In order to encode 0x123456789ABCDEF0 the macro\n" "// will be invoked as follows: GRISU_UINT64_C(0x12345678,9ABCDEF0).\n") (print) (print-powers-reduced 1) (print-powers-reduced 2) (print-powers-reduced 3) (print-powers-reduced 4) (print-powers-reduced 5) (print-powers-reduced 6) (print-powers-reduced 7) (print-powers-reduced 8) (print-powers-reduced 9) (print-powers-reduced 10) (print-powers-reduced 11) (print-powers-reduced 12) (print-powers-reduced 13) (print-powers-reduced 14) (print-powers-reduced 15) (print-powers-reduced 16) (print-powers-reduced 17) (print-powers-reduced 18) (print-powers-reduced 19) (print-powers-reduced 20) (print "static const int GRISU_CACHE_OFFSET = " (- from) ";")) ;;----------------main -------------------------------------------------------- (define *main-args* #f) (define *mantissa-size* #f) (define *dest* #f) (define *round* #f) (define *from* #f) (define *to* #f) (define (my-main args) (set! *main-args* args) (args-parse (cdr args) (section "Help") (("?") (args-parse-usage #f)) ((("-h" "--help") (help "?, -h, --help" "This help message")) (args-parse-usage #f)) (section "Misc") (("-o" ?file (help "The output file")) (set! *dest* file)) (("--mantissa-size" ?size (help "Container-size in bits")) (set! *mantissa-size* (string->number size))) (("--round" ?direction (help "Round bignums (down, round or up)")) (set! *round* (string->symbol direction))) (("--from" ?from (help "start at 10^from")) (set! *from* (string->number from))) (("--to" ?to (help "go up to 10^to")) (set! *to* (string->number to))) (else (print "Illegal argument `" else "'. Usage:") (args-parse-usage #f))) (when (not *from*) (error "generate-ten-powers" "Missing from" #f)) (when (not *to*) (error "generate-ten-powers" "Missing to" #f)) (when (not *mantissa-size*) (error "generate-ten-powers" "Missing mantissa size" #f)) (when (not (memv *round* '(up down round))) (error "generate-ten-powers" "Missing round-method" *round*)) (let ((dividers (generate-powers *from* *to* *mantissa-size*)) (p (if (not *dest*) (current-output-port) (open-output-file *dest*)))) (unwind-protect (with-output-to-port p (lambda () (print-c dividers *from* *to* "GRISU_CACHE_STRUCT" "GRISU_CACHE_NAME" "GRISU_CACHE_MAX_DISTANCE" "GRISU_CACHE_OFFSET" "GRISU_UINT64_C" ))) (if *dest* (close-output-port p))))) node-v4.2.6/deps/v8/tools/generate_shim_headers/000755 000766 000024 00000000000 12650222326 021703 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/grokdump.py000755 000766 000024 00000335511 12650222326 017613 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import BaseHTTPServer import bisect import cgi import cmd import codecs import ctypes import datetime import disasm import mmap import optparse import os import re import sys import types import urllib import urlparse import v8heapconst import webbrowser PORT_NUMBER = 8081 USAGE="""usage: %prog [OPTIONS] [DUMP-FILE] Minidump analyzer. Shows the processor state at the point of exception including the stack of the active thread and the referenced objects in the V8 heap. Code objects are disassembled and the addresses linked from the stack (e.g. pushed return addresses) are marked with "=>". Examples: $ %prog 12345678-1234-1234-1234-123456789abcd-full.dmp""" DEBUG=False def DebugPrint(s): if not DEBUG: return print s class Descriptor(object): """Descriptor of a structure in a memory.""" def __init__(self, fields): self.fields = fields self.is_flexible = False for _, type_or_func in fields: if isinstance(type_or_func, types.FunctionType): self.is_flexible = True break if not self.is_flexible: self.ctype = Descriptor._GetCtype(fields) self.size = ctypes.sizeof(self.ctype) def Read(self, memory, offset): if self.is_flexible: fields_copy = self.fields[:] last = 0 for name, type_or_func in fields_copy: if isinstance(type_or_func, types.FunctionType): partial_ctype = Descriptor._GetCtype(fields_copy[:last]) partial_object = partial_ctype.from_buffer(memory, offset) type = type_or_func(partial_object) if type is not None: fields_copy[last] = (name, type) last += 1 else: last += 1 complete_ctype = Descriptor._GetCtype(fields_copy[:last]) else: complete_ctype = self.ctype return complete_ctype.from_buffer(memory, offset) @staticmethod def _GetCtype(fields): class Raw(ctypes.Structure): _fields_ = fields _pack_ = 1 def __str__(self): return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field)) for field, _ in Raw._fields_) + "}" return Raw def FullDump(reader, heap): """Dump all available memory regions.""" def dump_region(reader, start, size, location): print while start & 3 != 0: start += 1 size -= 1 location += 1 is_executable = reader.IsProbableExecutableRegion(location, size) is_ascii = reader.IsProbableASCIIRegion(location, size) if is_executable is not False: lines = reader.GetDisasmLines(start, size) for line in lines: print FormatDisasmLine(start, heap, line) print if is_ascii is not False: # Output in the same format as the Unix hd command addr = start for i in xrange(0, size, 16): slot = i + location hex_line = "" asc_line = "" for i in xrange(16): if slot + i < location + size: byte = ctypes.c_uint8.from_buffer(reader.minidump, slot + i).value if byte >= 0x20 and byte < 0x7f: asc_line += chr(byte) else: asc_line += "." hex_line += " %02x" % (byte) else: hex_line += " " if i == 7: hex_line += " " print "%s %s |%s|" % (reader.FormatIntPtr(addr), hex_line, asc_line) addr += 16 if is_executable is not True and is_ascii is not True: print "%s - %s" % (reader.FormatIntPtr(start), reader.FormatIntPtr(start + size)) print start + size + 1; for i in xrange(0, size, reader.PointerSize()): slot = start + i maybe_address = reader.ReadUIntPtr(slot) heap_object = heap.FindObject(maybe_address) print "%s: %s" % (reader.FormatIntPtr(slot), reader.FormatIntPtr(maybe_address)) if heap_object: heap_object.Print(Printer()) print reader.ForEachMemoryRegion(dump_region) # Heap constants generated by 'make grokdump' in v8heapconst module. INSTANCE_TYPES = v8heapconst.INSTANCE_TYPES KNOWN_MAPS = v8heapconst.KNOWN_MAPS KNOWN_OBJECTS = v8heapconst.KNOWN_OBJECTS # Set of structures and constants that describe the layout of minidump # files. Based on MSDN and Google Breakpad. MINIDUMP_HEADER = Descriptor([ ("signature", ctypes.c_uint32), ("version", ctypes.c_uint32), ("stream_count", ctypes.c_uint32), ("stream_directories_rva", ctypes.c_uint32), ("checksum", ctypes.c_uint32), ("time_date_stampt", ctypes.c_uint32), ("flags", ctypes.c_uint64) ]) MINIDUMP_LOCATION_DESCRIPTOR = Descriptor([ ("data_size", ctypes.c_uint32), ("rva", ctypes.c_uint32) ]) MINIDUMP_STRING = Descriptor([ ("length", ctypes.c_uint32), ("buffer", lambda t: ctypes.c_uint8 * (t.length + 2)) ]) MINIDUMP_DIRECTORY = Descriptor([ ("stream_type", ctypes.c_uint32), ("location", MINIDUMP_LOCATION_DESCRIPTOR.ctype) ]) MD_EXCEPTION_MAXIMUM_PARAMETERS = 15 MINIDUMP_EXCEPTION = Descriptor([ ("code", ctypes.c_uint32), ("flags", ctypes.c_uint32), ("record", ctypes.c_uint64), ("address", ctypes.c_uint64), ("parameter_count", ctypes.c_uint32), ("unused_alignment", ctypes.c_uint32), ("information", ctypes.c_uint64 * MD_EXCEPTION_MAXIMUM_PARAMETERS) ]) MINIDUMP_EXCEPTION_STREAM = Descriptor([ ("thread_id", ctypes.c_uint32), ("unused_alignment", ctypes.c_uint32), ("exception", MINIDUMP_EXCEPTION.ctype), ("thread_context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) ]) # Stream types. MD_UNUSED_STREAM = 0 MD_RESERVED_STREAM_0 = 1 MD_RESERVED_STREAM_1 = 2 MD_THREAD_LIST_STREAM = 3 MD_MODULE_LIST_STREAM = 4 MD_MEMORY_LIST_STREAM = 5 MD_EXCEPTION_STREAM = 6 MD_SYSTEM_INFO_STREAM = 7 MD_THREAD_EX_LIST_STREAM = 8 MD_MEMORY_64_LIST_STREAM = 9 MD_COMMENT_STREAM_A = 10 MD_COMMENT_STREAM_W = 11 MD_HANDLE_DATA_STREAM = 12 MD_FUNCTION_TABLE_STREAM = 13 MD_UNLOADED_MODULE_LIST_STREAM = 14 MD_MISC_INFO_STREAM = 15 MD_MEMORY_INFO_LIST_STREAM = 16 MD_THREAD_INFO_LIST_STREAM = 17 MD_HANDLE_OPERATION_LIST_STREAM = 18 MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE = 80 MINIDUMP_FLOATING_SAVE_AREA_X86 = Descriptor([ ("control_word", ctypes.c_uint32), ("status_word", ctypes.c_uint32), ("tag_word", ctypes.c_uint32), ("error_offset", ctypes.c_uint32), ("error_selector", ctypes.c_uint32), ("data_offset", ctypes.c_uint32), ("data_selector", ctypes.c_uint32), ("register_area", ctypes.c_uint8 * MD_FLOATINGSAVEAREA_X86_REGISTERAREA_SIZE), ("cr0_npx_state", ctypes.c_uint32) ]) MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE = 512 # Context flags. MD_CONTEXT_X86 = 0x00010000 MD_CONTEXT_X86_CONTROL = (MD_CONTEXT_X86 | 0x00000001) MD_CONTEXT_X86_INTEGER = (MD_CONTEXT_X86 | 0x00000002) MD_CONTEXT_X86_SEGMENTS = (MD_CONTEXT_X86 | 0x00000004) MD_CONTEXT_X86_FLOATING_POINT = (MD_CONTEXT_X86 | 0x00000008) MD_CONTEXT_X86_DEBUG_REGISTERS = (MD_CONTEXT_X86 | 0x00000010) MD_CONTEXT_X86_EXTENDED_REGISTERS = (MD_CONTEXT_X86 | 0x00000020) def EnableOnFlag(type, flag): return lambda o: [None, type][int((o.context_flags & flag) != 0)] MINIDUMP_CONTEXT_X86 = Descriptor([ ("context_flags", ctypes.c_uint32), # MD_CONTEXT_X86_DEBUG_REGISTERS. ("dr0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), ("dr1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), ("dr2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), ("dr3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), ("dr6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), ("dr7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_DEBUG_REGISTERS)), # MD_CONTEXT_X86_FLOATING_POINT. ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_X86.ctype, MD_CONTEXT_X86_FLOATING_POINT)), # MD_CONTEXT_X86_SEGMENTS. ("gs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), ("fs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), ("es", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), ("ds", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_SEGMENTS)), # MD_CONTEXT_X86_INTEGER. ("edi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), ("esi", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), ("ebx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), ("edx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), ("ecx", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), ("eax", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_INTEGER)), # MD_CONTEXT_X86_CONTROL. ("ebp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), ("eip", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), # MD_CONTEXT_X86_EXTENDED_REGISTERS. ("extended_registers", EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE, MD_CONTEXT_X86_EXTENDED_REGISTERS)) ]) MD_CONTEXT_ARM = 0x40000000 MD_CONTEXT_ARM_INTEGER = (MD_CONTEXT_ARM | 0x00000002) MD_CONTEXT_ARM_FLOATING_POINT = (MD_CONTEXT_ARM | 0x00000004) MD_FLOATINGSAVEAREA_ARM_FPR_COUNT = 32 MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT = 8 MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([ ("fpscr", ctypes.c_uint64), ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPR_COUNT), ("extra", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT) ]) MINIDUMP_CONTEXT_ARM = Descriptor([ ("context_flags", ctypes.c_uint32), # MD_CONTEXT_ARM_INTEGER. ("r0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r4", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r5", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r8", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r9", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r10", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r11", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("r12", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("sp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("lr", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("pc", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), ("cpsr", ctypes.c_uint32), ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype, MD_CONTEXT_ARM_FLOATING_POINT)) ]) MD_CONTEXT_ARM64 = 0x80000000 MD_CONTEXT_ARM64_INTEGER = (MD_CONTEXT_ARM64 | 0x00000002) MD_CONTEXT_ARM64_FLOATING_POINT = (MD_CONTEXT_ARM64 | 0x00000004) MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT = 64 MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([ ("fpscr", ctypes.c_uint64), ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM64_FPR_COUNT), ]) MINIDUMP_CONTEXT_ARM64 = Descriptor([ ("context_flags", ctypes.c_uint64), # MD_CONTEXT_ARM64_INTEGER. ("r0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r4", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r5", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r16", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r17", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r18", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r19", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r20", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r21", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r22", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r23", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r24", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r25", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r26", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r27", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("r28", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("fp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("lr", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("sp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("pc", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_ARM64_INTEGER)), ("cpsr", ctypes.c_uint32), ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype, MD_CONTEXT_ARM64_FLOATING_POINT)) ]) MD_CONTEXT_AMD64 = 0x00100000 MD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001) MD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002) MD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004) MD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008) MD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010) MINIDUMP_CONTEXT_AMD64 = Descriptor([ ("p1_home", ctypes.c_uint64), ("p2_home", ctypes.c_uint64), ("p3_home", ctypes.c_uint64), ("p4_home", ctypes.c_uint64), ("p5_home", ctypes.c_uint64), ("p6_home", ctypes.c_uint64), ("context_flags", ctypes.c_uint32), ("mx_csr", ctypes.c_uint32), # MD_CONTEXT_AMD64_CONTROL. ("cs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), # MD_CONTEXT_AMD64_SEGMENTS ("ds", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), ("es", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), ("fs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), ("gs", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_SEGMENTS)), # MD_CONTEXT_AMD64_CONTROL. ("ss", EnableOnFlag(ctypes.c_uint16, MD_CONTEXT_AMD64_CONTROL)), ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_AMD64_CONTROL)), # MD_CONTEXT_AMD64_DEBUG_REGISTERS. ("dr0", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("dr1", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("dr2", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("dr3", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("dr6", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("dr7", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), # MD_CONTEXT_AMD64_INTEGER. ("rax", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("rcx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("rdx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("rbx", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), # MD_CONTEXT_AMD64_CONTROL. ("rsp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), # MD_CONTEXT_AMD64_INTEGER. ("rbp", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("rsi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("rdi", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r8", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r9", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r10", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r11", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r12", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r13", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r14", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), ("r15", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_INTEGER)), # MD_CONTEXT_AMD64_CONTROL. ("rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_CONTROL)), # MD_CONTEXT_AMD64_FLOATING_POINT ("sse_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), MD_CONTEXT_AMD64_FLOATING_POINT)), ("vector_registers", EnableOnFlag(ctypes.c_uint8 * (16 * 26), MD_CONTEXT_AMD64_FLOATING_POINT)), ("vector_control", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_FLOATING_POINT)), # MD_CONTEXT_AMD64_DEBUG_REGISTERS. ("debug_control", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("last_branch_to_rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("last_branch_from_rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("last_exception_to_rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)), ("last_exception_from_rip", EnableOnFlag(ctypes.c_uint64, MD_CONTEXT_AMD64_DEBUG_REGISTERS)) ]) MINIDUMP_MEMORY_DESCRIPTOR = Descriptor([ ("start", ctypes.c_uint64), ("memory", MINIDUMP_LOCATION_DESCRIPTOR.ctype) ]) MINIDUMP_MEMORY_DESCRIPTOR64 = Descriptor([ ("start", ctypes.c_uint64), ("size", ctypes.c_uint64) ]) MINIDUMP_MEMORY_LIST = Descriptor([ ("range_count", ctypes.c_uint32), ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count) ]) MINIDUMP_MEMORY_LIST_Mac = Descriptor([ ("range_count", ctypes.c_uint32), ("junk", ctypes.c_uint32), ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR.ctype * m.range_count) ]) MINIDUMP_MEMORY_LIST64 = Descriptor([ ("range_count", ctypes.c_uint64), ("base_rva", ctypes.c_uint64), ("ranges", lambda m: MINIDUMP_MEMORY_DESCRIPTOR64.ctype * m.range_count) ]) MINIDUMP_THREAD = Descriptor([ ("id", ctypes.c_uint32), ("suspend_count", ctypes.c_uint32), ("priority_class", ctypes.c_uint32), ("priority", ctypes.c_uint32), ("ted", ctypes.c_uint64), ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype), ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) ]) MINIDUMP_THREAD_LIST = Descriptor([ ("thread_count", ctypes.c_uint32), ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) ]) MINIDUMP_THREAD_LIST_Mac = Descriptor([ ("thread_count", ctypes.c_uint32), ("junk", ctypes.c_uint32), ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) ]) MINIDUMP_VS_FIXEDFILEINFO = Descriptor([ ("dwSignature", ctypes.c_uint32), ("dwStrucVersion", ctypes.c_uint32), ("dwFileVersionMS", ctypes.c_uint32), ("dwFileVersionLS", ctypes.c_uint32), ("dwProductVersionMS", ctypes.c_uint32), ("dwProductVersionLS", ctypes.c_uint32), ("dwFileFlagsMask", ctypes.c_uint32), ("dwFileFlags", ctypes.c_uint32), ("dwFileOS", ctypes.c_uint32), ("dwFileType", ctypes.c_uint32), ("dwFileSubtype", ctypes.c_uint32), ("dwFileDateMS", ctypes.c_uint32), ("dwFileDateLS", ctypes.c_uint32) ]) MINIDUMP_RAW_MODULE = Descriptor([ ("base_of_image", ctypes.c_uint64), ("size_of_image", ctypes.c_uint32), ("checksum", ctypes.c_uint32), ("time_date_stamp", ctypes.c_uint32), ("module_name_rva", ctypes.c_uint32), ("version_info", MINIDUMP_VS_FIXEDFILEINFO.ctype), ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), ("reserved0", ctypes.c_uint32 * 2), ("reserved1", ctypes.c_uint32 * 2) ]) MINIDUMP_MODULE_LIST = Descriptor([ ("number_of_modules", ctypes.c_uint32), ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) ]) MINIDUMP_MODULE_LIST_Mac = Descriptor([ ("number_of_modules", ctypes.c_uint32), ("junk", ctypes.c_uint32), ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) ]) MINIDUMP_RAW_SYSTEM_INFO = Descriptor([ ("processor_architecture", ctypes.c_uint16) ]) MD_CPU_ARCHITECTURE_X86 = 0 MD_CPU_ARCHITECTURE_ARM = 5 MD_CPU_ARCHITECTURE_ARM64 = 0x8003 MD_CPU_ARCHITECTURE_AMD64 = 9 class FuncSymbol: def __init__(self, start, size, name): self.start = start self.end = self.start + size self.name = name def __cmp__(self, other): if isinstance(other, FuncSymbol): return self.start - other.start return self.start - other def Covers(self, addr): return (self.start <= addr) and (addr < self.end) class MinidumpReader(object): """Minidump (.dmp) reader.""" _HEADER_MAGIC = 0x504d444d def __init__(self, options, minidump_name): self.minidump_name = minidump_name self.minidump_file = open(minidump_name, "r") self.minidump = mmap.mmap(self.minidump_file.fileno(), 0, mmap.MAP_PRIVATE) self.header = MINIDUMP_HEADER.Read(self.minidump, 0) if self.header.signature != MinidumpReader._HEADER_MAGIC: print >>sys.stderr, "Warning: Unsupported minidump header magic!" DebugPrint(self.header) directories = [] offset = self.header.stream_directories_rva for _ in xrange(self.header.stream_count): directories.append(MINIDUMP_DIRECTORY.Read(self.minidump, offset)) offset += MINIDUMP_DIRECTORY.size self.arch = None self.exception = None self.exception_context = None self.memory_list = None self.memory_list64 = None self.module_list = None self.thread_map = {} self.symdir = options.symdir self.modules_with_symbols = [] self.symbols = [] # Find MDRawSystemInfo stream and determine arch. for d in directories: if d.stream_type == MD_SYSTEM_INFO_STREAM: system_info = MINIDUMP_RAW_SYSTEM_INFO.Read( self.minidump, d.location.rva) self.arch = system_info.processor_architecture assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64, MD_CPU_ARCHITECTURE_X86] assert not self.arch is None for d in directories: DebugPrint(d) if d.stream_type == MD_EXCEPTION_STREAM: self.exception = MINIDUMP_EXCEPTION_STREAM.Read( self.minidump, d.location.rva) DebugPrint(self.exception) if self.arch == MD_CPU_ARCHITECTURE_X86: self.exception_context = MINIDUMP_CONTEXT_X86.Read( self.minidump, self.exception.thread_context.rva) elif self.arch == MD_CPU_ARCHITECTURE_AMD64: self.exception_context = MINIDUMP_CONTEXT_AMD64.Read( self.minidump, self.exception.thread_context.rva) elif self.arch == MD_CPU_ARCHITECTURE_ARM: self.exception_context = MINIDUMP_CONTEXT_ARM.Read( self.minidump, self.exception.thread_context.rva) elif self.arch == MD_CPU_ARCHITECTURE_ARM64: self.exception_context = MINIDUMP_CONTEXT_ARM64.Read( self.minidump, self.exception.thread_context.rva) DebugPrint(self.exception_context) elif d.stream_type == MD_THREAD_LIST_STREAM: thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva) if ctypes.sizeof(thread_list) + 4 == d.location.data_size: thread_list = MINIDUMP_THREAD_LIST_Mac.Read( self.minidump, d.location.rva) assert ctypes.sizeof(thread_list) == d.location.data_size DebugPrint(thread_list) for thread in thread_list.threads: DebugPrint(thread) self.thread_map[thread.id] = thread elif d.stream_type == MD_MODULE_LIST_STREAM: assert self.module_list is None self.module_list = MINIDUMP_MODULE_LIST.Read( self.minidump, d.location.rva) if ctypes.sizeof(self.module_list) + 4 == d.location.data_size: self.module_list = MINIDUMP_MODULE_LIST_Mac.Read( self.minidump, d.location.rva) assert ctypes.sizeof(self.module_list) == d.location.data_size DebugPrint(self.module_list) elif d.stream_type == MD_MEMORY_LIST_STREAM: print >>sys.stderr, "Warning: This is not a full minidump!" assert self.memory_list is None self.memory_list = MINIDUMP_MEMORY_LIST.Read( self.minidump, d.location.rva) if ctypes.sizeof(self.memory_list) + 4 == d.location.data_size: self.memory_list = MINIDUMP_MEMORY_LIST_Mac.Read( self.minidump, d.location.rva) assert ctypes.sizeof(self.memory_list) == d.location.data_size DebugPrint(self.memory_list) elif d.stream_type == MD_MEMORY_64_LIST_STREAM: assert self.memory_list64 is None self.memory_list64 = MINIDUMP_MEMORY_LIST64.Read( self.minidump, d.location.rva) assert ctypes.sizeof(self.memory_list64) == d.location.data_size DebugPrint(self.memory_list64) def IsValidAddress(self, address): return self.FindLocation(address) is not None def ReadU8(self, address): location = self.FindLocation(address) return ctypes.c_uint8.from_buffer(self.minidump, location).value def ReadU32(self, address): location = self.FindLocation(address) return ctypes.c_uint32.from_buffer(self.minidump, location).value def ReadU64(self, address): location = self.FindLocation(address) return ctypes.c_uint64.from_buffer(self.minidump, location).value def ReadUIntPtr(self, address): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return self.ReadU64(address) elif self.arch == MD_CPU_ARCHITECTURE_ARM: return self.ReadU32(address) elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return self.ReadU64(address) elif self.arch == MD_CPU_ARCHITECTURE_X86: return self.ReadU32(address) def ReadBytes(self, address, size): location = self.FindLocation(address) return self.minidump[location:location + size] def _ReadWord(self, location): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return ctypes.c_uint64.from_buffer(self.minidump, location).value elif self.arch == MD_CPU_ARCHITECTURE_ARM: return ctypes.c_uint32.from_buffer(self.minidump, location).value elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return ctypes.c_uint64.from_buffer(self.minidump, location).value elif self.arch == MD_CPU_ARCHITECTURE_X86: return ctypes.c_uint32.from_buffer(self.minidump, location).value def IsProbableASCIIRegion(self, location, length): ascii_bytes = 0 non_ascii_bytes = 0 for i in xrange(length): loc = location + i byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value if byte >= 0x7f: non_ascii_bytes += 1 if byte < 0x20 and byte != 0: non_ascii_bytes += 1 if byte < 0x7f and byte >= 0x20: ascii_bytes += 1 if byte == 0xa: # newline ascii_bytes += 1 if ascii_bytes * 10 <= length: return False if length > 0 and ascii_bytes > non_ascii_bytes * 7: return True if ascii_bytes > non_ascii_bytes * 3: return None # Maybe return False def IsProbableExecutableRegion(self, location, length): opcode_bytes = 0 sixty_four = self.arch == MD_CPU_ARCHITECTURE_AMD64 for i in xrange(length): loc = location + i byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value if (byte == 0x8b or # mov byte == 0x89 or # mov reg-reg (byte & 0xf0) == 0x50 or # push/pop (sixty_four and (byte & 0xf0) == 0x40) or # rex prefix byte == 0xc3 or # return byte == 0x74 or # jeq byte == 0x84 or # jeq far byte == 0x75 or # jne byte == 0x85 or # jne far byte == 0xe8 or # call byte == 0xe9 or # jmp far byte == 0xeb): # jmp near opcode_bytes += 1 opcode_percent = (opcode_bytes * 100) / length threshold = 20 if opcode_percent > threshold + 2: return True if opcode_percent > threshold - 2: return None # Maybe return False def FindRegion(self, addr): answer = [-1, -1] def is_in(reader, start, size, location): if addr >= start and addr < start + size: answer[0] = start answer[1] = size self.ForEachMemoryRegion(is_in) if answer[0] == -1: return None return answer def ForEachMemoryRegion(self, cb): if self.memory_list64 is not None: for r in self.memory_list64.ranges: location = self.memory_list64.base_rva + offset cb(self, r.start, r.size, location) offset += r.size if self.memory_list is not None: for r in self.memory_list.ranges: cb(self, r.start, r.memory.data_size, r.memory.rva) def FindWord(self, word, alignment=0): def search_inside_region(reader, start, size, location): location = (location + alignment) & ~alignment for i in xrange(size - self.PointerSize()): loc = location + i if reader._ReadWord(loc) == word: slot = start + (loc - location) print "%s: %s" % (reader.FormatIntPtr(slot), reader.FormatIntPtr(word)) self.ForEachMemoryRegion(search_inside_region) def FindWordList(self, word): aligned_res = [] unaligned_res = [] def search_inside_region(reader, start, size, location): for i in xrange(size - self.PointerSize()): loc = location + i if reader._ReadWord(loc) == word: slot = start + (loc - location) if slot % self.PointerSize() == 0: aligned_res.append(slot) else: unaligned_res.append(slot) self.ForEachMemoryRegion(search_inside_region) return (aligned_res, unaligned_res) def FindLocation(self, address): offset = 0 if self.memory_list64 is not None: for r in self.memory_list64.ranges: if r.start <= address < r.start + r.size: return self.memory_list64.base_rva + offset + address - r.start offset += r.size if self.memory_list is not None: for r in self.memory_list.ranges: if r.start <= address < r.start + r.memory.data_size: return r.memory.rva + address - r.start return None def GetDisasmLines(self, address, size): def CountUndefinedInstructions(lines): pattern = "" return sum([line.count(pattern) for (ignore, line) in lines]) location = self.FindLocation(address) if location is None: return [] arch = None possible_objdump_flags = [""] if self.arch == MD_CPU_ARCHITECTURE_X86: arch = "ia32" elif self.arch == MD_CPU_ARCHITECTURE_ARM: arch = "arm" possible_objdump_flags = ["", "--disassembler-options=force-thumb"] elif self.arch == MD_CPU_ARCHITECTURE_ARM64: arch = "arm64" possible_objdump_flags = ["", "--disassembler-options=force-thumb"] elif self.arch == MD_CPU_ARCHITECTURE_AMD64: arch = "x64" results = [ disasm.GetDisasmLines(self.minidump_name, location, size, arch, False, objdump_flags) for objdump_flags in possible_objdump_flags ] return min(results, key=CountUndefinedInstructions) def Dispose(self): self.minidump.close() self.minidump_file.close() def ExceptionIP(self): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return self.exception_context.rip elif self.arch == MD_CPU_ARCHITECTURE_ARM: return self.exception_context.pc elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return self.exception_context.pc elif self.arch == MD_CPU_ARCHITECTURE_X86: return self.exception_context.eip def ExceptionSP(self): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return self.exception_context.rsp elif self.arch == MD_CPU_ARCHITECTURE_ARM: return self.exception_context.sp elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return self.exception_context.sp elif self.arch == MD_CPU_ARCHITECTURE_X86: return self.exception_context.esp def ExceptionFP(self): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return self.exception_context.rbp elif self.arch == MD_CPU_ARCHITECTURE_ARM: return None elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return self.exception_context.fp elif self.arch == MD_CPU_ARCHITECTURE_X86: return self.exception_context.ebp def FormatIntPtr(self, value): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return "%016x" % value elif self.arch == MD_CPU_ARCHITECTURE_ARM: return "%08x" % value elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return "%016x" % value elif self.arch == MD_CPU_ARCHITECTURE_X86: return "%08x" % value def PointerSize(self): if self.arch == MD_CPU_ARCHITECTURE_AMD64: return 8 elif self.arch == MD_CPU_ARCHITECTURE_ARM: return 4 elif self.arch == MD_CPU_ARCHITECTURE_ARM64: return 8 elif self.arch == MD_CPU_ARCHITECTURE_X86: return 4 def Register(self, name): return self.exception_context.__getattribute__(name) def ReadMinidumpString(self, rva): string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer) string = string.decode("utf16") return string[0:len(string) - 1] # Load FUNC records from a BreakPad symbol file # # http://code.google.com/p/google-breakpad/wiki/SymbolFiles # def _LoadSymbolsFrom(self, symfile, baseaddr): print "Loading symbols from %s" % (symfile) funcs = [] with open(symfile) as f: for line in f: result = re.match( r"^FUNC ([a-f0-9]+) ([a-f0-9]+) ([a-f0-9]+) (.*)$", line) if result is not None: start = int(result.group(1), 16) size = int(result.group(2), 16) name = result.group(4).rstrip() bisect.insort_left(self.symbols, FuncSymbol(baseaddr + start, size, name)) print " ... done" def TryLoadSymbolsFor(self, modulename, module): try: symfile = os.path.join(self.symdir, modulename.replace('.', '_') + ".pdb.sym") if os.path.isfile(symfile): self._LoadSymbolsFrom(symfile, module.base_of_image) self.modules_with_symbols.append(module) except Exception as e: print " ... failure (%s)" % (e) # Returns true if address is covered by some module that has loaded symbols. def _IsInModuleWithSymbols(self, addr): for module in self.modules_with_symbols: start = module.base_of_image end = start + module.size_of_image if (start <= addr) and (addr < end): return True return False # Find symbol covering the given address and return its name in format # + def FindSymbol(self, addr): if not self._IsInModuleWithSymbols(addr): return None i = bisect.bisect_left(self.symbols, addr) symbol = None if (0 < i) and self.symbols[i - 1].Covers(addr): symbol = self.symbols[i - 1] elif (i < len(self.symbols)) and self.symbols[i].Covers(addr): symbol = self.symbols[i] else: return None diff = addr - symbol.start return "%s+0x%x" % (symbol.name, diff) class Printer(object): """Printer with indentation support.""" def __init__(self): self.indent = 0 def Indent(self): self.indent += 2 def Dedent(self): self.indent -= 2 def Print(self, string): print "%s%s" % (self._IndentString(), string) def PrintLines(self, lines): indent = self._IndentString() print "\n".join("%s%s" % (indent, line) for line in lines) def _IndentString(self): return self.indent * " " ADDRESS_RE = re.compile(r"0x[0-9a-fA-F]+") def FormatDisasmLine(start, heap, line): line_address = start + line[0] stack_slot = heap.stack_map.get(line_address) marker = " " if stack_slot: marker = "=>" code = AnnotateAddresses(heap, line[1]) # Compute the actual call target which the disassembler is too stupid # to figure out (it adds the call offset to the disassembly offset rather # than the absolute instruction address). if heap.reader.arch == MD_CPU_ARCHITECTURE_X86: if code.startswith("e8"): words = code.split() if len(words) > 6 and words[5] == "call": offset = int(words[4] + words[3] + words[2] + words[1], 16) target = (line_address + offset + 5) & 0xFFFFFFFF code = code.replace(words[6], "0x%08x" % target) # TODO(jkummerow): port this hack to ARM and x64. return "%s%08x %08x: %s" % (marker, line_address, line[0], code) def AnnotateAddresses(heap, line): extra = [] for m in ADDRESS_RE.finditer(line): maybe_address = int(m.group(0), 16) object = heap.FindObject(maybe_address) if not object: continue extra.append(str(object)) if len(extra) == 0: return line return "%s ;; %s" % (line, ", ".join(extra)) class HeapObject(object): def __init__(self, heap, map, address): self.heap = heap self.map = map self.address = address def Is(self, cls): return isinstance(self, cls) def Print(self, p): p.Print(str(self)) def __str__(self): instance_type = "???" if self.map is not None: instance_type = INSTANCE_TYPES[self.map.instance_type] return "HeapObject(%s, %s)" % (self.heap.reader.FormatIntPtr(self.address), instance_type) def ObjectField(self, offset): field_value = self.heap.reader.ReadUIntPtr(self.address + offset) return self.heap.FindObjectOrSmi(field_value) def SmiField(self, offset): field_value = self.heap.reader.ReadUIntPtr(self.address + offset) if (field_value & 1) == 0: return field_value / 2 return None class Map(HeapObject): def Decode(self, offset, size, value): return (value >> offset) & ((1 << size) - 1) # Instance Sizes def InstanceSizesOffset(self): return self.heap.PointerSize() def InstanceSizeOffset(self): return self.InstanceSizesOffset() def InObjectProperties(self): return self.InstanceSizeOffset() + 1 def PreAllocatedPropertyFields(self): return self.InObjectProperties() + 1 def VisitorId(self): return self.PreAllocatedPropertyFields() + 1 # Instance Attributes def InstanceAttributesOffset(self): return self.InstanceSizesOffset() + self.heap.IntSize() def InstanceTypeOffset(self): return self.InstanceAttributesOffset() def UnusedPropertyFieldsOffset(self): return self.InstanceTypeOffset() + 1 def BitFieldOffset(self): return self.UnusedPropertyFieldsOffset() + 1 def BitField2Offset(self): return self.BitFieldOffset() + 1 # Other fields def PrototypeOffset(self): return self.InstanceAttributesOffset() + self.heap.IntSize() def ConstructorOffset(self): return self.PrototypeOffset() + self.heap.PointerSize() def TransitionsOrBackPointerOffset(self): return self.ConstructorOffset() + self.heap.PointerSize() def DescriptorsOffset(self): return self.TransitionsOrBackPointerOffset() + self.heap.PointerSize() def CodeCacheOffset(self): return self.DescriptorsOffset() + self.heap.PointerSize() def DependentCodeOffset(self): return self.CodeCacheOffset() + self.heap.PointerSize() def BitField3Offset(self): return self.DependentCodeOffset() + self.heap.PointerSize() def ReadByte(self, offset): return self.heap.reader.ReadU8(self.address + offset) def Print(self, p): p.Print("Map(%08x)" % (self.address)) p.Print("- size: %d, inobject: %d, preallocated: %d, visitor: %d" % ( self.ReadByte(self.InstanceSizeOffset()), self.ReadByte(self.InObjectProperties()), self.ReadByte(self.PreAllocatedPropertyFields()), self.VisitorId())) bitfield = self.ReadByte(self.BitFieldOffset()) bitfield2 = self.ReadByte(self.BitField2Offset()) p.Print("- %s, unused: %d, bf: %d, bf2: %d" % ( INSTANCE_TYPES[self.ReadByte(self.InstanceTypeOffset())], self.ReadByte(self.UnusedPropertyFieldsOffset()), bitfield, bitfield2)) p.Print("- kind: %s" % (self.Decode(3, 5, bitfield2))) bitfield3 = self.ObjectField(self.BitField3Offset()) p.Print( "- EnumLength: %d NumberOfOwnDescriptors: %d OwnsDescriptors: %s" % ( self.Decode(0, 11, bitfield3), self.Decode(11, 11, bitfield3), self.Decode(25, 1, bitfield3))) p.Print("- IsShared: %s" % (self.Decode(22, 1, bitfield3))) p.Print("- FunctionWithPrototype: %s" % (self.Decode(23, 1, bitfield3))) p.Print("- DictionaryMap: %s" % (self.Decode(24, 1, bitfield3))) descriptors = self.ObjectField(self.DescriptorsOffset()) if descriptors.__class__ == FixedArray: DescriptorArray(descriptors).Print(p) else: p.Print("Descriptors: %s" % (descriptors)) transitions = self.ObjectField(self.TransitionsOrBackPointerOffset()) if transitions.__class__ == FixedArray: TransitionArray(transitions).Print(p) else: p.Print("TransitionsOrBackPointer: %s" % (transitions)) def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.instance_type = \ heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) class String(HeapObject): def LengthOffset(self): # First word after the map is the hash, the second is the length. return self.heap.PointerSize() * 2 def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.length = self.SmiField(self.LengthOffset()) def GetChars(self): return "?string?" def Print(self, p): p.Print(str(self)) def __str__(self): return "\"%s\"" % self.GetChars() class SeqString(String): def CharsOffset(self): return self.heap.PointerSize() * 3 def __init__(self, heap, map, address): String.__init__(self, heap, map, address) self.chars = heap.reader.ReadBytes(self.address + self.CharsOffset(), self.length) def GetChars(self): return self.chars class ExternalString(String): # TODO(vegorov) fix ExternalString for X64 architecture RESOURCE_OFFSET = 12 WEBKIT_RESOUCE_STRING_IMPL_OFFSET = 4 WEBKIT_STRING_IMPL_CHARS_OFFSET = 8 def __init__(self, heap, map, address): String.__init__(self, heap, map, address) reader = heap.reader self.resource = \ reader.ReadU32(self.address + ExternalString.RESOURCE_OFFSET) self.chars = "?external string?" if not reader.IsValidAddress(self.resource): return string_impl_address = self.resource + \ ExternalString.WEBKIT_RESOUCE_STRING_IMPL_OFFSET if not reader.IsValidAddress(string_impl_address): return string_impl = reader.ReadU32(string_impl_address) chars_ptr_address = string_impl + \ ExternalString.WEBKIT_STRING_IMPL_CHARS_OFFSET if not reader.IsValidAddress(chars_ptr_address): return chars_ptr = reader.ReadU32(chars_ptr_address) if not reader.IsValidAddress(chars_ptr): return raw_chars = reader.ReadBytes(chars_ptr, 2 * self.length) self.chars = codecs.getdecoder("utf16")(raw_chars)[0] def GetChars(self): return self.chars class ConsString(String): def LeftOffset(self): return self.heap.PointerSize() * 3 def RightOffset(self): return self.heap.PointerSize() * 4 def __init__(self, heap, map, address): String.__init__(self, heap, map, address) self.left = self.ObjectField(self.LeftOffset()) self.right = self.ObjectField(self.RightOffset()) def GetChars(self): try: return self.left.GetChars() + self.right.GetChars() except: return "***CAUGHT EXCEPTION IN GROKDUMP***" class Oddball(HeapObject): # Should match declarations in objects.h KINDS = [ "False", "True", "TheHole", "Null", "ArgumentMarker", "Undefined", "Other" ] def ToStringOffset(self): return self.heap.PointerSize() def ToNumberOffset(self): return self.ToStringOffset() + self.heap.PointerSize() def KindOffset(self): return self.ToNumberOffset() + self.heap.PointerSize() def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.to_string = self.ObjectField(self.ToStringOffset()) self.kind = self.SmiField(self.KindOffset()) def Print(self, p): p.Print(str(self)) def __str__(self): if self.to_string: return "Oddball(%08x, <%s>)" % (self.address, str(self.to_string)) else: kind = "???" if 0 <= self.kind < len(Oddball.KINDS): kind = Oddball.KINDS[self.kind] return "Oddball(%08x, kind=%s)" % (self.address, kind) class FixedArray(HeapObject): def LengthOffset(self): return self.heap.PointerSize() def ElementsOffset(self): return self.heap.PointerSize() * 2 def MemberOffset(self, i): return self.ElementsOffset() + self.heap.PointerSize() * i def Get(self, i): return self.ObjectField(self.MemberOffset(i)) def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.length = self.SmiField(self.LengthOffset()) def Print(self, p): p.Print("FixedArray(%s) {" % self.heap.reader.FormatIntPtr(self.address)) p.Indent() p.Print("length: %d" % self.length) base_offset = self.ElementsOffset() for i in xrange(self.length): offset = base_offset + 4 * i try: p.Print("[%08d] = %s" % (i, self.ObjectField(offset))) except TypeError: p.Dedent() p.Print("...") p.Print("}") return p.Dedent() p.Print("}") def __str__(self): return "FixedArray(%08x, length=%d)" % (self.address, self.length) class DescriptorArray(object): def __init__(self, array): self.array = array def Length(self): return self.array.Get(0) def Decode(self, offset, size, value): return (value >> offset) & ((1 << size) - 1) TYPES = [ "normal", "field", "function", "callbacks" ] def Type(self, value): return DescriptorArray.TYPES[self.Decode(0, 3, value)] def Attributes(self, value): attributes = self.Decode(3, 3, value) result = [] if (attributes & 0): result += ["ReadOnly"] if (attributes & 1): result += ["DontEnum"] if (attributes & 2): result += ["DontDelete"] return "[" + (",".join(result)) + "]" def Deleted(self, value): return self.Decode(6, 1, value) == 1 def FieldIndex(self, value): return self.Decode(20, 11, value) def Pointer(self, value): return self.Decode(6, 11, value) def Details(self, di, value): return ( di, self.Type(value), self.Attributes(value), self.FieldIndex(value), self.Pointer(value) ) def Print(self, p): length = self.Length() array = self.array p.Print("Descriptors(%08x, length=%d)" % (array.address, length)) p.Print("[et] %s" % (array.Get(1))) for di in xrange(length): i = 2 + di * 3 p.Print("0x%x" % (array.address + array.MemberOffset(i))) p.Print("[%i] name: %s" % (di, array.Get(i + 0))) p.Print("[%i] details: %s %s field-index %i pointer %i" % \ self.Details(di, array.Get(i + 1))) p.Print("[%i] value: %s" % (di, array.Get(i + 2))) end = self.array.length // 3 if length != end: p.Print("[%i-%i] slack descriptors" % (length, end)) class TransitionArray(object): def __init__(self, array): self.array = array def IsSimpleTransition(self): return self.array.length <= 2 def Length(self): # SimpleTransition cases if self.IsSimpleTransition(): return self.array.length - 1 return (self.array.length - 3) // 2 def Print(self, p): length = self.Length() array = self.array p.Print("Transitions(%08x, length=%d)" % (array.address, length)) p.Print("[backpointer] %s" % (array.Get(0))) if self.IsSimpleTransition(): if length == 1: p.Print("[simple target] %s" % (array.Get(1))) return elements = array.Get(1) if elements is not None: p.Print("[elements ] %s" % (elements)) prototype = array.Get(2) if prototype is not None: p.Print("[prototype ] %s" % (prototype)) for di in xrange(length): i = 3 + di * 2 p.Print("[%i] symbol: %s" % (di, array.Get(i + 0))) p.Print("[%i] target: %s" % (di, array.Get(i + 1))) class JSFunction(HeapObject): def CodeEntryOffset(self): return 3 * self.heap.PointerSize() def SharedOffset(self): return 5 * self.heap.PointerSize() def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) code_entry = \ heap.reader.ReadU32(self.address + self.CodeEntryOffset()) self.code = heap.FindObject(code_entry - Code.HeaderSize(heap) + 1) self.shared = self.ObjectField(self.SharedOffset()) def Print(self, p): source = "\n".join(" %s" % line for line in self._GetSource().split("\n")) p.Print("JSFunction(%s) {" % self.heap.reader.FormatIntPtr(self.address)) p.Indent() p.Print("inferred name: %s" % self.shared.inferred_name) if self.shared.script.Is(Script) and self.shared.script.name.Is(String): p.Print("script name: %s" % self.shared.script.name) p.Print("source:") p.PrintLines(self._GetSource().split("\n")) p.Print("code:") self.code.Print(p) if self.code != self.shared.code: p.Print("unoptimized code:") self.shared.code.Print(p) p.Dedent() p.Print("}") def __str__(self): inferred_name = "" if self.shared is not None and self.shared.Is(SharedFunctionInfo): inferred_name = self.shared.inferred_name return "JSFunction(%s, %s) " % \ (self.heap.reader.FormatIntPtr(self.address), inferred_name) def _GetSource(self): source = "?source?" start = self.shared.start_position end = self.shared.end_position if not self.shared.script.Is(Script): return source script_source = self.shared.script.source if not script_source.Is(String): return source if start and end: source = script_source.GetChars()[start:end] return source class SharedFunctionInfo(HeapObject): def CodeOffset(self): return 2 * self.heap.PointerSize() def ScriptOffset(self): return 7 * self.heap.PointerSize() def InferredNameOffset(self): return 9 * self.heap.PointerSize() def EndPositionOffset(self): return 12 * self.heap.PointerSize() + 4 * self.heap.IntSize() def StartPositionAndTypeOffset(self): return 12 * self.heap.PointerSize() + 5 * self.heap.IntSize() def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.code = self.ObjectField(self.CodeOffset()) self.script = self.ObjectField(self.ScriptOffset()) self.inferred_name = self.ObjectField(self.InferredNameOffset()) if heap.PointerSize() == 8: start_position_and_type = \ heap.reader.ReadU32(self.StartPositionAndTypeOffset()) self.start_position = start_position_and_type >> 2 pseudo_smi_end_position = \ heap.reader.ReadU32(self.EndPositionOffset()) self.end_position = pseudo_smi_end_position >> 2 else: start_position_and_type = \ self.SmiField(self.StartPositionAndTypeOffset()) if start_position_and_type: self.start_position = start_position_and_type >> 2 else: self.start_position = None self.end_position = \ self.SmiField(self.EndPositionOffset()) class Script(HeapObject): def SourceOffset(self): return self.heap.PointerSize() def NameOffset(self): return self.SourceOffset() + self.heap.PointerSize() def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.source = self.ObjectField(self.SourceOffset()) self.name = self.ObjectField(self.NameOffset()) class CodeCache(HeapObject): def DefaultCacheOffset(self): return self.heap.PointerSize() def NormalTypeCacheOffset(self): return self.DefaultCacheOffset() + self.heap.PointerSize() def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.default_cache = self.ObjectField(self.DefaultCacheOffset()) self.normal_type_cache = self.ObjectField(self.NormalTypeCacheOffset()) def Print(self, p): p.Print("CodeCache(%s) {" % self.heap.reader.FormatIntPtr(self.address)) p.Indent() p.Print("default cache: %s" % self.default_cache) p.Print("normal type cache: %s" % self.normal_type_cache) p.Dedent() p.Print("}") class Code(HeapObject): CODE_ALIGNMENT_MASK = (1 << 5) - 1 def InstructionSizeOffset(self): return self.heap.PointerSize() @staticmethod def HeaderSize(heap): return (heap.PointerSize() + heap.IntSize() + \ 4 * heap.PointerSize() + 3 * heap.IntSize() + \ Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK def __init__(self, heap, map, address): HeapObject.__init__(self, heap, map, address) self.entry = self.address + Code.HeaderSize(heap) self.instruction_size = \ heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) def Print(self, p): lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) p.Indent() p.Print("instruction_size: %d" % self.instruction_size) p.PrintLines(self._FormatLine(line) for line in lines) p.Dedent() p.Print("}") def _FormatLine(self, line): return FormatDisasmLine(self.entry, self.heap, line) class V8Heap(object): CLASS_MAP = { "SYMBOL_TYPE": SeqString, "ONE_BYTE_SYMBOL_TYPE": SeqString, "CONS_SYMBOL_TYPE": ConsString, "CONS_ONE_BYTE_SYMBOL_TYPE": ConsString, "EXTERNAL_SYMBOL_TYPE": ExternalString, "EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString, "EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString, "SHORT_EXTERNAL_SYMBOL_TYPE": ExternalString, "SHORT_EXTERNAL_SYMBOL_WITH_ONE_BYTE_DATA_TYPE": ExternalString, "SHORT_EXTERNAL_ONE_BYTE_SYMBOL_TYPE": ExternalString, "STRING_TYPE": SeqString, "ONE_BYTE_STRING_TYPE": SeqString, "CONS_STRING_TYPE": ConsString, "CONS_ONE_BYTE_STRING_TYPE": ConsString, "EXTERNAL_STRING_TYPE": ExternalString, "EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE": ExternalString, "EXTERNAL_ONE_BYTE_STRING_TYPE": ExternalString, "MAP_TYPE": Map, "ODDBALL_TYPE": Oddball, "FIXED_ARRAY_TYPE": FixedArray, "JS_FUNCTION_TYPE": JSFunction, "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, "SCRIPT_TYPE": Script, "CODE_CACHE_TYPE": CodeCache, "CODE_TYPE": Code, } def __init__(self, reader, stack_map): self.reader = reader self.stack_map = stack_map self.objects = {} def FindObjectOrSmi(self, tagged_address): if (tagged_address & 1) == 0: return tagged_address / 2 return self.FindObject(tagged_address) def FindObject(self, tagged_address): if tagged_address in self.objects: return self.objects[tagged_address] if (tagged_address & self.ObjectAlignmentMask()) != 1: return None address = tagged_address - 1 if not self.reader.IsValidAddress(address): return None map_tagged_address = self.reader.ReadUIntPtr(address) if tagged_address == map_tagged_address: # Meta map? meta_map = Map(self, None, address) instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) if instance_type_name != "MAP_TYPE": return None meta_map.map = meta_map object = meta_map else: map = self.FindMap(map_tagged_address) if map is None: return None instance_type_name = INSTANCE_TYPES.get(map.instance_type) if instance_type_name is None: return None cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) object = cls(self, map, address) self.objects[tagged_address] = object return object def FindMap(self, tagged_address): if (tagged_address & self.MapAlignmentMask()) != 1: return None address = tagged_address - 1 if not self.reader.IsValidAddress(address): return None object = Map(self, None, address) return object def IntSize(self): return 4 def PointerSize(self): return self.reader.PointerSize() def ObjectAlignmentMask(self): return self.PointerSize() - 1 def MapAlignmentMask(self): if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64: return (1 << 4) - 1 elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM: return (1 << 4) - 1 elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM64: return (1 << 4) - 1 elif self.reader.arch == MD_CPU_ARCHITECTURE_X86: return (1 << 5) - 1 def PageAlignmentMask(self): return (1 << 20) - 1 class KnownObject(HeapObject): def __init__(self, heap, known_name): HeapObject.__init__(self, heap, None, None) self.known_name = known_name def __str__(self): return "<%s>" % self.known_name class KnownMap(HeapObject): def __init__(self, heap, known_name, instance_type): HeapObject.__init__(self, heap, None, None) self.instance_type = instance_type self.known_name = known_name def __str__(self): return "<%s>" % self.known_name COMMENT_RE = re.compile(r"^C (0x[0-9a-fA-F]+) (.*)$") PAGEADDRESS_RE = re.compile( r"^P (mappage|oldpage) (0x[0-9a-fA-F]+)$") class InspectionInfo(object): def __init__(self, minidump_name, reader): self.comment_file = minidump_name + ".comments" self.address_comments = {} self.page_address = {} if os.path.exists(self.comment_file): with open(self.comment_file, "r") as f: lines = f.readlines() f.close() for l in lines: m = COMMENT_RE.match(l) if m: self.address_comments[int(m.group(1), 0)] = m.group(2) m = PAGEADDRESS_RE.match(l) if m: self.page_address[m.group(1)] = int(m.group(2), 0) self.reader = reader self.styles = {} self.color_addresses() return def get_page_address(self, page_kind): return self.page_address.get(page_kind, 0) def save_page_address(self, page_kind, address): with open(self.comment_file, "a") as f: f.write("P %s 0x%x\n" % (page_kind, address)) f.close() def color_addresses(self): # Color all stack addresses. exception_thread = self.reader.thread_map[self.reader.exception.thread_id] stack_top = self.reader.ExceptionSP() stack_bottom = exception_thread.stack.start + \ exception_thread.stack.memory.data_size frame_pointer = self.reader.ExceptionFP() self.styles[frame_pointer] = "frame" for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): self.styles[slot] = "stackaddress" for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): maybe_address = self.reader.ReadUIntPtr(slot) self.styles[maybe_address] = "stackval" if slot == frame_pointer: self.styles[slot] = "frame" frame_pointer = maybe_address self.styles[self.reader.ExceptionIP()] = "pc" def get_style_class(self, address): return self.styles.get(address, None) def get_style_class_string(self, address): style = self.get_style_class(address) if style != None: return " class=\"%s\" " % style else: return "" def set_comment(self, address, comment): self.address_comments[address] = comment with open(self.comment_file, "a") as f: f.write("C 0x%x %s\n" % (address, comment)) f.close() def get_comment(self, address): return self.address_comments.get(address, "") class InspectionPadawan(object): """The padawan can improve annotations by sensing well-known objects.""" def __init__(self, reader, heap): self.reader = reader self.heap = heap self.known_first_map_page = 0 self.known_first_old_page = 0 def __getattr__(self, name): """An InspectionPadawan can be used instead of V8Heap, even though it does not inherit from V8Heap (aka. mixin).""" return getattr(self.heap, name) def GetPageOffset(self, tagged_address): return tagged_address & self.heap.PageAlignmentMask() def IsInKnownMapSpace(self, tagged_address): page_address = tagged_address & ~self.heap.PageAlignmentMask() return page_address == self.known_first_map_page def IsInKnownOldSpace(self, tagged_address): page_address = tagged_address & ~self.heap.PageAlignmentMask() return page_address == self.known_first_old_page def ContainingKnownOldSpaceName(self, tagged_address): page_address = tagged_address & ~self.heap.PageAlignmentMask() if page_address == self.known_first_old_page: return "OLD_SPACE" return None def SenseObject(self, tagged_address): if self.IsInKnownOldSpace(tagged_address): offset = self.GetPageOffset(tagged_address) lookup_key = (self.ContainingKnownOldSpaceName(tagged_address), offset) known_obj_name = KNOWN_OBJECTS.get(lookup_key) if known_obj_name: return KnownObject(self, known_obj_name) if self.IsInKnownMapSpace(tagged_address): known_map = self.SenseMap(tagged_address) if known_map: return known_map found_obj = self.heap.FindObject(tagged_address) if found_obj: return found_obj address = tagged_address - 1 if self.reader.IsValidAddress(address): map_tagged_address = self.reader.ReadUIntPtr(address) map = self.SenseMap(map_tagged_address) if map is None: return None instance_type_name = INSTANCE_TYPES.get(map.instance_type) if instance_type_name is None: return None cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) return cls(self, map, address) return None def SenseMap(self, tagged_address): if self.IsInKnownMapSpace(tagged_address): offset = self.GetPageOffset(tagged_address) known_map_info = KNOWN_MAPS.get(offset) if known_map_info: known_map_type, known_map_name = known_map_info return KnownMap(self, known_map_name, known_map_type) found_map = self.heap.FindMap(tagged_address) if found_map: return found_map return None def FindObjectOrSmi(self, tagged_address): """When used as a mixin in place of V8Heap.""" found_obj = self.SenseObject(tagged_address) if found_obj: return found_obj if (tagged_address & 1) == 0: return "Smi(%d)" % (tagged_address / 2) else: return "Unknown(%s)" % self.reader.FormatIntPtr(tagged_address) def FindObject(self, tagged_address): """When used as a mixin in place of V8Heap.""" raise NotImplementedError def FindMap(self, tagged_address): """When used as a mixin in place of V8Heap.""" raise NotImplementedError def PrintKnowledge(self): print " known_first_map_page = %s\n"\ " known_first_old_page = %s" % ( self.reader.FormatIntPtr(self.known_first_map_page), self.reader.FormatIntPtr(self.known_first_old_page)) WEB_HEADER = """ Dump %(dump_name)s


""" WEB_FOOTER = """ """ class WebParameterError(Exception): def __init__(self, message): Exception.__init__(self, message) class InspectionWebHandler(BaseHTTPServer.BaseHTTPRequestHandler): def formatter(self, query_components): name = query_components.get("dump", [None])[0] return self.server.get_dump_formatter(name) def send_success_html_headers(self): self.send_response(200) self.send_header("Cache-Control", "no-cache, no-store, must-revalidate") self.send_header("Pragma", "no-cache") self.send_header("Expires", "0") self.send_header('Content-type','text/html') self.end_headers() return def do_GET(self): try: parsedurl = urlparse.urlparse(self.path) query_components = urlparse.parse_qs(parsedurl.query) if parsedurl.path == "/dumps.html": self.send_success_html_headers() self.server.output_dumps(self.wfile) elif parsedurl.path == "/summary.html": self.send_success_html_headers() self.formatter(query_components).output_summary(self.wfile) elif parsedurl.path == "/info.html": self.send_success_html_headers() self.formatter(query_components).output_info(self.wfile) elif parsedurl.path == "/modules.html": self.send_success_html_headers() self.formatter(query_components).output_modules(self.wfile) elif parsedurl.path == "/search.html": address = query_components.get("val", []) if len(address) != 1: self.send_error(404, "Invalid params") return self.send_success_html_headers() self.formatter(query_components).output_search_res( self.wfile, address[0]) elif parsedurl.path == "/disasm.html": address = query_components.get("val", []) exact = query_components.get("exact", ["on"]) if len(address) != 1: self.send_error(404, "Invalid params") return self.send_success_html_headers() self.formatter(query_components).output_disasm( self.wfile, address[0], exact[0]) elif parsedurl.path == "/data.html": address = query_components.get("val", []) datakind = query_components.get("type", ["address"]) if len(address) == 1 and len(datakind) == 1: self.send_success_html_headers() self.formatter(query_components).output_data( self.wfile, address[0], datakind[0]) else: self.send_error(404,'Invalid params') elif parsedurl.path == "/setdumpdesc": name = query_components.get("dump", [""]) description = query_components.get("description", [""]) if len(name) == 1 and len(description) == 1: name = name[0] description = description[0] if self.server.set_dump_desc(name, description): self.send_success_html_headers() self.wfile.write("OK") return self.send_error(404,'Invalid params') elif parsedurl.path == "/setcomment": address = query_components.get("address", []) comment = query_components.get("comment", [""]) if len(address) == 1 and len(comment) == 1: address = address[0] comment = comment[0] self.formatter(query_components).set_comment(address, comment) self.send_success_html_headers() self.wfile.write("OK") else: self.send_error(404,'Invalid params') elif parsedurl.path == "/setpageaddress": kind = query_components.get("kind", []) address = query_components.get("address", [""]) if len(kind) == 1 and len(address) == 1: kind = kind[0] address = address[0] self.formatter(query_components).set_page_address(kind, address) self.send_success_html_headers() self.wfile.write("OK") else: self.send_error(404,'Invalid params') else: self.send_error(404,'File Not Found: %s' % self.path) except IOError: self.send_error(404,'File Not Found: %s' % self.path) except WebParameterError as e: self.send_error(404, 'Web parameter error: %s' % e.message) HTML_REG_FORMAT = "%s: %s
\n" class InspectionWebFormatter(object): CONTEXT_FULL = 0 CONTEXT_SHORT = 1 def __init__(self, switches, minidump_name, http_server): self.dumpfilename = os.path.split(minidump_name)[1] self.encfilename = urllib.urlencode({ 'dump' : self.dumpfilename }) self.reader = MinidumpReader(switches, minidump_name) self.server = http_server # Set up the heap exception_thread = self.reader.thread_map[self.reader.exception.thread_id] stack_top = self.reader.ExceptionSP() stack_bottom = exception_thread.stack.start + \ exception_thread.stack.memory.data_size stack_map = {self.reader.ExceptionIP(): -1} for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): maybe_address = self.reader.ReadUIntPtr(slot) if not maybe_address in stack_map: stack_map[maybe_address] = slot self.heap = V8Heap(self.reader, stack_map) self.padawan = InspectionPadawan(self.reader, self.heap) self.comments = InspectionInfo(minidump_name, self.reader) self.padawan.known_first_old_page = ( self.comments.get_page_address("oldpage")) self.padawan.known_first_map_page = ( self.comments.get_page_address("mappage")) def set_comment(self, straddress, comment): try: address = int(straddress, 0) self.comments.set_comment(address, comment) except ValueError: print "Invalid address" def set_page_address(self, kind, straddress): try: address = int(straddress, 0) if kind == "oldpage": self.padawan.known_first_old_page = address elif kind == "mappage": self.padawan.known_first_map_page = address self.comments.save_page_address(kind, address) except ValueError: print "Invalid address" def td_from_address(self, f, address): f.write("" % self.comments.get_style_class_string(address)) def format_address(self, maybeaddress, straddress = None): if maybeaddress is None: return "not in dump" else: if straddress is None: straddress = "0x" + self.reader.FormatIntPtr(maybeaddress) style_class = "" if not self.reader.IsValidAddress(maybeaddress): style_class = " class=\"nodump\"" return ("%s" % (style_class, self.encfilename, straddress, straddress)) def output_header(self, f): f.write(WEB_HEADER % { "query_dump" : self.encfilename, "dump_name" : cgi.escape(self.dumpfilename) }) def output_footer(self, f): f.write(WEB_FOOTER) MAX_CONTEXT_STACK = 4096 def output_summary(self, f): self.output_header(f) f.write('
') self.output_context(f, InspectionWebFormatter.CONTEXT_SHORT) self.output_disasm_pc(f) # Output stack exception_thread = self.reader.thread_map[self.reader.exception.thread_id] stack_bottom = exception_thread.stack.start + \ min(exception_thread.stack.memory.data_size, self.MAX_CONTEXT_STACK) stack_top = self.reader.ExceptionSP() self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack") f.write('
') self.output_footer(f) return def output_info(self, f): self.output_header(f) f.write("

Dump info

\n") f.write("Description: ") self.server.output_dump_desc_field(f, self.dumpfilename) f.write("
\n") f.write("Filename: ") f.write("%s
\n" % (self.dumpfilename)) dt = datetime.datetime.fromtimestamp(self.reader.header.time_date_stampt) f.write("Timestamp: %s
\n" % dt.strftime('%Y-%m-%d %H:%M:%S')) self.output_context(f, InspectionWebFormatter.CONTEXT_FULL) self.output_address_ranges(f) self.output_footer(f) return def output_address_ranges(self, f): regions = {} def print_region(_reader, start, size, _location): regions[start] = size self.reader.ForEachMemoryRegion(print_region) f.write("

Available memory regions

\n") f.write('
') f.write("\n") f.write("") f.write("") f.write("") f.write("") f.write("\n") for start in sorted(regions): size = regions[start] f.write("") f.write("" % self.format_address(start)) f.write("" % self.format_address(start + size)) f.write("" % size) f.write("\n") f.write("
Start addressEnd addressNumber of bytes
%s %s %d
\n") f.write('
') return def output_module_details(self, f, module): f.write("%s" % GetModuleName(self.reader, module)) file_version = GetVersionString(module.version_info.dwFileVersionMS, module.version_info.dwFileVersionLS) product_version = GetVersionString(module.version_info.dwProductVersionMS, module.version_info.dwProductVersionLS) f.write("
  \n") f.write("base: %s" % self.reader.FormatIntPtr(module.base_of_image)) f.write("
  \n") f.write(" end: %s" % self.reader.FormatIntPtr(module.base_of_image + module.size_of_image)) f.write("
  \n") f.write(" file version: %s" % file_version) f.write("
  \n") f.write(" product version: %s" % product_version) f.write("
  \n") time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) f.write(" timestamp: %s" % time_date_stamp) f.write("
\n"); def output_modules(self, f): self.output_header(f) f.write('
') for module in self.reader.module_list.modules: self.output_module_details(f, module) f.write("
") self.output_footer(f) return def output_context(self, f, details): exception_thread = self.reader.thread_map[self.reader.exception.thread_id] f.write("

Exception context

") f.write('
\n') f.write("Thread id: %d" % exception_thread.id) f.write("   Exception code: %08X
\n" % self.reader.exception.exception.code) if details == InspectionWebFormatter.CONTEXT_FULL: if self.reader.exception.exception.parameter_count > 0: f.write("   Exception parameters: \n") for i in xrange(0, self.reader.exception.exception.parameter_count): f.write("%08x" % self.reader.exception.exception.information[i]) f.write("

\n") for r in CONTEXT_FOR_ARCH[self.reader.arch]: f.write(HTML_REG_FORMAT % (r, self.format_address(self.reader.Register(r)))) # TODO(vitalyr): decode eflags. if self.reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: f.write("cpsr: %s" % bin(self.reader.exception_context.cpsr)[2:]) else: f.write("eflags: %s" % bin(self.reader.exception_context.eflags)[2:]) f.write('
\n') return def align_down(self, a, size): alignment_correction = a % size return a - alignment_correction def align_up(self, a, size): alignment_correction = (size - 1) - ((a + size - 1) % size) return a + alignment_correction def format_object(self, address): heap_object = self.padawan.SenseObject(address) return cgi.escape(str(heap_object or "")) def output_data(self, f, straddress, datakind): try: self.output_header(f) address = int(straddress, 0) if not self.reader.IsValidAddress(address): f.write("

Address 0x%x not found in the dump.

" % address) return region = self.reader.FindRegion(address) if datakind == "address": self.output_words(f, region[0], region[0] + region[1], address, "Dump") elif datakind == "ascii": self.output_ascii(f, region[0], region[0] + region[1], address) self.output_footer(f) except ValueError: f.write("

Unrecognized address format \"%s\".

" % straddress) return def output_words(self, f, start_address, end_address, highlight_address, desc): region = self.reader.FindRegion(highlight_address) if region is None: f.write("

Address 0x%x not found in the dump.

\n" % (highlight_address)) return size = self.heap.PointerSize() start_address = self.align_down(start_address, size) low = self.align_down(region[0], size) high = self.align_up(region[0] + region[1], size) if start_address < low: start_address = low end_address = self.align_up(end_address, size) if end_address > high: end_address = high expand = "" if start_address != low or end_address != high: expand = ("(" " more..." " )" % (self.encfilename, highlight_address)) f.write("

%s 0x%x - 0x%x, " "highlighting 0x%x %s

\n" % (desc, start_address, end_address, highlight_address, expand)) f.write('
') f.write("\n") for j in xrange(0, end_address - start_address, size): slot = start_address + j heap_object = "" maybe_address = None end_region = region[0] + region[1] if slot < region[0] or slot + size > end_region: straddress = "0x" for i in xrange(end_region, slot + size): straddress += "??" for i in reversed( xrange(max(slot, region[0]), min(slot + size, end_region))): straddress += "%02x" % self.reader.ReadU8(i) for i in xrange(slot, region[0]): straddress += "??" else: maybe_address = self.reader.ReadUIntPtr(slot) straddress = self.format_address(maybe_address) if maybe_address: heap_object = self.format_object(maybe_address) address_fmt = "%s \n" if slot == highlight_address: f.write("\n") address_fmt = "%s \n" elif slot < highlight_address and highlight_address < slot + size: f.write("\n") address_fmt = "%s \n" else: f.write("\n") f.write(" \n") f.write(" ") self.td_from_address(f, slot) f.write(address_fmt % self.format_address(slot)) f.write(" ") self.td_from_address(f, maybe_address) f.write(": %s \n" % straddress) f.write(" \n") f.write(" \n" % (heap_object or '')) f.write("\n") f.write("
") self.output_comment_box(f, "da-", slot) f.write("") if maybe_address != None: self.output_comment_box( f, "sv-" + self.reader.FormatIntPtr(slot), maybe_address) f.write(" %s
\n") f.write("
") return def output_ascii(self, f, start_address, end_address, highlight_address): region = self.reader.FindRegion(highlight_address) if region is None: f.write("

Address %x not found in the dump.

" % highlight_address) return if start_address < region[0]: start_address = region[0] if end_address > region[0] + region[1]: end_address = region[0] + region[1] expand = "" if start_address != region[0] or end_address != region[0] + region[1]: link = ("data.html?%s&val=0x%x&type=ascii#highlight" % (self.encfilename, highlight_address)) expand = "(more...)" % link f.write("

ASCII dump 0x%x - 0x%x, highlighting 0x%x %s

" % (start_address, end_address, highlight_address, expand)) line_width = 64 f.write('
') start = self.align_down(start_address, line_width) for i in xrange(end_address - start): address = start + i if address % 64 == 0: if address != start: f.write("
") f.write("0x%08x: " % address) if address < start_address: f.write(" ") else: if address == highlight_address: f.write("") code = self.reader.ReadU8(address) if code < 127 and code >= 32: f.write("&#") f.write(str(code)) f.write(";") else: f.write("·") if address == highlight_address: f.write("") f.write("
") return def output_disasm(self, f, straddress, strexact): try: self.output_header(f) address = int(straddress, 0) if not self.reader.IsValidAddress(address): f.write("

Address 0x%x not found in the dump.

" % address) return region = self.reader.FindRegion(address) self.output_disasm_range( f, region[0], region[0] + region[1], address, strexact == "on") self.output_footer(f) except ValueError: f.write("

Unrecognized address format \"%s\".

" % straddress) return def output_disasm_range( self, f, start_address, end_address, highlight_address, exact): region = self.reader.FindRegion(highlight_address) if start_address < region[0]: start_address = region[0] if end_address > region[0] + region[1]: end_address = region[0] + region[1] count = end_address - start_address lines = self.reader.GetDisasmLines(start_address, count) found = False if exact: for line in lines: if line[0] + start_address == highlight_address: found = True break if not found: start_address = highlight_address count = end_address - start_address lines = self.reader.GetDisasmLines(highlight_address, count) expand = "" if start_address != region[0] or end_address != region[0] + region[1]: exactness = "" if exact and not found and end_address == region[0] + region[1]: exactness = "&exact=off" expand = ("(more...)" % (self.encfilename, exactness, highlight_address)) f.write("

Disassembling 0x%x - 0x%x, highlighting 0x%x %s

" % (start_address, end_address, highlight_address, expand)) f.write('
') f.write("\n"); for i in xrange(len(lines)): line = lines[i] next_address = count if i + 1 < len(lines): next_line = lines[i + 1] next_address = next_line[0] self.format_disasm_line( f, start_address, line, next_address, highlight_address) f.write("
\n") f.write("
") return def annotate_disasm_addresses(self, line): extra = [] for m in ADDRESS_RE.finditer(line): maybe_address = int(m.group(0), 16) formatted_address = self.format_address(maybe_address, m.group(0)) line = line.replace(m.group(0), formatted_address) object_info = self.padawan.SenseObject(maybe_address) if not object_info: continue extra.append(cgi.escape(str(object_info))) if len(extra) == 0: return line return ("%s ;; %s" % (line, ", ".join(extra))) def format_disasm_line( self, f, start, line, next_address, highlight_address): line_address = start + line[0] address_fmt = " %s\n" if line_address == highlight_address: f.write("\n") address_fmt = " %s\n" elif (line_address < highlight_address and highlight_address < next_address + start): f.write("\n") address_fmt = " %s\n" else: f.write("\n") num_bytes = next_address - line[0] stack_slot = self.heap.stack_map.get(line_address) marker = "" if stack_slot: marker = "=>" op_offset = 3 * num_bytes - 1 code = line[1] # Compute the actual call target which the disassembler is too stupid # to figure out (it adds the call offset to the disassembly offset rather # than the absolute instruction address). if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86: if code.startswith("e8"): words = code.split() if len(words) > 6 and words[5] == "call": offset = int(words[4] + words[3] + words[2] + words[1], 16) target = (line_address + offset + 5) & 0xFFFFFFFF code = code.replace(words[6], "0x%08x" % target) # TODO(jkummerow): port this hack to ARM and x64. opcodes = code[:op_offset] code = self.annotate_disasm_addresses(code[op_offset:]) f.write(" ") self.output_comment_box(f, "codel-", line_address) f.write("\n") f.write(address_fmt % marker) f.write(" ") self.td_from_address(f, line_address) f.write("%s (+0x%x)\n" % (self.format_address(line_address), line[0])) f.write(" : %s \n" % opcodes) f.write(" %s\n" % code) f.write("\n") def output_comment_box(self, f, prefix, address): f.write("" % (prefix, self.reader.FormatIntPtr(address), cgi.escape(self.comments.get_comment(address)) or "")) MAX_FOUND_RESULTS = 100 def output_find_results(self, f, results): f.write("Addresses") toomany = len(results) > self.MAX_FOUND_RESULTS if toomany: f.write("(found %i results, displaying only first %i)" % (len(results), self.MAX_FOUND_RESULTS)) f.write(": \n") results = sorted(results) results = results[:min(len(results), self.MAX_FOUND_RESULTS)] for address in results: f.write("%s\n" % (self.comments.get_style_class_string(address), self.format_address(address))) if toomany: f.write("...\n") def output_page_info(self, f, page_kind, page_address, my_page_address): if my_page_address == page_address and page_address != 0: f.write("Marked first %s page.\n" % page_kind) else: f.write("" % page_kind) f.write("Marked first %s page." % page_kind) f.write("\n") f.write("\n" % page_kind) return def output_search_res(self, f, straddress): try: self.output_header(f) f.write("

Search results for %s

" % straddress) address = int(straddress, 0) f.write("Comment: ") self.output_comment_box(f, "search-", address) f.write("
\n") page_address = address & ~self.heap.PageAlignmentMask() f.write("Page info: \n") self.output_page_info(f, "old", self.padawan.known_first_old_page, \ page_address) self.output_page_info(f, "map", self.padawan.known_first_map_page, \ page_address) if not self.reader.IsValidAddress(address): f.write("

The contents at address %s not found in the dump.

" % \ straddress) else: # Print as words self.output_words(f, address - 8, address + 32, address, "Dump") # Print as ASCII f.write("
\n") self.output_ascii(f, address, address + 256, address) # Print as code f.write("
\n") self.output_disasm_range(f, address - 16, address + 16, address, True) aligned_res, unaligned_res = self.reader.FindWordList(address) if len(aligned_res) > 0: f.write("

Occurrences of 0x%x at aligned addresses

\n" % address) self.output_find_results(f, aligned_res) if len(unaligned_res) > 0: f.write("

Occurrences of 0x%x at unaligned addresses

\n" % \ address) self.output_find_results(f, unaligned_res) if len(aligned_res) + len(unaligned_res) == 0: f.write("

No occurences of 0x%x found in the dump

\n" % address) self.output_footer(f) except ValueError: f.write("

Unrecognized address format \"%s\".

" % straddress) return def output_disasm_pc(self, f): address = self.reader.ExceptionIP() if not self.reader.IsValidAddress(address): return self.output_disasm_range(f, address - 16, address + 16, address, True) WEB_DUMPS_HEADER = """ Dump list """ WEB_DUMPS_FOOTER = """ """ DUMP_FILE_RE = re.compile(r"[-_0-9a-zA-Z][-\._0-9a-zA-Z]*\.dmp$") class InspectionWebServer(BaseHTTPServer.HTTPServer): def __init__(self, port_number, switches, minidump_name): BaseHTTPServer.HTTPServer.__init__( self, ('', port_number), InspectionWebHandler) splitpath = os.path.split(minidump_name) self.dumppath = splitpath[0] self.dumpfilename = splitpath[1] self.default_formatter = InspectionWebFormatter( switches, minidump_name, self) self.formatters = { self.dumpfilename : self.default_formatter } self.switches = switches def output_dump_desc_field(self, f, name): try: descfile = open(os.path.join(self.dumppath, name + ".desc"), "r") desc = descfile.readline() descfile.close() except IOError: desc = "" f.write("\n" % (cgi.escape(name), desc)) def set_dump_desc(self, name, description): if not DUMP_FILE_RE.match(name): return False fname = os.path.join(self.dumppath, name) if not os.path.isfile(fname): return False fname = fname + ".desc" descfile = open(fname, "w") descfile.write(description) descfile.close() return True def get_dump_formatter(self, name): if name is None: return self.default_formatter else: if not DUMP_FILE_RE.match(name): raise WebParameterError("Invalid name '%s'" % name) formatter = self.formatters.get(name, None) if formatter is None: try: formatter = InspectionWebFormatter( self.switches, os.path.join(self.dumppath, name), self) self.formatters[name] = formatter except IOError: raise WebParameterError("Could not open dump '%s'" % name) return formatter def output_dumps(self, f): f.write(WEB_DUMPS_HEADER) f.write("

List of available dumps

") f.write("\n") f.write("") f.write("") f.write("") f.write("") f.write("") dumps_by_time = {} for fname in os.listdir(self.dumppath): if DUMP_FILE_RE.match(fname): mtime = os.stat(os.path.join(self.dumppath, fname)).st_mtime fnames = dumps_by_time.get(mtime, []) fnames.append(fname) dumps_by_time[mtime] = fnames for mtime in sorted(dumps_by_time, reverse=True): fnames = dumps_by_time[mtime] for fname in fnames: f.write("\n") f.write("\n" % ( (urllib.urlencode({ 'dump' : fname }), fname))) f.write("") f.write("") f.write("\n") f.write("
NameFile timeComment
%s   ") f.write(datetime.datetime.fromtimestamp(mtime)) f.write("   ") self.output_dump_desc_field(f, fname) f.write("
\n") f.write(WEB_DUMPS_FOOTER) return class InspectionShell(cmd.Cmd): def __init__(self, reader, heap): cmd.Cmd.__init__(self) self.reader = reader self.heap = heap self.padawan = InspectionPadawan(reader, heap) self.prompt = "(grok) " def do_da(self, address): """ Print ASCII string starting at specified address. """ address = int(address, 16) string = "" while self.reader.IsValidAddress(address): code = self.reader.ReadU8(address) if code < 128: string += chr(code) else: break address += 1 if string == "": print "Not an ASCII string at %s" % self.reader.FormatIntPtr(address) else: print "%s\n" % string def do_dd(self, args): """ Interpret memory in the given region [address, address + num * word_size) (if available) as a sequence of words. Automatic alignment is not performed. If the num is not specified, a default value of 16 words is used. Synopsis: dd 0x
0x """ args = args.split(' ') start = int(args[0], 16) num = int(args[1], 16) if len(args) > 1 else 0x10 if (start & self.heap.ObjectAlignmentMask()) != 0: print "Warning: Dumping un-aligned memory, is this what you had in mind?" for i in xrange(0, self.reader.PointerSize() * num, self.reader.PointerSize()): slot = start + i if not self.reader.IsValidAddress(slot): print "Address is not contained within the minidump!" return maybe_address = self.reader.ReadUIntPtr(slot) heap_object = self.padawan.SenseObject(maybe_address) print "%s: %s %s" % (self.reader.FormatIntPtr(slot), self.reader.FormatIntPtr(maybe_address), heap_object or '') def do_do(self, address): """ Interpret memory at the given address as a V8 object. Automatic alignment makes sure that you can pass tagged as well as un-tagged addresses. """ address = int(address, 16) if (address & self.heap.ObjectAlignmentMask()) == 0: address = address + 1 elif (address & self.heap.ObjectAlignmentMask()) != 1: print "Address doesn't look like a valid pointer!" return heap_object = self.padawan.SenseObject(address) if heap_object: heap_object.Print(Printer()) else: print "Address cannot be interpreted as object!" def do_do_desc(self, address): """ Print a descriptor array in a readable format. """ start = int(address, 16) if ((start & 1) == 1): start = start - 1 DescriptorArray(FixedArray(self.heap, None, start)).Print(Printer()) def do_do_map(self, address): """ Print a descriptor array in a readable format. """ start = int(address, 16) if ((start & 1) == 1): start = start - 1 Map(self.heap, None, start).Print(Printer()) def do_do_trans(self, address): """ Print a transition array in a readable format. """ start = int(address, 16) if ((start & 1) == 1): start = start - 1 TransitionArray(FixedArray(self.heap, None, start)).Print(Printer()) def do_dp(self, address): """ Interpret memory at the given address as being on a V8 heap page and print information about the page header (if available). """ address = int(address, 16) page_address = address & ~self.heap.PageAlignmentMask() if self.reader.IsValidAddress(page_address): raise NotImplementedError else: print "Page header is not available!" def do_k(self, arguments): """ Teach V8 heap layout information to the inspector. This increases the amount of annotations the inspector can produce while dumping data. The first page of each heap space is of particular interest because it contains known objects that do not move. """ self.padawan.PrintKnowledge() def do_ko(self, address): """ Teach V8 heap layout information to the inspector. Set the first old space page by passing any pointer into that page. """ address = int(address, 16) page_address = address & ~self.heap.PageAlignmentMask() self.padawan.known_first_old_page = page_address def do_km(self, address): """ Teach V8 heap layout information to the inspector. Set the first map-space page by passing any pointer into that page. """ address = int(address, 16) page_address = address & ~self.heap.PageAlignmentMask() self.padawan.known_first_map_page = page_address def do_list(self, smth): """ List all available memory regions. """ def print_region(reader, start, size, location): print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start), reader.FormatIntPtr(start + size), size) print "Available memory regions:" self.reader.ForEachMemoryRegion(print_region) def do_lm(self, arg): """ List details for all loaded modules in the minidump. An argument can be passed to limit the output to only those modules that contain the argument as a substring (case insensitive match). """ for module in self.reader.module_list.modules: if arg: name = GetModuleName(self.reader, module).lower() if name.find(arg.lower()) >= 0: PrintModuleDetails(self.reader, module) else: PrintModuleDetails(self.reader, module) print def do_s(self, word): """ Search for a given word in available memory regions. The given word is expanded to full pointer size and searched at aligned as well as un-aligned memory locations. Use 'sa' to search aligned locations only. """ try: word = int(word, 0) except ValueError: print "Malformed word, prefix with '0x' to use hexadecimal format." return print "Searching for word %d/0x%s:" % (word, self.reader.FormatIntPtr(word)) self.reader.FindWord(word) def do_sh(self, none): """ Search for the V8 Heap object in all available memory regions. You might get lucky and find this rare treasure full of invaluable information. """ raise NotImplementedError def do_u(self, args): """ Unassemble memory in the region [address, address + size). If the size is not specified, a default value of 32 bytes is used. Synopsis: u 0x
0x """ args = args.split(' ') start = int(args[0], 16) size = int(args[1], 16) if len(args) > 1 else 0x20 if not self.reader.IsValidAddress(start): print "Address is not contained within the minidump!" return lines = self.reader.GetDisasmLines(start, size) for line in lines: print FormatDisasmLine(start, self.heap, line) print def do_EOF(self, none): raise KeyboardInterrupt EIP_PROXIMITY = 64 CONTEXT_FOR_ARCH = { MD_CPU_ARCHITECTURE_AMD64: ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'], MD_CPU_ARCHITECTURE_ARM: ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10', 'r11', 'r12', 'sp', 'lr', 'pc'], MD_CPU_ARCHITECTURE_ARM64: ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15', 'r16', 'r17', 'r18', 'r19', 'r20', 'r21', 'r22', 'r23', 'r24', 'r25', 'r26', 'r27', 'r28', 'fp', 'lr', 'sp', 'pc'], MD_CPU_ARCHITECTURE_X86: ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] } KNOWN_MODULES = {'chrome.exe', 'chrome.dll'} def GetVersionString(ms, ls): return "%d.%d.%d.%d" % (ms >> 16, ms & 0xffff, ls >> 16, ls & 0xffff) def GetModuleName(reader, module): name = reader.ReadMinidumpString(module.module_name_rva) # simplify for path manipulation name = name.encode('utf-8') return str(os.path.basename(str(name).replace("\\", "/"))) def PrintModuleDetails(reader, module): print "%s" % GetModuleName(reader, module) file_version = GetVersionString(module.version_info.dwFileVersionMS, module.version_info.dwFileVersionLS) product_version = GetVersionString(module.version_info.dwProductVersionMS, module.version_info.dwProductVersionLS) print " base: %s" % reader.FormatIntPtr(module.base_of_image) print " end: %s" % reader.FormatIntPtr(module.base_of_image + module.size_of_image) print " file version: %s" % file_version print " product version: %s" % product_version time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) print " timestamp: %s" % time_date_stamp def AnalyzeMinidump(options, minidump_name): reader = MinidumpReader(options, minidump_name) heap = None DebugPrint("========================================") if reader.exception is None: print "Minidump has no exception info" else: print "Exception info:" exception_thread = reader.thread_map[reader.exception.thread_id] print " thread id: %d" % exception_thread.id print " code: %08X" % reader.exception.exception.code print " context:" for r in CONTEXT_FOR_ARCH[reader.arch]: print " %s: %s" % (r, reader.FormatIntPtr(reader.Register(r))) # TODO(vitalyr): decode eflags. if reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: print " cpsr: %s" % bin(reader.exception_context.cpsr)[2:] else: print " eflags: %s" % bin(reader.exception_context.eflags)[2:] print print " modules:" for module in reader.module_list.modules: name = GetModuleName(reader, module) if name in KNOWN_MODULES: print " %s at %08X" % (name, module.base_of_image) reader.TryLoadSymbolsFor(name, module) print stack_top = reader.ExceptionSP() stack_bottom = exception_thread.stack.start + \ exception_thread.stack.memory.data_size stack_map = {reader.ExceptionIP(): -1} for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): maybe_address = reader.ReadUIntPtr(slot) if not maybe_address in stack_map: stack_map[maybe_address] = slot heap = V8Heap(reader, stack_map) print "Disassembly around exception.eip:" eip_symbol = reader.FindSymbol(reader.ExceptionIP()) if eip_symbol is not None: print eip_symbol disasm_start = reader.ExceptionIP() - EIP_PROXIMITY disasm_bytes = 2 * EIP_PROXIMITY if (options.full): full_range = reader.FindRegion(reader.ExceptionIP()) if full_range is not None: disasm_start = full_range[0] disasm_bytes = full_range[1] lines = reader.GetDisasmLines(disasm_start, disasm_bytes) if not lines: print "Could not disassemble using %s." % OBJDUMP_BIN print "Pass path to architecture specific objdump via --objdump?" for line in lines: print FormatDisasmLine(disasm_start, heap, line) print if heap is None: heap = V8Heap(reader, None) if options.full: FullDump(reader, heap) if options.command: InspectionShell(reader, heap).onecmd(options.command) if options.shell: try: InspectionShell(reader, heap).cmdloop("type help to get help") except KeyboardInterrupt: print "Kthxbye." elif not options.command: if reader.exception is not None: frame_pointer = reader.ExceptionFP() in_oom_dump_area = False print "Annotated stack (from exception.esp to bottom):" for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): ascii_content = [c if c >= '\x20' and c < '\x7f' else '.' for c in reader.ReadBytes(slot, reader.PointerSize())] maybe_address = reader.ReadUIntPtr(slot) maybe_address_contents = None if maybe_address >= stack_top and maybe_address <= stack_bottom: maybe_address_contents = reader.ReadUIntPtr(maybe_address) if maybe_address_contents == 0xdecade00: in_oom_dump_area = True heap_object = heap.FindObject(maybe_address) maybe_symbol = reader.FindSymbol(maybe_address) oom_comment = "" if in_oom_dump_area: if maybe_address_contents == 0xdecade00: oom_comment = " <----- HeapStats start marker" elif maybe_address_contents == 0xdecade01: oom_comment = " <----- HeapStats end marker" elif maybe_address_contents is not None: oom_comment = " %d (%d Mbytes)" % (maybe_address_contents, maybe_address_contents >> 20) if slot == frame_pointer: maybe_symbol = "<---- frame pointer" frame_pointer = maybe_address print "%s: %s %s %s%s" % (reader.FormatIntPtr(slot), reader.FormatIntPtr(maybe_address), "".join(ascii_content), maybe_symbol or "", oom_comment) if maybe_address_contents == 0xdecade01: in_oom_dump_area = False if heap_object: heap_object.Print(Printer()) print reader.Dispose() if __name__ == "__main__": parser = optparse.OptionParser(USAGE) parser.add_option("-s", "--shell", dest="shell", action="store_true", help="start an interactive inspector shell") parser.add_option("-w", "--web", dest="web", action="store_true", help="start a web server on localhost:%i" % PORT_NUMBER) parser.add_option("-c", "--command", dest="command", default="", help="run an interactive inspector shell command and exit") parser.add_option("-f", "--full", dest="full", action="store_true", help="dump all information contained in the minidump") parser.add_option("--symdir", dest="symdir", default=".", help="directory containing *.pdb.sym file with symbols") parser.add_option("--objdump", default="/usr/bin/objdump", help="objdump tool to use [default: %default]") options, args = parser.parse_args() if os.path.exists(options.objdump): disasm.OBJDUMP_BIN = options.objdump OBJDUMP_BIN = options.objdump else: print "Cannot find %s, falling back to default objdump" % options.objdump if len(args) != 1: parser.print_help() sys.exit(1) if options.web: try: server = InspectionWebServer(PORT_NUMBER, options, args[0]) print 'Started httpserver on port ' , PORT_NUMBER webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) server.serve_forever() except KeyboardInterrupt: print '^C received, shutting down the web server' server.socket.close() else: AnalyzeMinidump(options, args[0]) node-v4.2.6/deps/v8/tools/gyp/000755 000766 000024 00000000000 12650222326 016175 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/js2c.py000755 000766 000024 00000044533 12650222326 016625 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This is a utility for converting JavaScript source code into C-style # char arrays. It is used for embedded JavaScript code in the V8 # library. import os, re, sys, string import optparse import jsmin import bz2 import textwrap class Error(Exception): def __init__(self, msg): Exception.__init__(self, msg) def ToCArray(byte_sequence): result = [] for chr in byte_sequence: result.append(str(ord(chr))) joined = ", ".join(result) return textwrap.fill(joined, 80) def RemoveCommentsAndTrailingWhitespace(lines): lines = re.sub(r'//.*\n', '\n', lines) # end-of-line comments lines = re.sub(re.compile(r'/\*.*?\*/', re.DOTALL), '', lines) # comments. lines = re.sub(r'\s+\n+', '\n', lines) # trailing whitespace return lines def ReadFile(filename): file = open(filename, "rt") try: lines = file.read() finally: file.close() return lines EVAL_PATTERN = re.compile(r'\beval\s*\(') WITH_PATTERN = re.compile(r'\bwith\s*\(') INVALID_ERROR_MESSAGE_PATTERN = re.compile( r'Make(?!Generic)\w*Error\(([kA-Z]\w+)') NEW_ERROR_PATTERN = re.compile(r'new \$\w*Error\((?!\))') def Validate(lines): # Because of simplified context setup, eval and with is not # allowed in the natives files. if EVAL_PATTERN.search(lines): raise Error("Eval disallowed in natives.") if WITH_PATTERN.search(lines): raise Error("With statements disallowed in natives.") invalid_error = INVALID_ERROR_MESSAGE_PATTERN.search(lines) if invalid_error: raise Error("Unknown error message template '%s'" % invalid_error.group(1)) if NEW_ERROR_PATTERN.search(lines): raise Error("Error constructed without message template.") # Pass lines through unchanged. return lines def ExpandConstants(lines, constants): for key, value in constants: lines = key.sub(str(value), lines) return lines def ExpandMacroDefinition(lines, pos, name_pattern, macro, expander): pattern_match = name_pattern.search(lines, pos) while pattern_match is not None: # Scan over the arguments height = 1 start = pattern_match.start() end = pattern_match.end() assert lines[end - 1] == '(' last_match = end arg_index = [0] # Wrap state into array, to work around Python "scoping" mapping = { } def add_arg(str): # Remember to expand recursively in the arguments replacement = expander(str.strip()) mapping[macro.args[arg_index[0]]] = replacement arg_index[0] += 1 while end < len(lines) and height > 0: # We don't count commas at higher nesting levels. if lines[end] == ',' and height == 1: add_arg(lines[last_match:end]) last_match = end + 1 elif lines[end] in ['(', '{', '[']: height = height + 1 elif lines[end] in [')', '}', ']']: height = height - 1 end = end + 1 # Remember to add the last match. add_arg(lines[last_match:end-1]) result = macro.expand(mapping) # Replace the occurrence of the macro with the expansion lines = lines[:start] + result + lines[end:] pattern_match = name_pattern.search(lines, start + len(result)) return lines def ExpandMacros(lines, macros): # We allow macros to depend on the previously declared macros, but # we don't allow self-dependecies or recursion. for name_pattern, macro in reversed(macros): def expander(s): return ExpandMacros(s, macros) lines = ExpandMacroDefinition(lines, 0, name_pattern, macro, expander) return lines class TextMacro: def __init__(self, args, body): self.args = args self.body = body def expand(self, mapping): result = self.body for key, value in mapping.items(): result = result.replace(key, value) return result class PythonMacro: def __init__(self, args, fun): self.args = args self.fun = fun def expand(self, mapping): args = [] for arg in self.args: args.append(mapping[arg]) return str(self.fun(*args)) CONST_PATTERN = re.compile(r'^define\s+([a-zA-Z0-9_]+)\s*=\s*([^;]*);$') MACRO_PATTERN = re.compile(r'^macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$') PYTHON_MACRO_PATTERN = re.compile(r'^python\s+macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*=\s*([^;]*);$') def ReadMacros(lines): constants = [] macros = [] for line in lines.split('\n'): hash = line.find('#') if hash != -1: line = line[:hash] line = line.strip() if len(line) is 0: continue const_match = CONST_PATTERN.match(line) if const_match: name = const_match.group(1) value = const_match.group(2).strip() constants.append((re.compile("\\b%s\\b" % name), value)) else: macro_match = MACRO_PATTERN.match(line) if macro_match: name = macro_match.group(1) args = [match.strip() for match in macro_match.group(2).split(',')] body = macro_match.group(3).strip() macros.append((re.compile("\\b%s\\(" % name), TextMacro(args, body))) else: python_match = PYTHON_MACRO_PATTERN.match(line) if python_match: name = python_match.group(1) args = [match.strip() for match in python_match.group(2).split(',')] body = python_match.group(3).strip() fun = eval("lambda " + ",".join(args) + ': ' + body) macros.append((re.compile("\\b%s\\(" % name), PythonMacro(args, fun))) else: raise Error("Illegal line: " + line) return (constants, macros) TEMPLATE_PATTERN = re.compile(r'^\s+T\(([A-Z][a-zA-Z]*),') def ReadMessageTemplates(lines): templates = [] index = 0 for line in lines.split('\n'): template_match = TEMPLATE_PATTERN.match(line) if template_match: name = "k%s" % template_match.group(1) value = index index = index + 1 templates.append((re.compile("\\b%s\\b" % name), value)) return templates INLINE_MACRO_PATTERN = re.compile(r'macro\s+([a-zA-Z0-9_]+)\s*\(([^)]*)\)\s*\n') INLINE_MACRO_END_PATTERN = re.compile(r'endmacro\s*\n') def ExpandInlineMacros(lines): pos = 0 while True: macro_match = INLINE_MACRO_PATTERN.search(lines, pos) if macro_match is None: # no more macros return lines name = macro_match.group(1) args = [match.strip() for match in macro_match.group(2).split(',')] end_macro_match = INLINE_MACRO_END_PATTERN.search(lines, macro_match.end()); if end_macro_match is None: raise Error("Macro %s unclosed" % name) body = lines[macro_match.end():end_macro_match.start()] # remove macro definition lines = lines[:macro_match.start()] + lines[end_macro_match.end():] name_pattern = re.compile("\\b%s\\(" % name) macro = TextMacro(args, body) # advance position to where the macro defintion was pos = macro_match.start() def non_expander(s): return s lines = ExpandMacroDefinition(lines, pos, name_pattern, macro, non_expander) INLINE_CONSTANT_PATTERN = re.compile(r'define\s+([a-zA-Z0-9_]+)\s*=\s*([^;\n]+)[;\n]') def ExpandInlineConstants(lines): pos = 0 while True: const_match = INLINE_CONSTANT_PATTERN.search(lines, pos) if const_match is None: # no more constants return lines name = const_match.group(1) replacement = const_match.group(2) name_pattern = re.compile("\\b%s\\b" % name) # remove constant definition and replace lines = (lines[:const_match.start()] + re.sub(name_pattern, replacement, lines[const_match.end():])) # advance position to where the constant defintion was pos = const_match.start() HEADER_TEMPLATE = """\ // Copyright 2011 Google Inc. All Rights Reserved. // This file was generated from .js source files by GYP. If you // want to make changes to this file you should either change the // javascript source files or the GYP script. #include "src/v8.h" #include "src/snapshot/natives.h" #include "src/utils.h" namespace v8 { namespace internal { %(sources_declaration)s\ template <> int NativesCollection<%(type)s>::GetBuiltinsCount() { return %(builtin_count)i; } template <> int NativesCollection<%(type)s>::GetDebuggerCount() { return %(debugger_count)i; } template <> int NativesCollection<%(type)s>::GetIndex(const char* name) { %(get_index_cases)s\ return -1; } template <> Vector NativesCollection<%(type)s>::GetScriptSource(int index) { %(get_script_source_cases)s\ return Vector("", 0); } template <> Vector NativesCollection<%(type)s>::GetScriptName(int index) { %(get_script_name_cases)s\ return Vector("", 0); } template <> Vector NativesCollection<%(type)s>::GetScriptsSource() { return Vector(sources, %(total_length)i); } } // internal } // v8 """ SOURCES_DECLARATION = """\ static const char sources[] = { %s }; """ GET_INDEX_CASE = """\ if (strcmp(name, "%(id)s") == 0) return %(i)i; """ GET_SCRIPT_SOURCE_CASE = """\ if (index == %(i)i) return Vector(sources + %(offset)i, %(source_length)i); """ GET_SCRIPT_NAME_CASE = """\ if (index == %(i)i) return Vector("%(name)s", %(length)i); """ def BuildFilterChain(macro_filename, message_template_file): """Build the chain of filter functions to be applied to the sources. Args: macro_filename: Name of the macro file, if any. Returns: A function (string -> string) that processes a source file. """ filter_chain = [] if macro_filename: (consts, macros) = ReadMacros(ReadFile(macro_filename)) filter_chain.append(lambda l: ExpandConstants(l, consts)) filter_chain.append(lambda l: ExpandMacros(l, macros)) if message_template_file: message_templates = ReadMessageTemplates(ReadFile(message_template_file)) filter_chain.append(lambda l: ExpandConstants(l, message_templates)) filter_chain.extend([ RemoveCommentsAndTrailingWhitespace, ExpandInlineMacros, ExpandInlineConstants, Validate, jsmin.JavaScriptMinifier().JSMinify ]) def chain(f1, f2): return lambda x: f2(f1(x)) return reduce(chain, filter_chain) def BuildExtraFilterChain(): return lambda x: RemoveCommentsAndTrailingWhitespace(Validate(x)) class Sources: def __init__(self): self.names = [] self.modules = [] self.is_debugger_id = [] def IsDebuggerFile(filename): return filename.endswith("-debugger.js") def IsMacroFile(filename): return filename.endswith("macros.py") def IsMessageTemplateFile(filename): return filename.endswith("messages.h") def PrepareSources(source_files, native_type, emit_js): """Read, prepare and assemble the list of source files. Args: source_files: List of JavaScript-ish source files. A file named macros.py will be treated as a list of macros. native_type: String corresponding to a NativeType enum value, allowing us to treat different types of sources differently. emit_js: True if we should skip the byte conversion and just leave the sources as JS strings. Returns: An instance of Sources. """ macro_file = None macro_files = filter(IsMacroFile, source_files) assert len(macro_files) in [0, 1] if macro_files: source_files.remove(macro_files[0]) macro_file = macro_files[0] message_template_file = None message_template_files = filter(IsMessageTemplateFile, source_files) assert len(message_template_files) in [0, 1] if message_template_files: source_files.remove(message_template_files[0]) message_template_file = message_template_files[0] filters = None if native_type == "EXTRAS": filters = BuildExtraFilterChain() else: filters = BuildFilterChain(macro_file, message_template_file) # Sort 'debugger' sources first. source_files = sorted(source_files, lambda l,r: IsDebuggerFile(r) - IsDebuggerFile(l)) source_files_and_contents = [(f, ReadFile(f)) for f in source_files] # Have a single not-quite-empty source file if there are none present; # otherwise you get errors trying to compile an empty C++ array. # It cannot be empty (or whitespace, which gets trimmed to empty), as # the deserialization code assumes each file is nonempty. if not source_files_and_contents: source_files_and_contents = [("dummy.js", "(function() {})")] result = Sources() for (source, contents) in source_files_and_contents: try: lines = filters(contents) except Error as e: raise Error("In file %s:\n%s" % (source, str(e))) result.modules.append(lines) is_debugger = IsDebuggerFile(source) result.is_debugger_id.append(is_debugger) name = os.path.basename(source)[:-3] result.names.append(name if not is_debugger else name[:-9]) return result def BuildMetadata(sources, source_bytes, native_type): """Build the meta data required to generate a libaries file. Args: sources: A Sources instance with the prepared sources. source_bytes: A list of source bytes. (The concatenation of all sources; might be compressed.) native_type: The parameter for the NativesCollection template. Returns: A dictionary for use with HEADER_TEMPLATE. """ total_length = len(source_bytes) raw_sources = "".join(sources.modules) # The sources are expected to be ASCII-only. assert not filter(lambda value: ord(value) >= 128, raw_sources) # Loop over modules and build up indices into the source blob: get_index_cases = [] get_script_name_cases = [] get_script_source_cases = [] offset = 0 for i in xrange(len(sources.modules)): native_name = "native %s.js" % sources.names[i] d = { "i": i, "id": sources.names[i], "name": native_name, "length": len(native_name), "offset": offset, "source_length": len(sources.modules[i]), } get_index_cases.append(GET_INDEX_CASE % d) get_script_name_cases.append(GET_SCRIPT_NAME_CASE % d) get_script_source_cases.append(GET_SCRIPT_SOURCE_CASE % d) offset += len(sources.modules[i]) assert offset == len(raw_sources) metadata = { "builtin_count": len(sources.modules), "debugger_count": sum(sources.is_debugger_id), "sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes), "total_length": total_length, "get_index_cases": "".join(get_index_cases), "get_script_source_cases": "".join(get_script_source_cases), "get_script_name_cases": "".join(get_script_name_cases), "type": native_type, } return metadata def PutInt(blob_file, value): assert(value >= 0 and value < (1 << 28)) if (value < 1 << 6): size = 1 elif (value < 1 << 14): size = 2 elif (value < 1 << 22): size = 3 else: size = 4 value_with_length = (value << 2) | (size - 1) byte_sequence = bytearray() for i in xrange(size): byte_sequence.append(value_with_length & 255) value_with_length >>= 8; blob_file.write(byte_sequence) def PutStr(blob_file, value): PutInt(blob_file, len(value)); blob_file.write(value); def WriteStartupBlob(sources, startup_blob): """Write a startup blob, as expected by V8 Initialize ... TODO(vogelheim): Add proper method name. Args: sources: A Sources instance with the prepared sources. startup_blob_file: Name of file to write the blob to. """ output = open(startup_blob, "wb") debug_sources = sum(sources.is_debugger_id); PutInt(output, debug_sources) for i in xrange(debug_sources): PutStr(output, sources.names[i]); PutStr(output, sources.modules[i]); PutInt(output, len(sources.names) - debug_sources) for i in xrange(debug_sources, len(sources.names)): PutStr(output, sources.names[i]); PutStr(output, sources.modules[i]); output.close() def JS2C(sources, target, native_type, raw_file, startup_blob, emit_js): prepared_sources = PrepareSources(sources, native_type, emit_js) sources_output = "".join(prepared_sources.modules) metadata = BuildMetadata(prepared_sources, sources_output, native_type) # Optionally emit raw file. if raw_file: output = open(raw_file, "w") output.write(sources_output) output.close() if startup_blob: WriteStartupBlob(prepared_sources, startup_blob) # Emit resulting source file. output = open(target, "w") if emit_js: output.write(sources_output) else: output.write(HEADER_TEMPLATE % metadata) output.close() def main(): parser = optparse.OptionParser() parser.add_option("--raw", help="file to write the processed sources array to.") parser.add_option("--startup_blob", help="file to write the startup blob to.") parser.add_option("--js", help="writes a JS file output instead of a C file", action="store_true") parser.set_usage("""js2c out.cc type sources.js ... out.cc: C code to be generated. type: type parameter for NativesCollection template. sources.js: JS internal sources or macros.py.""") (options, args) = parser.parse_args() JS2C(args[2:], args[0], args[1], options.raw, options.startup_blob, options.js) if __name__ == "__main__": main() node-v4.2.6/deps/v8/tools/jsmin.py000644 000766 000024 00000026167 12650222326 017104 0ustar00iojsstaff000000 000000 #!/usr/bin/python2.4 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """A JavaScript minifier. It is far from being a complete JS parser, so there are many valid JavaScript programs that will be ruined by it. Another strangeness is that it accepts $ and % as parts of identifiers. It doesn't merge lines or strip out blank lines in order to ease debugging. Variables at the top scope are properties of the global object so we can't rename them. It is assumed that you introduce variables with var as if JavaScript followed C++ scope rules around curly braces, so the declaration must be above the first use. Use as: import jsmin minifier = JavaScriptMinifier() program1 = minifier.JSMinify(program1) program2 = minifier.JSMinify(program2) """ import re class JavaScriptMinifier(object): """An object that you can feed code snippets to to get them minified.""" def __init__(self): # We prepopulate the list of identifiers that shouldn't be used. These # short language keywords could otherwise be used by the script as variable # names. self.seen_identifiers = {"do": True, "in": True} self.identifier_counter = 0 self.in_comment = False self.map = {} self.nesting = 0 def LookAtIdentifier(self, m): """Records identifiers or keywords that we see in use. (So we can avoid renaming variables to these strings.) Args: m: The match object returned by re.search. Returns: Nothing. """ identifier = m.group(1) self.seen_identifiers[identifier] = True def Push(self): """Called when we encounter a '{'.""" self.nesting += 1 def Pop(self): """Called when we encounter a '}'.""" self.nesting -= 1 # We treat each top-level opening brace as a single scope that can span # several sets of nested braces. if self.nesting == 0: self.map = {} self.identifier_counter = 0 def Declaration(self, m): """Rewrites bits of the program selected by a regexp. These can be curly braces, literal strings, function declarations and var declarations. (These last two must be on one line including the opening curly brace of the function for their variables to be renamed). Args: m: The match object returned by re.search. Returns: The string that should replace the match in the rewritten program. """ matched_text = m.group(0) if matched_text.startswith("`") and matched_text.endswith("`"): return re.sub(r"\$\{([\w$%]+)\}", lambda m: '${' + self.FindNewName(m.group(1)) + '}', matched_text) if matched_text == "{": self.Push() return matched_text if matched_text == "}": self.Pop() return matched_text if re.match("[\"'/]", matched_text): return matched_text m = re.match(r"var ", matched_text) if m: var_names = matched_text[m.end():] var_names = re.split(r",", var_names) return "var " + ",".join(map(self.FindNewName, var_names)) m = re.match(r"(function\b[^(]*)\((.*)\)\{$", matched_text) if m: up_to_args = m.group(1) args = m.group(2) args = re.split(r",", args) self.Push() return up_to_args + "(" + ",".join(map(self.FindNewName, args)) + "){" if matched_text in self.map: return self.map[matched_text] return matched_text def CharFromNumber(self, number): """A single-digit base-52 encoding using a-zA-Z.""" if number < 26: return chr(number + 97) number -= 26 return chr(number + 65) def FindNewName(self, var_name): """Finds a new 1-character or 2-character name for a variable. Enters it into the mapping table for this scope. Args: var_name: The name of the variable before renaming. Returns: The new name of the variable. """ new_identifier = "" # Variable names that end in _ are member variables of the global object, # so they can be visible from code in a different scope. We leave them # alone. if var_name in self.map: return self.map[var_name] if self.nesting == 0: return var_name # Do not rename arguments object. if var_name == 'arguments': return 'arguments' while True: identifier_first_char = self.identifier_counter % 52 identifier_second_char = self.identifier_counter // 52 new_identifier = self.CharFromNumber(identifier_first_char) if identifier_second_char != 0: new_identifier = ( self.CharFromNumber(identifier_second_char - 1) + new_identifier) self.identifier_counter += 1 if not new_identifier in self.seen_identifiers: break self.map[var_name] = new_identifier return new_identifier def RemoveSpaces(self, m): """Returns literal strings unchanged, replaces other inputs with group 2. Other inputs are replaced with the contents of capture 1. This is either a single space or an empty string. Args: m: The match object returned by re.search. Returns: The string that should be inserted instead of the matched text. """ entire_match = m.group(0) replacement = m.group(1) if re.match(r"'.*'$", entire_match): return entire_match if re.match(r'".*"$', entire_match): return entire_match if re.match(r"`.*`$", entire_match): return entire_match if re.match(r"/.+/$", entire_match): return entire_match return replacement def JSMinify(self, text): """The main entry point. Takes a text and returns a compressed version. The compressed version hopefully does the same thing. Line breaks are preserved. Args: text: The text of the code snippet as a multiline string. Returns: The compressed text of the code snippet as a multiline string. """ new_lines = [] for line in re.split(r"\n", text): line = line.replace("\t", " ") if self.in_comment: m = re.search(r"\*/", line) if m: line = line[m.end():] self.in_comment = False else: new_lines.append("") continue if not self.in_comment: line = re.sub(r"/\*.*?\*/", " ", line) line = re.sub(r"//.*", "", line) m = re.search(r"/\*", line) if m: line = line[:m.start()] self.in_comment = True # Strip leading and trailing spaces. line = re.sub(r"^ +", "", line) line = re.sub(r" +$", "", line) # A regexp that matches a literal string surrounded by "double quotes". # This regexp can handle embedded backslash-escaped characters including # embedded backslash-escaped double quotes. double_quoted_string = r'"(?:[^"\\]|\\.)*"' # A regexp that matches a literal string surrounded by 'single quotes'. single_quoted_string = r"'(?:[^'\\]|\\.)*'" # A regexp that matches a template string template_string = r"`(?:[^`\\]|\\.)*`" # A regexp that matches a regexp literal surrounded by /slashes/. # Don't allow a regexp to have a ) before the first ( since that's a # syntax error and it's probably just two unrelated slashes. # Also don't allow it to come after anything that can only be the # end of a primary expression. slash_quoted_regexp = r"(? /dev/null; then log_file=${arg} fi done tools_path=`cd $(dirname "$0");pwd` if [ ! "$D8_PATH" ]; then d8_public=`which d8` if [ -x "$d8_public" ]; then D8_PATH=$(dirname "$d8_public"); fi fi [ -n "$D8_PATH" ] || D8_PATH=$tools_path/.. d8_exec=$D8_PATH/d8 if [ ! -x "$d8_exec" ]; then D8_PATH=`pwd`/out/native d8_exec=$D8_PATH/d8 fi if [ ! -x "$d8_exec" ]; then d8_exec=`grep -m 1 -o '".*/d8"' $log_file | sed 's/"//g'` fi if [ ! -x "$d8_exec" ]; then echo "d8 shell not found in $D8_PATH" echo "To build, execute 'make native' from the V8 directory" exit 1 fi # nm spits out 'no symbols found' messages to stderr. cat $log_file | $d8_exec $tools_path/splaytree.js $tools_path/codemap.js \ $tools_path/csvparser.js $tools_path/consarray.js \ $tools_path/profile.js $tools_path/profile_view.js \ $tools_path/logreader.js $tools_path/tickprocessor.js \ $tools_path/SourceMap.js \ $tools_path/tickprocessor-driver.js -- $@ 2>/dev/null node-v4.2.6/deps/v8/tools/ll_prof.py000755 000766 000024 00000103475 12650222326 017422 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import bisect import collections import ctypes import disasm import mmap import optparse import os import re import subprocess import sys import time USAGE="""usage: %prog [OPTION]... Analyses V8 and perf logs to produce profiles. Perf logs can be collected using a command like: $ perf record -R -e cycles -c 10000 -f -i ./d8 bench.js --ll-prof # -R: collect all data # -e cycles: use cpu-cycles event (run "perf list" for details) # -c 10000: write a sample after each 10000 events # -f: force output file overwrite # -i: limit profiling to our process and the kernel # --ll-prof shell flag enables the right V8 logs This will produce a binary trace file (perf.data) that %prog can analyse. IMPORTANT: The kernel has an internal maximum for events per second, it is 100K by default. That's not enough for "-c 10000". Set it to some higher value: $ echo 10000000 | sudo tee /proc/sys/kernel/perf_event_max_sample_rate You can also make the warning about kernel address maps go away: $ echo 0 | sudo tee /proc/sys/kernel/kptr_restrict We have a convenience script that handles all of the above for you: $ tools/run-llprof.sh ./d8 bench.js Examples: # Print flat profile with annotated disassembly for the 10 top # symbols. Use default log names and include the snapshot log. $ %prog --snapshot --disasm-top=10 # Print flat profile with annotated disassembly for all used symbols. # Use default log names and include kernel symbols into analysis. $ %prog --disasm-all --kernel # Print flat profile. Use custom log names. $ %prog --log=foo.log --snapshot-log=snap-foo.log --trace=foo.data --snapshot """ JS_ORIGIN = "js" JS_SNAPSHOT_ORIGIN = "js-snapshot" class Code(object): """Code object.""" _id = 0 UNKNOWN = 0 V8INTERNAL = 1 FULL_CODEGEN = 2 OPTIMIZED = 3 def __init__(self, name, start_address, end_address, origin, origin_offset): self.id = Code._id Code._id += 1 self.name = name self.other_names = None self.start_address = start_address self.end_address = end_address self.origin = origin self.origin_offset = origin_offset self.self_ticks = 0 self.self_ticks_map = None self.callee_ticks = None if name.startswith("LazyCompile:*"): self.codetype = Code.OPTIMIZED elif name.startswith("LazyCompile:"): self.codetype = Code.FULL_CODEGEN elif name.startswith("v8::internal::"): self.codetype = Code.V8INTERNAL else: self.codetype = Code.UNKNOWN def AddName(self, name): assert self.name != name if self.other_names is None: self.other_names = [name] return if not name in self.other_names: self.other_names.append(name) def FullName(self): if self.other_names is None: return self.name self.other_names.sort() return "%s (aka %s)" % (self.name, ", ".join(self.other_names)) def IsUsed(self): return self.self_ticks > 0 or self.callee_ticks is not None def Tick(self, pc): self.self_ticks += 1 if self.self_ticks_map is None: self.self_ticks_map = collections.defaultdict(lambda: 0) offset = pc - self.start_address self.self_ticks_map[offset] += 1 def CalleeTick(self, callee): if self.callee_ticks is None: self.callee_ticks = collections.defaultdict(lambda: 0) self.callee_ticks[callee] += 1 def PrintAnnotated(self, arch, options): if self.self_ticks_map is None: ticks_map = [] else: ticks_map = self.self_ticks_map.items() # Convert the ticks map to offsets and counts arrays so that later # we can do binary search in the offsets array. ticks_map.sort(key=lambda t: t[0]) ticks_offsets = [t[0] for t in ticks_map] ticks_counts = [t[1] for t in ticks_map] # Get a list of disassembled lines and their addresses. lines = self._GetDisasmLines(arch, options) if len(lines) == 0: return # Print annotated lines. address = lines[0][0] total_count = 0 for i in xrange(len(lines)): start_offset = lines[i][0] - address if i == len(lines) - 1: end_offset = self.end_address - self.start_address else: end_offset = lines[i + 1][0] - address # Ticks (reported pc values) are not always precise, i.e. not # necessarily point at instruction starts. So we have to search # for ticks that touch the current instruction line. j = bisect.bisect_left(ticks_offsets, end_offset) count = 0 for offset, cnt in reversed(zip(ticks_offsets[:j], ticks_counts[:j])): if offset < start_offset: break count += cnt total_count += count count = 100.0 * count / self.self_ticks if count >= 0.01: print "%15.2f %x: %s" % (count, lines[i][0], lines[i][1]) else: print "%s %x: %s" % (" " * 15, lines[i][0], lines[i][1]) print assert total_count == self.self_ticks, \ "Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self) def __str__(self): return "%s [0x%x, 0x%x) size: %d origin: %s" % ( self.name, self.start_address, self.end_address, self.end_address - self.start_address, self.origin) def _GetDisasmLines(self, arch, options): if self.origin == JS_ORIGIN or self.origin == JS_SNAPSHOT_ORIGIN: inplace = False filename = options.log + ".ll" else: inplace = True filename = self.origin return disasm.GetDisasmLines(filename, self.origin_offset, self.end_address - self.start_address, arch, inplace) class CodePage(object): """Group of adjacent code objects.""" SHIFT = 20 # 1M pages SIZE = (1 << SHIFT) MASK = ~(SIZE - 1) @staticmethod def PageAddress(address): return address & CodePage.MASK @staticmethod def PageId(address): return address >> CodePage.SHIFT @staticmethod def PageAddressFromId(id): return id << CodePage.SHIFT def __init__(self, address): self.address = address self.code_objects = [] def Add(self, code): self.code_objects.append(code) def Remove(self, code): self.code_objects.remove(code) def Find(self, pc): code_objects = self.code_objects for i, code in enumerate(code_objects): if code.start_address <= pc < code.end_address: code_objects[0], code_objects[i] = code, code_objects[0] return code return None def __iter__(self): return self.code_objects.__iter__() class CodeMap(object): """Code object map.""" def __init__(self): self.pages = {} self.min_address = 1 << 64 self.max_address = -1 def Add(self, code, max_pages=-1): page_id = CodePage.PageId(code.start_address) limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1) pages = 0 while page_id < limit_id: if max_pages >= 0 and pages > max_pages: print >>sys.stderr, \ "Warning: page limit (%d) reached for %s [%s]" % ( max_pages, code.name, code.origin) break if page_id in self.pages: page = self.pages[page_id] else: page = CodePage(CodePage.PageAddressFromId(page_id)) self.pages[page_id] = page page.Add(code) page_id += 1 pages += 1 self.min_address = min(self.min_address, code.start_address) self.max_address = max(self.max_address, code.end_address) def Remove(self, code): page_id = CodePage.PageId(code.start_address) limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1) removed = False while page_id < limit_id: if page_id not in self.pages: page_id += 1 continue page = self.pages[page_id] page.Remove(code) removed = True page_id += 1 return removed def AllCode(self): for page in self.pages.itervalues(): for code in page: if CodePage.PageAddress(code.start_address) == page.address: yield code def UsedCode(self): for code in self.AllCode(): if code.IsUsed(): yield code def Print(self): for code in self.AllCode(): print code def Find(self, pc): if pc < self.min_address or pc >= self.max_address: return None page_id = CodePage.PageId(pc) if page_id not in self.pages: return None return self.pages[page_id].Find(pc) class CodeInfo(object): """Generic info about generated code objects.""" def __init__(self, arch, header_size): self.arch = arch self.header_size = header_size class SnapshotLogReader(object): """V8 snapshot log reader.""" _SNAPSHOT_CODE_NAME_RE = re.compile( r"snapshot-code-name,(\d+),\"(.*)\"") def __init__(self, log_name): self.log_name = log_name def ReadNameMap(self): log = open(self.log_name, "r") try: snapshot_pos_to_name = {} for line in log: match = SnapshotLogReader._SNAPSHOT_CODE_NAME_RE.match(line) if match: pos = int(match.group(1)) name = match.group(2) snapshot_pos_to_name[pos] = name finally: log.close() return snapshot_pos_to_name class LogReader(object): """V8 low-level (binary) log reader.""" _ARCH_TO_POINTER_TYPE_MAP = { "ia32": ctypes.c_uint32, "arm": ctypes.c_uint32, "mips": ctypes.c_uint32, "x64": ctypes.c_uint64, "arm64": ctypes.c_uint64 } _CODE_CREATE_TAG = "C" _CODE_MOVE_TAG = "M" _CODE_DELETE_TAG = "D" _SNAPSHOT_POSITION_TAG = "P" _CODE_MOVING_GC_TAG = "G" def __init__(self, log_name, code_map, snapshot_pos_to_name): self.log_file = open(log_name, "r") self.log = mmap.mmap(self.log_file.fileno(), 0, mmap.MAP_PRIVATE) self.log_pos = 0 self.code_map = code_map self.snapshot_pos_to_name = snapshot_pos_to_name self.address_to_snapshot_name = {} self.arch = self.log[:self.log.find("\0")] self.log_pos += len(self.arch) + 1 assert self.arch in LogReader._ARCH_TO_POINTER_TYPE_MAP, \ "Unsupported architecture %s" % self.arch pointer_type = LogReader._ARCH_TO_POINTER_TYPE_MAP[self.arch] self.code_create_struct = LogReader._DefineStruct([ ("name_size", ctypes.c_int32), ("code_address", pointer_type), ("code_size", ctypes.c_int32)]) self.code_move_struct = LogReader._DefineStruct([ ("from_address", pointer_type), ("to_address", pointer_type)]) self.code_delete_struct = LogReader._DefineStruct([ ("address", pointer_type)]) self.snapshot_position_struct = LogReader._DefineStruct([ ("address", pointer_type), ("position", ctypes.c_int32)]) def ReadUpToGC(self): while self.log_pos < self.log.size(): tag = self.log[self.log_pos] self.log_pos += 1 if tag == LogReader._CODE_MOVING_GC_TAG: self.address_to_snapshot_name.clear() return if tag == LogReader._CODE_CREATE_TAG: event = self.code_create_struct.from_buffer(self.log, self.log_pos) self.log_pos += ctypes.sizeof(event) start_address = event.code_address end_address = start_address + event.code_size if start_address in self.address_to_snapshot_name: name = self.address_to_snapshot_name[start_address] origin = JS_SNAPSHOT_ORIGIN else: name = self.log[self.log_pos:self.log_pos + event.name_size] origin = JS_ORIGIN self.log_pos += event.name_size origin_offset = self.log_pos self.log_pos += event.code_size code = Code(name, start_address, end_address, origin, origin_offset) conficting_code = self.code_map.Find(start_address) if conficting_code: if not (conficting_code.start_address == code.start_address and conficting_code.end_address == code.end_address): self.code_map.Remove(conficting_code) else: LogReader._HandleCodeConflict(conficting_code, code) # TODO(vitalyr): this warning is too noisy because of our # attempts to reconstruct code log from the snapshot. # print >>sys.stderr, \ # "Warning: Skipping duplicate code log entry %s" % code continue self.code_map.Add(code) continue if tag == LogReader._CODE_MOVE_TAG: event = self.code_move_struct.from_buffer(self.log, self.log_pos) self.log_pos += ctypes.sizeof(event) old_start_address = event.from_address new_start_address = event.to_address if old_start_address == new_start_address: # Skip useless code move entries. continue code = self.code_map.Find(old_start_address) if not code: print >>sys.stderr, "Warning: Not found %x" % old_start_address continue assert code.start_address == old_start_address, \ "Inexact move address %x for %s" % (old_start_address, code) self.code_map.Remove(code) size = code.end_address - code.start_address code.start_address = new_start_address code.end_address = new_start_address + size self.code_map.Add(code) continue if tag == LogReader._CODE_DELETE_TAG: event = self.code_delete_struct.from_buffer(self.log, self.log_pos) self.log_pos += ctypes.sizeof(event) old_start_address = event.address code = self.code_map.Find(old_start_address) if not code: print >>sys.stderr, "Warning: Not found %x" % old_start_address continue assert code.start_address == old_start_address, \ "Inexact delete address %x for %s" % (old_start_address, code) self.code_map.Remove(code) continue if tag == LogReader._SNAPSHOT_POSITION_TAG: event = self.snapshot_position_struct.from_buffer(self.log, self.log_pos) self.log_pos += ctypes.sizeof(event) start_address = event.address snapshot_pos = event.position if snapshot_pos in self.snapshot_pos_to_name: self.address_to_snapshot_name[start_address] = \ self.snapshot_pos_to_name[snapshot_pos] continue assert False, "Unknown tag %s" % tag def Dispose(self): self.log.close() self.log_file.close() @staticmethod def _DefineStruct(fields): class Struct(ctypes.Structure): _fields_ = fields return Struct @staticmethod def _HandleCodeConflict(old_code, new_code): assert (old_code.start_address == new_code.start_address and old_code.end_address == new_code.end_address), \ "Conficting code log entries %s and %s" % (old_code, new_code) if old_code.name == new_code.name: return # Code object may be shared by a few functions. Collect the full # set of names. old_code.AddName(new_code.name) class Descriptor(object): """Descriptor of a structure in the binary trace log.""" CTYPE_MAP = { "u16": ctypes.c_uint16, "u32": ctypes.c_uint32, "u64": ctypes.c_uint64 } def __init__(self, fields): class TraceItem(ctypes.Structure): _fields_ = Descriptor.CtypesFields(fields) def __str__(self): return ", ".join("%s: %s" % (field, self.__getattribute__(field)) for field, _ in TraceItem._fields_) self.ctype = TraceItem def Read(self, trace, offset): return self.ctype.from_buffer(trace, offset) @staticmethod def CtypesFields(fields): return [(field, Descriptor.CTYPE_MAP[format]) for (field, format) in fields] # Please see http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=tools/perf # for the gory details. # Reference: struct perf_file_header in kernel/tools/perf/util/header.h TRACE_HEADER_DESC = Descriptor([ ("magic", "u64"), ("size", "u64"), ("attr_size", "u64"), ("attrs_offset", "u64"), ("attrs_size", "u64"), ("data_offset", "u64"), ("data_size", "u64"), ("event_types_offset", "u64"), ("event_types_size", "u64") ]) # Reference: /usr/include/linux/perf_event.h PERF_EVENT_ATTR_DESC = Descriptor([ ("type", "u32"), ("size", "u32"), ("config", "u64"), ("sample_period_or_freq", "u64"), ("sample_type", "u64"), ("read_format", "u64"), ("flags", "u64"), ("wakeup_events_or_watermark", "u32"), ("bp_type", "u32"), ("bp_addr", "u64"), ("bp_len", "u64") ]) # Reference: /usr/include/linux/perf_event.h PERF_EVENT_HEADER_DESC = Descriptor([ ("type", "u32"), ("misc", "u16"), ("size", "u16") ]) # Reference: kernel/events/core.c PERF_MMAP_EVENT_BODY_DESC = Descriptor([ ("pid", "u32"), ("tid", "u32"), ("addr", "u64"), ("len", "u64"), ("pgoff", "u64") ]) # perf_event_attr.sample_type bits control the set of # perf_sample_event fields. PERF_SAMPLE_IP = 1 << 0 PERF_SAMPLE_TID = 1 << 1 PERF_SAMPLE_TIME = 1 << 2 PERF_SAMPLE_ADDR = 1 << 3 PERF_SAMPLE_READ = 1 << 4 PERF_SAMPLE_CALLCHAIN = 1 << 5 PERF_SAMPLE_ID = 1 << 6 PERF_SAMPLE_CPU = 1 << 7 PERF_SAMPLE_PERIOD = 1 << 8 PERF_SAMPLE_STREAM_ID = 1 << 9 PERF_SAMPLE_RAW = 1 << 10 # Reference: /usr/include/perf_event.h, the comment for PERF_RECORD_SAMPLE. PERF_SAMPLE_EVENT_BODY_FIELDS = [ ("ip", "u64", PERF_SAMPLE_IP), ("pid", "u32", PERF_SAMPLE_TID), ("tid", "u32", PERF_SAMPLE_TID), ("time", "u64", PERF_SAMPLE_TIME), ("addr", "u64", PERF_SAMPLE_ADDR), ("id", "u64", PERF_SAMPLE_ID), ("stream_id", "u64", PERF_SAMPLE_STREAM_ID), ("cpu", "u32", PERF_SAMPLE_CPU), ("res", "u32", PERF_SAMPLE_CPU), ("period", "u64", PERF_SAMPLE_PERIOD), # Don't want to handle read format that comes after the period and # before the callchain and has variable size. ("nr", "u64", PERF_SAMPLE_CALLCHAIN) # Raw data follows the callchain and is ignored. ] PERF_SAMPLE_EVENT_IP_FORMAT = "u64" PERF_RECORD_MMAP = 1 PERF_RECORD_SAMPLE = 9 class TraceReader(object): """Perf (linux-2.6/tools/perf) trace file reader.""" _TRACE_HEADER_MAGIC = 4993446653023372624 def __init__(self, trace_name): self.trace_file = open(trace_name, "r") self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE) self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0) if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC: print >>sys.stderr, "Warning: unsupported trace header magic" self.offset = self.trace_header.data_offset self.limit = self.trace_header.data_offset + self.trace_header.data_size assert self.limit <= self.trace.size(), \ "Trace data limit exceeds trace file size" self.header_size = ctypes.sizeof(PERF_EVENT_HEADER_DESC.ctype) assert self.trace_header.attrs_size != 0, \ "No perf event attributes found in the trace" perf_event_attr = PERF_EVENT_ATTR_DESC.Read(self.trace, self.trace_header.attrs_offset) self.sample_event_body_desc = self._SampleEventBodyDesc( perf_event_attr.sample_type) self.callchain_supported = \ (perf_event_attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0 if self.callchain_supported: self.ip_struct = Descriptor.CTYPE_MAP[PERF_SAMPLE_EVENT_IP_FORMAT] self.ip_size = ctypes.sizeof(self.ip_struct) def ReadEventHeader(self): if self.offset >= self.limit: return None, 0 offset = self.offset header = PERF_EVENT_HEADER_DESC.Read(self.trace, self.offset) self.offset += header.size return header, offset def ReadMmap(self, header, offset): mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace, offset + self.header_size) # Read null-terminated filename. filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info): offset + header.size] mmap_info.filename = HOST_ROOT + filename[:filename.find(chr(0))] return mmap_info def ReadSample(self, header, offset): sample = self.sample_event_body_desc.Read(self.trace, offset + self.header_size) if not self.callchain_supported: return sample sample.ips = [] offset += self.header_size + ctypes.sizeof(sample) for _ in xrange(sample.nr): sample.ips.append( self.ip_struct.from_buffer(self.trace, offset).value) offset += self.ip_size return sample def Dispose(self): self.trace.close() self.trace_file.close() def _SampleEventBodyDesc(self, sample_type): assert (sample_type & PERF_SAMPLE_READ) == 0, \ "Can't hande read format in samples" fields = [(field, format) for (field, format, bit) in PERF_SAMPLE_EVENT_BODY_FIELDS if (bit & sample_type) != 0] return Descriptor(fields) OBJDUMP_SECTION_HEADER_RE = re.compile( r"^\s*\d+\s(\.\S+)\s+[a-f0-9]") OBJDUMP_SYMBOL_LINE_RE = re.compile( r"^([a-f0-9]+)\s(.{7})\s(\S+)\s+([a-f0-9]+)\s+(?:\.hidden\s+)?(.*)$") OBJDUMP_DYNAMIC_SYMBOLS_START_RE = re.compile( r"^DYNAMIC SYMBOL TABLE") OBJDUMP_SKIP_RE = re.compile( r"^.*ld\.so\.cache$") KERNEL_ALLSYMS_FILE = "/proc/kallsyms" PERF_KERNEL_ALLSYMS_RE = re.compile( r".*kallsyms.*") KERNEL_ALLSYMS_LINE_RE = re.compile( r"^([a-f0-9]+)\s(?:t|T)\s(\S+)$") class LibraryRepo(object): def __init__(self): self.infos = [] self.names = set() self.ticks = {} def HasDynamicSymbols(self, filename): if filename.endswith(".ko"): return False process = subprocess.Popen( "%s -h %s" % (OBJDUMP_BIN, filename), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) pipe = process.stdout try: for line in pipe: match = OBJDUMP_SECTION_HEADER_RE.match(line) if match and match.group(1) == 'dynsym': return True finally: pipe.close() assert process.wait() == 0, "Failed to objdump -h %s" % filename return False def Load(self, mmap_info, code_map, options): # Skip kernel mmaps when requested using the fact that their tid # is 0. if mmap_info.tid == 0 and not options.kernel: return True if OBJDUMP_SKIP_RE.match(mmap_info.filename): return True if PERF_KERNEL_ALLSYMS_RE.match(mmap_info.filename): return self._LoadKernelSymbols(code_map) self.infos.append(mmap_info) mmap_info.ticks = 0 mmap_info.unique_name = self._UniqueMmapName(mmap_info) if not os.path.exists(mmap_info.filename): return True # Request section headers (-h), symbols (-t), and dynamic symbols # (-T) from objdump. # Unfortunately, section headers span two lines, so we have to # keep the just seen section name (from the first line in each # section header) in the after_section variable. if self.HasDynamicSymbols(mmap_info.filename): dynamic_symbols = "-T" else: dynamic_symbols = "" process = subprocess.Popen( "%s -h -t %s -C %s" % (OBJDUMP_BIN, dynamic_symbols, mmap_info.filename), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) pipe = process.stdout after_section = None code_sections = set() reloc_sections = set() dynamic = False try: for line in pipe: if after_section: if line.find("CODE") != -1: code_sections.add(after_section) if line.find("RELOC") != -1: reloc_sections.add(after_section) after_section = None continue match = OBJDUMP_SECTION_HEADER_RE.match(line) if match: after_section = match.group(1) continue if OBJDUMP_DYNAMIC_SYMBOLS_START_RE.match(line): dynamic = True continue match = OBJDUMP_SYMBOL_LINE_RE.match(line) if match: start_address = int(match.group(1), 16) origin_offset = start_address flags = match.group(2) section = match.group(3) if section in code_sections: if dynamic or section in reloc_sections: start_address += mmap_info.addr size = int(match.group(4), 16) name = match.group(5) origin = mmap_info.filename code_map.Add(Code(name, start_address, start_address + size, origin, origin_offset)) finally: pipe.close() assert process.wait() == 0, "Failed to objdump %s" % mmap_info.filename def Tick(self, pc): for i, mmap_info in enumerate(self.infos): if mmap_info.addr <= pc < (mmap_info.addr + mmap_info.len): mmap_info.ticks += 1 self.infos[0], self.infos[i] = mmap_info, self.infos[0] return True return False def _UniqueMmapName(self, mmap_info): name = mmap_info.filename index = 1 while name in self.names: name = "%s-%d" % (mmap_info.filename, index) index += 1 self.names.add(name) return name def _LoadKernelSymbols(self, code_map): if not os.path.exists(KERNEL_ALLSYMS_FILE): print >>sys.stderr, "Warning: %s not found" % KERNEL_ALLSYMS_FILE return False kallsyms = open(KERNEL_ALLSYMS_FILE, "r") code = None for line in kallsyms: match = KERNEL_ALLSYMS_LINE_RE.match(line) if match: start_address = int(match.group(1), 16) end_address = start_address name = match.group(2) if code: code.end_address = start_address code_map.Add(code, 16) code = Code(name, start_address, end_address, "kernel", 0) return True def PrintReport(code_map, library_repo, arch, ticks, options): print "Ticks per symbol:" used_code = [code for code in code_map.UsedCode()] used_code.sort(key=lambda x: x.self_ticks, reverse=True) for i, code in enumerate(used_code): code_ticks = code.self_ticks print "%10d %5.1f%% %s [%s]" % (code_ticks, 100. * code_ticks / ticks, code.FullName(), code.origin) if options.disasm_all or i < options.disasm_top: code.PrintAnnotated(arch, options) print print "Ticks per library:" mmap_infos = [m for m in library_repo.infos if m.ticks > 0] mmap_infos.sort(key=lambda m: m.ticks, reverse=True) for mmap_info in mmap_infos: mmap_ticks = mmap_info.ticks print "%10d %5.1f%% %s" % (mmap_ticks, 100. * mmap_ticks / ticks, mmap_info.unique_name) def PrintDot(code_map, options): print "digraph G {" for code in code_map.UsedCode(): if code.self_ticks < 10: continue print "n%d [shape=box,label=\"%s\"];" % (code.id, code.name) if code.callee_ticks: for callee, ticks in code.callee_ticks.iteritems(): print "n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks) print "}" if __name__ == "__main__": parser = optparse.OptionParser(USAGE) parser.add_option("--snapshot-log", default="obj/release/snapshot.log", help="V8 snapshot log file name [default: %default]") parser.add_option("--log", default="v8.log", help="V8 log file name [default: %default]") parser.add_option("--snapshot", default=False, action="store_true", help="process V8 snapshot log [default: %default]") parser.add_option("--trace", default="perf.data", help="perf trace file name [default: %default]") parser.add_option("--kernel", default=False, action="store_true", help="process kernel entries [default: %default]") parser.add_option("--disasm-top", default=0, type="int", help=("number of top symbols to disassemble and annotate " "[default: %default]")) parser.add_option("--disasm-all", default=False, action="store_true", help=("disassemble and annotate all used symbols " "[default: %default]")) parser.add_option("--dot", default=False, action="store_true", help="produce dot output (WIP) [default: %default]") parser.add_option("--quiet", "-q", default=False, action="store_true", help="no auxiliary messages [default: %default]") parser.add_option("--gc-fake-mmap", default="/tmp/__v8_gc__", help="gc fake mmap file [default: %default]") parser.add_option("--objdump", default="/usr/bin/objdump", help="objdump tool to use [default: %default]") parser.add_option("--host-root", default="", help="Path to the host root [default: %default]") options, args = parser.parse_args() if not options.quiet: if options.snapshot: print "V8 logs: %s, %s, %s.ll" % (options.snapshot_log, options.log, options.log) else: print "V8 log: %s, %s.ll (no snapshot)" % (options.log, options.log) print "Perf trace file: %s" % options.trace V8_GC_FAKE_MMAP = options.gc_fake_mmap HOST_ROOT = options.host_root if os.path.exists(options.objdump): disasm.OBJDUMP_BIN = options.objdump OBJDUMP_BIN = options.objdump else: print "Cannot find %s, falling back to default objdump" % options.objdump # Stats. events = 0 ticks = 0 missed_ticks = 0 really_missed_ticks = 0 optimized_ticks = 0 generated_ticks = 0 v8_internal_ticks = 0 mmap_time = 0 sample_time = 0 # Process the snapshot log to fill the snapshot name map. snapshot_name_map = {} if options.snapshot: snapshot_log_reader = SnapshotLogReader(log_name=options.snapshot_log) snapshot_name_map = snapshot_log_reader.ReadNameMap() # Initialize the log reader. code_map = CodeMap() log_reader = LogReader(log_name=options.log + ".ll", code_map=code_map, snapshot_pos_to_name=snapshot_name_map) if not options.quiet: print "Generated code architecture: %s" % log_reader.arch print sys.stdout.flush() # Process the code and trace logs. library_repo = LibraryRepo() log_reader.ReadUpToGC() trace_reader = TraceReader(options.trace) while True: header, offset = trace_reader.ReadEventHeader() if not header: break events += 1 if header.type == PERF_RECORD_MMAP: start = time.time() mmap_info = trace_reader.ReadMmap(header, offset) if mmap_info.filename == HOST_ROOT + V8_GC_FAKE_MMAP: log_reader.ReadUpToGC() else: library_repo.Load(mmap_info, code_map, options) mmap_time += time.time() - start elif header.type == PERF_RECORD_SAMPLE: ticks += 1 start = time.time() sample = trace_reader.ReadSample(header, offset) code = code_map.Find(sample.ip) if code: code.Tick(sample.ip) if code.codetype == Code.OPTIMIZED: optimized_ticks += 1 elif code.codetype == Code.FULL_CODEGEN: generated_ticks += 1 elif code.codetype == Code.V8INTERNAL: v8_internal_ticks += 1 else: missed_ticks += 1 if not library_repo.Tick(sample.ip) and not code: really_missed_ticks += 1 if trace_reader.callchain_supported: for ip in sample.ips: caller_code = code_map.Find(ip) if caller_code: if code: caller_code.CalleeTick(code) code = caller_code sample_time += time.time() - start if options.dot: PrintDot(code_map, options) else: PrintReport(code_map, library_repo, log_reader.arch, ticks, options) if not options.quiet: def PrintTicks(number, total, description): print("%10d %5.1f%% ticks in %s" % (number, 100.0*number/total, description)) print print "Stats:" print "%10d total trace events" % events print "%10d total ticks" % ticks print "%10d ticks not in symbols" % missed_ticks unaccounted = "unaccounted ticks" if really_missed_ticks > 0: unaccounted += " (probably in the kernel, try --kernel)" PrintTicks(really_missed_ticks, ticks, unaccounted) PrintTicks(optimized_ticks, ticks, "ticks in optimized code") PrintTicks(generated_ticks, ticks, "ticks in other lazily compiled code") PrintTicks(v8_internal_ticks, ticks, "ticks in v8::internal::*") print "%10d total symbols" % len([c for c in code_map.AllCode()]) print "%10d used symbols" % len([c for c in code_map.UsedCode()]) print "%9.2fs library processing time" % mmap_time print "%9.2fs tick processing time" % sample_time log_reader.Dispose() trace_reader.Dispose() node-v4.2.6/deps/v8/tools/logreader.js000644 000766 000024 00000014427 12650222326 017710 0ustar00iojsstaff000000 000000 // Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * @fileoverview Log Reader is used to process log file produced by V8. */ /** * Base class for processing log files. * * @param {Array.} dispatchTable A table used for parsing and processing * log records. * @param {boolean} timedRange Ignore ticks outside timed range. * @param {boolean} pairwiseTimedRange Ignore ticks outside pairs of timer * markers. * @constructor */ function LogReader(dispatchTable, timedRange, pairwiseTimedRange) { /** * @type {Array.} */ this.dispatchTable_ = dispatchTable; /** * @type {boolean} */ this.timedRange_ = timedRange; /** * @type {boolean} */ this.pairwiseTimedRange_ = pairwiseTimedRange; if (pairwiseTimedRange) { this.timedRange_ = true; } /** * Current line. * @type {number} */ this.lineNum_ = 0; /** * CSV lines parser. * @type {CsvParser} */ this.csvParser_ = new CsvParser(); /** * Keeps track of whether we've seen a "current-time" tick yet. * @type {boolean} */ this.hasSeenTimerMarker_ = false; /** * List of log lines seen since last "current-time" tick. * @type {Array.} */ this.logLinesSinceLastTimerMarker_ = []; }; /** * Used for printing error messages. * * @param {string} str Error message. */ LogReader.prototype.printError = function(str) { // Do nothing. }; /** * Processes a portion of V8 profiler event log. * * @param {string} chunk A portion of log. */ LogReader.prototype.processLogChunk = function(chunk) { this.processLog_(chunk.split('\n')); }; /** * Processes a line of V8 profiler event log. * * @param {string} line A line of log. */ LogReader.prototype.processLogLine = function(line) { if (!this.timedRange_) { this.processLog_([line]); return; } if (line.startsWith("current-time")) { if (this.hasSeenTimerMarker_) { this.processLog_(this.logLinesSinceLastTimerMarker_); this.logLinesSinceLastTimerMarker_ = []; // In pairwise mode, a "current-time" line ends the timed range. if (this.pairwiseTimedRange_) { this.hasSeenTimerMarker_ = false; } } else { this.hasSeenTimerMarker_ = true; } } else { if (this.hasSeenTimerMarker_) { this.logLinesSinceLastTimerMarker_.push(line); } else if (!line.startsWith("tick")) { this.processLog_([line]); } } }; /** * Processes stack record. * * @param {number} pc Program counter. * @param {number} func JS Function. * @param {Array.} stack String representation of a stack. * @return {Array.} Processed stack. */ LogReader.prototype.processStack = function(pc, func, stack) { var fullStack = func ? [pc, func] : [pc]; var prevFrame = pc; for (var i = 0, n = stack.length; i < n; ++i) { var frame = stack[i]; var firstChar = frame.charAt(0); if (firstChar == '+' || firstChar == '-') { // An offset from the previous frame. prevFrame += parseInt(frame, 16); fullStack.push(prevFrame); // Filter out possible 'overflow' string. } else if (firstChar != 'o') { fullStack.push(parseInt(frame, 16)); } else { print("dropping: " + frame); } } return fullStack; }; /** * Returns whether a particular dispatch must be skipped. * * @param {!Object} dispatch Dispatch record. * @return {boolean} True if dispatch must be skipped. */ LogReader.prototype.skipDispatch = function(dispatch) { return false; }; /** * Does a dispatch of a log record. * * @param {Array.} fields Log record. * @private */ LogReader.prototype.dispatchLogRow_ = function(fields) { // Obtain the dispatch. var command = fields[0]; if (!(command in this.dispatchTable_)) return; var dispatch = this.dispatchTable_[command]; if (dispatch === null || this.skipDispatch(dispatch)) { return; } // Parse fields. var parsedFields = []; for (var i = 0; i < dispatch.parsers.length; ++i) { var parser = dispatch.parsers[i]; if (parser === null) { parsedFields.push(fields[1 + i]); } else if (typeof parser == 'function') { parsedFields.push(parser(fields[1 + i])); } else { // var-args parsedFields.push(fields.slice(1 + i)); break; } } // Run the processor. dispatch.processor.apply(this, parsedFields); }; /** * Processes log lines. * * @param {Array.} lines Log lines. * @private */ LogReader.prototype.processLog_ = function(lines) { for (var i = 0, n = lines.length; i < n; ++i, ++this.lineNum_) { var line = lines[i]; if (!line) { continue; } try { var fields = this.csvParser_.parseLine(line); this.dispatchLogRow_(fields); } catch (e) { this.printError('line ' + (this.lineNum_ + 1) + ': ' + (e.message || e)); } } }; node-v4.2.6/deps/v8/tools/mac-nm000755 000766 000024 00000001352 12650222326 016475 0ustar00iojsstaff000000 000000 #!/bin/sh # This script is a wrapper for OS X nm(1) tool. nm(1) perform C++ function # names demangling, so we're piping its output to c++filt(1) tool which does it. # But c++filt(1) comes with XCode (as a part of GNU binutils), so it doesn't # guaranteed to exist on a system. # # An alternative approach is to perform demangling in tick processor, but # for GNU C++ ABI this is a complex process (see cp-demangle.c sources), and # can't be done partially, because term boundaries are plain text symbols, such # as 'N', 'E', so one can't just do a search through a function name, it really # needs to be parsed, which requires a lot of knowledge to be coded in. if [ "`which c++filt`" == "" ]; then nm "$@" else nm "$@" | c++filt -p -i fi node-v4.2.6/deps/v8/tools/mac-tick-processor000755 000766 000024 00000000300 12650222326 021022 0ustar00iojsstaff000000 000000 #!/bin/sh # A wrapper script to call 'linux-tick-processor' with Mac-specific settings. tools_path=`cd $(dirname "$0");pwd` $tools_path/linux-tick-processor --mac --nm=$tools_path/mac-nm $@ node-v4.2.6/deps/v8/tools/mingw-generate-makefiles.sh000755 000766 000024 00000007525 12650222326 022615 0ustar00iojsstaff000000 000000 #!/bin/sh # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Monkey-patch GYP. cat > build/gyp/gyp.mingw << EOF #!/usr/bin/env python # Copyright (c) 2009 Google Inc. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys # TODO(mark): sys.path manipulation is some temporary testing stuff. try: import gyp except ImportError, e: import os.path sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'pylib')) import gyp def MonkeyBuildFileTargets(target_list, build_file): """From a target_list, returns the subset from the specified build_file. """ build_file = build_file.replace('/', '\\\\') return [p for p in target_list if gyp.common.BuildFile(p) == build_file] gyp.common.BuildFileTargets = MonkeyBuildFileTargets import gyp.generator.make import os def Monkey_ITIP(self): """Returns the location of the final output for an installable target.""" sep = os.path.sep # Xcode puts shared_library results into PRODUCT_DIR, and some gyp files # rely on this. Emulate this behavior for mac. if (self.type == 'shared_library' and (self.flavor != 'mac' or self.toolset != 'target')): # Install all shared libs into a common directory (per toolset) for # convenient access with LD_LIBRARY_PATH. return '\$(builddir)%slib.%s%s%s' % (sep, self.toolset, sep, self.alias) return '\$(builddir)' + sep + self.alias gyp.generator.make.MakefileWriter._InstallableTargetInstallPath = Monkey_ITIP if __name__ == '__main__': sys.exit(gyp.main(sys.argv[1:])) EOF # Delete old generated Makefiles. find out -name '*.mk' -or -name 'Makefile*' -exec rm {} \; # Generate fresh Makefiles. mv build/gyp/gyp build/gyp/gyp.original mv build/gyp/gyp.mingw build/gyp/gyp make out/Makefile.ia32 mv build/gyp/gyp build/gyp/gyp.mingw mv build/gyp/gyp.original build/gyp/gyp # Patch generated Makefiles: replace most backslashes with forward slashes, # fix library names in linker flags. FILES=$(find out -name '*.mk' -or -name 'Makefile*') for F in $FILES ; do echo "Patching $F..." cp $F $F.orig cat $F.orig \ | sed -e 's|\([)a-zA-Z0-9]\)\\\([a-zA-Z]\)|\1/\2|g' \ -e 's|\([)a-zA-Z0-9]\)\\\\\([a-zA-Z]\)|\1/\2|g' \ -e 's|'%s/n'|'%s\\\\n'|g' \ -e 's|-lwinmm\.lib|-lwinmm|g' \ -e 's|-lws2_32\.lib|-lws2_32|g' \ > $F rm $F.orig done node-v4.2.6/deps/v8/tools/nacl-run.py000755 000766 000024 00000011423 12650222326 017473 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This script executes the passed command line using the Native Client # 'sel_ldr' container. It is derived from android-run.py. import os from os.path import join, dirname, abspath import re import subprocess import sys import tempfile def Check(output, errors): failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID') for s in output.split('\n')]) return 1 if failed else 0 def Execute(cmdline): (fd_out, outname) = tempfile.mkstemp() (fd_err, errname) = tempfile.mkstemp() process = subprocess.Popen( args=cmdline, shell=True, stdout=fd_out, stderr=fd_err, ) exit_code = process.wait() os.close(fd_out) os.close(fd_err) output = file(outname).read() errors = file(errname).read() os.unlink(outname) os.unlink(errname) sys.stdout.write(output) sys.stderr.write(errors) return exit_code or Check(output, errors) def Escape(arg): def ShouldEscape(): for x in arg: if not x.isalnum() and x != '-' and x != '_': return True return False return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"')) def WriteToTemporaryFile(data): (fd, fname) = tempfile.mkstemp() os.close(fd) tmp_file = open(fname, "w") tmp_file.write(data) tmp_file.close() return fname def GetNaClArchFromNexe(nexe): try: p = subprocess.Popen(['file', nexe], stdout=subprocess.PIPE) out, err = p.communicate() lines = [re.sub("\s+", " " , line) for line in out.split('\n')] if lines[0].find(": ELF 32-bit LSB executable, Intel 80386") > 0: return "x86_32" if lines[0].find(": ELF 64-bit LSB executable, x86-64") > 0: return "x86_64" except: print 'file ' + sys.argv[1] + ' failed' return None def GetNaClResources(nexe): nacl_sdk_dir = os.environ["NACL_SDK_ROOT"] nacl_arch = GetNaClArchFromNexe(nexe) if sys.platform.startswith("linux"): platform = "linux" elif sys.platform == "darwin": platform = "mac" else: print("NaCl V8 testing is supported on Linux and MacOS only.") sys.exit(1) if nacl_arch is "x86_64": toolchain = platform + "_x86_glibc" sel_ldr = "sel_ldr_x86_64" irt = "irt_core_x86_64.nexe" libdir = "lib64" elif nacl_arch is "x86_32": toolchain = platform + "_x86_glibc" sel_ldr = "sel_ldr_x86_32" irt = "irt_core_x86_32.nexe" libdir = "lib32" elif nacl_arch is "arm": print("NaCl V8 ARM support is not ready yet.") sys.exit(1) else: print("Invalid nexe %s with NaCl arch %s" % (nexe, nacl_arch)) sys.exit(1) nacl_sel_ldr = os.path.join(nacl_sdk_dir, "tools", sel_ldr) nacl_irt = os.path.join(nacl_sdk_dir, "tools", irt) return (nacl_sdk_dir, nacl_sel_ldr, nacl_irt) def Main(): if (len(sys.argv) == 1): print("Usage: %s " % sys.argv[0]) return 1 args = [Escape(arg) for arg in sys.argv[1:]] (nacl_sdk_dir, nacl_sel_ldr, nacl_irt) = GetNaClResources(sys.argv[1]) # sel_ldr Options: # -c -c: disable validation (for performance) # -a: allow file access # -B : load the IRT command = ' '.join([nacl_sel_ldr, '-c', '-c', '-a', '-B', nacl_irt, '--'] + args) error_code = Execute(command) return error_code if __name__ == '__main__': sys.exit(Main()) node-v4.2.6/deps/v8/tools/ninja/000755 000766 000024 00000000000 12650222326 016475 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/oom_dump/000755 000766 000024 00000000000 12650222326 017215 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/OWNERS000644 000766 000024 00000000030 12650222326 016327 0ustar00iojsstaff000000 000000 machenbach@chromium.org node-v4.2.6/deps/v8/tools/parser-shell.cc000644 000766 000024 00000017053 12650222326 020314 0ustar00iojsstaff000000 000000 // Copyright 2014 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include #include #include "src/v8.h" #include "include/libplatform/libplatform.h" #include "src/api.h" #include "src/compiler.h" #include "src/scanner-character-streams.h" #include "tools/shell-utils.h" #include "src/parser.h" #include "src/preparse-data-format.h" #include "src/preparse-data.h" #include "src/preparser.h" using namespace v8::internal; class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { void* data = AllocateUninitialized(length); return data == NULL ? data : memset(data, 0, length); } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } virtual void Free(void* data, size_t) { free(data); } }; class StringResource8 : public v8::String::ExternalOneByteStringResource { public: StringResource8(const char* data, int length) : data_(data), length_(length) { } virtual size_t length() const { return length_; } virtual const char* data() const { return data_; } private: const char* data_; int length_; }; std::pair RunBaselineParser( const char* fname, Encoding encoding, int repeat, v8::Isolate* isolate, v8::Local context) { int length = 0; const byte* source = ReadFileAndRepeat(fname, &length, repeat); v8::Local source_handle; switch (encoding) { case UTF8: { source_handle = v8::String::NewFromUtf8( isolate, reinterpret_cast(source), v8::NewStringType::kNormal).ToLocalChecked(); break; } case UTF16: { source_handle = v8::String::NewFromTwoByte( isolate, reinterpret_cast(source), v8::NewStringType::kNormal, length / 2).ToLocalChecked(); break; } case LATIN1: { StringResource8* string_resource = new StringResource8(reinterpret_cast(source), length); source_handle = v8::String::NewExternalOneByte(isolate, string_resource) .ToLocalChecked(); break; } } v8::base::TimeDelta parse_time1, parse_time2; Handle

Chrome V8 profiling log processor

Process V8's profiling information log (sampling profiler tick information) in your browser. Particularly useful if you don't have the V8 shell (d8) at hand on your system. You still have to run Chrome with the appropriate command line flags to produce the profiling log.

Usage:

Click on the button and browse to the profiling log file (usually, v8.log). Process will start automatically and the output will be visible in the below text area.

Limitations and disclaimer:

This page offers a subset of the functionalities of the command-line tick processor utility in the V8 repository. In particular, this page cannot access the command-line utility that provides library symbol information, hence the [C++] section of the output stays empty. Also consider that this web-based tool is provided only for convenience and quick reference, you should refer to the command-line version for full output.

Copyright the V8 Authors - Last change to this page: 12/12/2012

node-v4.2.6/deps/v8/tools/tickprocessor-driver.js000644 000766 000024 00000006044 12650222326 022123 0ustar00iojsstaff000000 000000 // Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Tick Processor's code flow. function processArguments(args) { var processor = new ArgumentsProcessor(args); if (processor.parse()) { return processor.result(); } else { processor.printUsageAndExit(); } } function initSourceMapSupport() { // Pull dev tools source maps into our name space. SourceMap = WebInspector.SourceMap; // Overwrite the load function to load scripts synchronously. SourceMap.load = function(sourceMapURL) { var content = readFile(sourceMapURL); var sourceMapObject = (JSON.parse(content)); return new SourceMap(sourceMapURL, sourceMapObject); }; } var entriesProviders = { 'unix': UnixCppEntriesProvider, 'windows': WindowsCppEntriesProvider, 'mac': MacCppEntriesProvider }; var params = processArguments(arguments); var sourceMap = null; if (params.sourceMap) { initSourceMapSupport(); sourceMap = SourceMap.load(params.sourceMap); } var snapshotLogProcessor; if (params.snapshotLogFileName) { snapshotLogProcessor = new SnapshotLogProcessor(); snapshotLogProcessor.processLogFile(params.snapshotLogFileName); } var tickProcessor = new TickProcessor( new (entriesProviders[params.platform])(params.nm, params.targetRootFS), params.separateIc, params.callGraphSize, params.ignoreUnknown, params.stateFilter, snapshotLogProcessor, params.distortion, params.range, sourceMap, params.timedRange, params.pairwiseTimedRange); tickProcessor.processLogFile(params.logFileName); tickProcessor.printStatistics(); node-v4.2.6/deps/v8/tools/tickprocessor.js000644 000766 000024 00000073471 12650222326 020642 0ustar00iojsstaff000000 000000 // Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. function inherits(childCtor, parentCtor) { childCtor.prototype.__proto__ = parentCtor.prototype; }; function V8Profile(separateIc) { Profile.call(this); if (!separateIc) { this.skipThisFunction = function(name) { return V8Profile.IC_RE.test(name); }; } }; inherits(V8Profile, Profile); V8Profile.IC_RE = /^(?:CallIC|LoadIC|StoreIC)|(?:Builtin: (?:Keyed)?(?:Call|Load|Store)IC_)/; /** * A thin wrapper around shell's 'read' function showing a file name on error. */ function readFile(fileName) { try { return read(fileName); } catch (e) { print(fileName + ': ' + (e.message || e)); throw e; } } /** * Parser for dynamic code optimization state. */ function parseState(s) { switch (s) { case "": return Profile.CodeState.COMPILED; case "~": return Profile.CodeState.OPTIMIZABLE; case "*": return Profile.CodeState.OPTIMIZED; } throw new Error("unknown code state: " + s); } function SnapshotLogProcessor() { LogReader.call(this, { 'code-creation': { parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], processor: this.processCodeCreation }, 'code-move': { parsers: [parseInt, parseInt], processor: this.processCodeMove }, 'code-delete': { parsers: [parseInt], processor: this.processCodeDelete }, 'function-creation': null, 'function-move': null, 'function-delete': null, 'sfi-move': null, 'snapshot-pos': { parsers: [parseInt, parseInt], processor: this.processSnapshotPosition }}); V8Profile.prototype.handleUnknownCode = function(operation, addr) { var op = Profile.Operation; switch (operation) { case op.MOVE: print('Snapshot: Code move event for unknown code: 0x' + addr.toString(16)); break; case op.DELETE: print('Snapshot: Code delete event for unknown code: 0x' + addr.toString(16)); break; } }; this.profile_ = new V8Profile(); this.serializedEntries_ = []; } inherits(SnapshotLogProcessor, LogReader); SnapshotLogProcessor.prototype.processCodeCreation = function( type, kind, start, size, name, maybe_func) { if (maybe_func.length) { var funcAddr = parseInt(maybe_func[0]); var state = parseState(maybe_func[1]); this.profile_.addFuncCode(type, name, start, size, funcAddr, state); } else { this.profile_.addCode(type, name, start, size); } }; SnapshotLogProcessor.prototype.processCodeMove = function(from, to) { this.profile_.moveCode(from, to); }; SnapshotLogProcessor.prototype.processCodeDelete = function(start) { this.profile_.deleteCode(start); }; SnapshotLogProcessor.prototype.processSnapshotPosition = function(addr, pos) { this.serializedEntries_[pos] = this.profile_.findEntry(addr); }; SnapshotLogProcessor.prototype.processLogFile = function(fileName) { var contents = readFile(fileName); this.processLogChunk(contents); }; SnapshotLogProcessor.prototype.getSerializedEntryName = function(pos) { var entry = this.serializedEntries_[pos]; return entry ? entry.getRawName() : null; }; function TickProcessor( cppEntriesProvider, separateIc, callGraphSize, ignoreUnknown, stateFilter, snapshotLogProcessor, distortion, range, sourceMap, timedRange, pairwiseTimedRange) { LogReader.call(this, { 'shared-library': { parsers: [null, parseInt, parseInt], processor: this.processSharedLibrary }, 'code-creation': { parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], processor: this.processCodeCreation }, 'code-move': { parsers: [parseInt, parseInt], processor: this.processCodeMove }, 'code-delete': { parsers: [parseInt], processor: this.processCodeDelete }, 'sfi-move': { parsers: [parseInt, parseInt], processor: this.processFunctionMove }, 'snapshot-pos': { parsers: [parseInt, parseInt], processor: this.processSnapshotPosition }, 'tick': { parsers: [parseInt, parseInt, parseInt, parseInt, parseInt, 'var-args'], processor: this.processTick }, 'heap-sample-begin': { parsers: [null, null, parseInt], processor: this.processHeapSampleBegin }, 'heap-sample-end': { parsers: [null, null], processor: this.processHeapSampleEnd }, 'timer-event-start' : { parsers: [null, null, null], processor: this.advanceDistortion }, 'timer-event-end' : { parsers: [null, null, null], processor: this.advanceDistortion }, // Ignored events. 'profiler': null, 'function-creation': null, 'function-move': null, 'function-delete': null, 'heap-sample-item': null, 'current-time': null, // Handled specially, not parsed. // Obsolete row types. 'code-allocate': null, 'begin-code-region': null, 'end-code-region': null }, timedRange, pairwiseTimedRange); this.cppEntriesProvider_ = cppEntriesProvider; this.callGraphSize_ = callGraphSize; this.ignoreUnknown_ = ignoreUnknown; this.stateFilter_ = stateFilter; this.snapshotLogProcessor_ = snapshotLogProcessor; this.sourceMap = sourceMap; this.deserializedEntriesNames_ = []; var ticks = this.ticks_ = { total: 0, unaccounted: 0, excluded: 0, gc: 0 }; distortion = parseInt(distortion); // Convert picoseconds to nanoseconds. this.distortion_per_entry = isNaN(distortion) ? 0 : (distortion / 1000); this.distortion = 0; var rangelimits = range ? range.split(",") : []; var range_start = parseInt(rangelimits[0]); var range_end = parseInt(rangelimits[1]); // Convert milliseconds to nanoseconds. this.range_start = isNaN(range_start) ? -Infinity : (range_start * 1000); this.range_end = isNaN(range_end) ? Infinity : (range_end * 1000) V8Profile.prototype.handleUnknownCode = function( operation, addr, opt_stackPos) { var op = Profile.Operation; switch (operation) { case op.MOVE: print('Code move event for unknown code: 0x' + addr.toString(16)); break; case op.DELETE: print('Code delete event for unknown code: 0x' + addr.toString(16)); break; case op.TICK: // Only unknown PCs (the first frame) are reported as unaccounted, // otherwise tick balance will be corrupted (this behavior is compatible // with the original tickprocessor.py script.) if (opt_stackPos == 0) { ticks.unaccounted++; } break; } }; this.profile_ = new V8Profile(separateIc); this.codeTypes_ = {}; // Count each tick as a time unit. this.viewBuilder_ = new ViewBuilder(1); this.lastLogFileName_ = null; this.generation_ = 1; this.currentProducerProfile_ = null; }; inherits(TickProcessor, LogReader); TickProcessor.VmStates = { JS: 0, GC: 1, COMPILER: 2, OTHER: 3, EXTERNAL: 4, IDLE: 5 }; TickProcessor.CodeTypes = { CPP: 0, SHARED_LIB: 1 }; // Otherwise, this is JS-related code. We are not adding it to // codeTypes_ map because there can be zillions of them. TickProcessor.CALL_PROFILE_CUTOFF_PCT = 2.0; TickProcessor.CALL_GRAPH_SIZE = 5; /** * @override */ TickProcessor.prototype.printError = function(str) { print(str); }; TickProcessor.prototype.setCodeType = function(name, type) { this.codeTypes_[name] = TickProcessor.CodeTypes[type]; }; TickProcessor.prototype.isSharedLibrary = function(name) { return this.codeTypes_[name] == TickProcessor.CodeTypes.SHARED_LIB; }; TickProcessor.prototype.isCppCode = function(name) { return this.codeTypes_[name] == TickProcessor.CodeTypes.CPP; }; TickProcessor.prototype.isJsCode = function(name) { return name !== "UNKNOWN" && !(name in this.codeTypes_); }; TickProcessor.prototype.processLogFile = function(fileName) { this.lastLogFileName_ = fileName; var line; while (line = readline()) { this.processLogLine(line); } }; TickProcessor.prototype.processLogFileInTest = function(fileName) { // Hack file name to avoid dealing with platform specifics. this.lastLogFileName_ = 'v8.log'; var contents = readFile(fileName); this.processLogChunk(contents); }; TickProcessor.prototype.processSharedLibrary = function( name, startAddr, endAddr) { var entry = this.profile_.addLibrary(name, startAddr, endAddr); this.setCodeType(entry.getName(), 'SHARED_LIB'); var self = this; var libFuncs = this.cppEntriesProvider_.parseVmSymbols( name, startAddr, endAddr, function(fName, fStart, fEnd) { self.profile_.addStaticCode(fName, fStart, fEnd); self.setCodeType(fName, 'CPP'); }); }; TickProcessor.prototype.processCodeCreation = function( type, kind, start, size, name, maybe_func) { name = this.deserializedEntriesNames_[start] || name; if (maybe_func.length) { var funcAddr = parseInt(maybe_func[0]); var state = parseState(maybe_func[1]); this.profile_.addFuncCode(type, name, start, size, funcAddr, state); } else { this.profile_.addCode(type, name, start, size); } }; TickProcessor.prototype.processCodeMove = function(from, to) { this.profile_.moveCode(from, to); }; TickProcessor.prototype.processCodeDelete = function(start) { this.profile_.deleteCode(start); }; TickProcessor.prototype.processFunctionMove = function(from, to) { this.profile_.moveFunc(from, to); }; TickProcessor.prototype.processSnapshotPosition = function(addr, pos) { if (this.snapshotLogProcessor_) { this.deserializedEntriesNames_[addr] = this.snapshotLogProcessor_.getSerializedEntryName(pos); } }; TickProcessor.prototype.includeTick = function(vmState) { return this.stateFilter_ == null || this.stateFilter_ == vmState; }; TickProcessor.prototype.processTick = function(pc, ns_since_start, is_external_callback, tos_or_external_callback, vmState, stack) { this.distortion += this.distortion_per_entry; ns_since_start -= this.distortion; if (ns_since_start < this.range_start || ns_since_start > this.range_end) { return; } this.ticks_.total++; if (vmState == TickProcessor.VmStates.GC) this.ticks_.gc++; if (!this.includeTick(vmState)) { this.ticks_.excluded++; return; } if (is_external_callback) { // Don't use PC when in external callback code, as it can point // inside callback's code, and we will erroneously report // that a callback calls itself. Instead we use tos_or_external_callback, // as simply resetting PC will produce unaccounted ticks. pc = tos_or_external_callback; tos_or_external_callback = 0; } else if (tos_or_external_callback) { // Find out, if top of stack was pointing inside a JS function // meaning that we have encountered a frameless invocation. var funcEntry = this.profile_.findEntry(tos_or_external_callback); if (!funcEntry || !funcEntry.isJSFunction || !funcEntry.isJSFunction()) { tos_or_external_callback = 0; } } this.profile_.recordTick(this.processStack(pc, tos_or_external_callback, stack)); }; TickProcessor.prototype.advanceDistortion = function() { this.distortion += this.distortion_per_entry; } TickProcessor.prototype.processHeapSampleBegin = function(space, state, ticks) { if (space != 'Heap') return; this.currentProducerProfile_ = new CallTree(); }; TickProcessor.prototype.processHeapSampleEnd = function(space, state) { if (space != 'Heap' || !this.currentProducerProfile_) return; print('Generation ' + this.generation_ + ':'); var tree = this.currentProducerProfile_; tree.computeTotalWeights(); var producersView = this.viewBuilder_.buildView(tree); // Sort by total time, desc, then by name, desc. producersView.sort(function(rec1, rec2) { return rec2.totalTime - rec1.totalTime || (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1); }); this.printHeavyProfile(producersView.head.children); this.currentProducerProfile_ = null; this.generation_++; }; TickProcessor.prototype.printStatistics = function() { print('Statistical profiling result from ' + this.lastLogFileName_ + ', (' + this.ticks_.total + ' ticks, ' + this.ticks_.unaccounted + ' unaccounted, ' + this.ticks_.excluded + ' excluded).'); if (this.ticks_.total == 0) return; var flatProfile = this.profile_.getFlatProfile(); var flatView = this.viewBuilder_.buildView(flatProfile); // Sort by self time, desc, then by name, desc. flatView.sort(function(rec1, rec2) { return rec2.selfTime - rec1.selfTime || (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1); }); var totalTicks = this.ticks_.total; if (this.ignoreUnknown_) { totalTicks -= this.ticks_.unaccounted; } // Count library ticks var flatViewNodes = flatView.head.children; var self = this; var libraryTicks = 0; this.printHeader('Shared libraries'); this.printEntries(flatViewNodes, totalTicks, null, function(name) { return self.isSharedLibrary(name); }, function(rec) { libraryTicks += rec.selfTime; }); var nonLibraryTicks = totalTicks - libraryTicks; var jsTicks = 0; this.printHeader('JavaScript'); this.printEntries(flatViewNodes, totalTicks, nonLibraryTicks, function(name) { return self.isJsCode(name); }, function(rec) { jsTicks += rec.selfTime; }); var cppTicks = 0; this.printHeader('C++'); this.printEntries(flatViewNodes, totalTicks, nonLibraryTicks, function(name) { return self.isCppCode(name); }, function(rec) { cppTicks += rec.selfTime; }); this.printHeader('Summary'); this.printLine('JavaScript', jsTicks, totalTicks, nonLibraryTicks); this.printLine('C++', cppTicks, totalTicks, nonLibraryTicks); this.printLine('GC', this.ticks_.gc, totalTicks, nonLibraryTicks); this.printLine('Shared libraries', libraryTicks, totalTicks, null); if (!this.ignoreUnknown_ && this.ticks_.unaccounted > 0) { this.printLine('Unaccounted', this.ticks_.unaccounted, this.ticks_.total, null); } print('\n [C++ entry points]:'); print(' ticks cpp total name'); var c_entry_functions = this.profile_.getCEntryProfile(); var total_c_entry = c_entry_functions[0].ticks; for (var i = 1; i < c_entry_functions.length; i++) { c = c_entry_functions[i]; this.printLine(c.name, c.ticks, total_c_entry, totalTicks); } this.printHeavyProfHeader(); var heavyProfile = this.profile_.getBottomUpProfile(); var heavyView = this.viewBuilder_.buildView(heavyProfile); // To show the same percentages as in the flat profile. heavyView.head.totalTime = totalTicks; // Sort by total time, desc, then by name, desc. heavyView.sort(function(rec1, rec2) { return rec2.totalTime - rec1.totalTime || (rec2.internalFuncName < rec1.internalFuncName ? -1 : 1); }); this.printHeavyProfile(heavyView.head.children); }; function padLeft(s, len) { s = s.toString(); if (s.length < len) { var padLength = len - s.length; if (!(padLength in padLeft)) { padLeft[padLength] = new Array(padLength + 1).join(' '); } s = padLeft[padLength] + s; } return s; }; TickProcessor.prototype.printHeader = function(headerTitle) { print('\n [' + headerTitle + ']:'); print(' ticks total nonlib name'); }; TickProcessor.prototype.printLine = function( entry, ticks, totalTicks, nonLibTicks) { var pct = ticks * 100 / totalTicks; var nonLibPct = nonLibTicks != null ? padLeft((ticks * 100 / nonLibTicks).toFixed(1), 5) + '% ' : ' '; print(' ' + padLeft(ticks, 5) + ' ' + padLeft(pct.toFixed(1), 5) + '% ' + nonLibPct + entry); } TickProcessor.prototype.printHeavyProfHeader = function() { print('\n [Bottom up (heavy) profile]:'); print(' Note: percentage shows a share of a particular caller in the ' + 'total\n' + ' amount of its parent calls.'); print(' Callers occupying less than ' + TickProcessor.CALL_PROFILE_CUTOFF_PCT.toFixed(1) + '% are not shown.\n'); print(' ticks parent name'); }; TickProcessor.prototype.processProfile = function( profile, filterP, func) { for (var i = 0, n = profile.length; i < n; ++i) { var rec = profile[i]; if (!filterP(rec.internalFuncName)) { continue; } func(rec); } }; TickProcessor.prototype.getLineAndColumn = function(name) { var re = /:([0-9]+):([0-9]+)$/; var array = re.exec(name); if (!array) { return null; } return {line: array[1], column: array[2]}; } TickProcessor.prototype.hasSourceMap = function() { return this.sourceMap != null; }; TickProcessor.prototype.formatFunctionName = function(funcName) { if (!this.hasSourceMap()) { return funcName; } var lc = this.getLineAndColumn(funcName); if (lc == null) { return funcName; } // in source maps lines and columns are zero based var lineNumber = lc.line - 1; var column = lc.column - 1; var entry = this.sourceMap.findEntry(lineNumber, column); var sourceFile = entry[2]; var sourceLine = entry[3] + 1; var sourceColumn = entry[4] + 1; return sourceFile + ':' + sourceLine + ':' + sourceColumn + ' -> ' + funcName; }; TickProcessor.prototype.printEntries = function( profile, totalTicks, nonLibTicks, filterP, callback) { var that = this; this.processProfile(profile, filterP, function (rec) { if (rec.selfTime == 0) return; callback(rec); var funcName = that.formatFunctionName(rec.internalFuncName); that.printLine(funcName, rec.selfTime, totalTicks, nonLibTicks); }); }; TickProcessor.prototype.printHeavyProfile = function(profile, opt_indent) { var self = this; var indent = opt_indent || 0; var indentStr = padLeft('', indent); this.processProfile(profile, function() { return true; }, function (rec) { // Cut off too infrequent callers. if (rec.parentTotalPercent < TickProcessor.CALL_PROFILE_CUTOFF_PCT) return; var funcName = self.formatFunctionName(rec.internalFuncName); print(' ' + padLeft(rec.totalTime, 5) + ' ' + padLeft(rec.parentTotalPercent.toFixed(1), 5) + '% ' + indentStr + funcName); // Limit backtrace depth. if (indent < 2 * self.callGraphSize_) { self.printHeavyProfile(rec.children, indent + 2); } // Delimit top-level functions. if (indent == 0) { print(''); } }); }; function CppEntriesProvider() { }; CppEntriesProvider.prototype.parseVmSymbols = function( libName, libStart, libEnd, processorFunc) { this.loadSymbols(libName); var prevEntry; function addEntry(funcInfo) { // Several functions can be mapped onto the same address. To avoid // creating zero-sized entries, skip such duplicates. // Also double-check that function belongs to the library address space. if (prevEntry && !prevEntry.end && prevEntry.start < funcInfo.start && prevEntry.start >= libStart && funcInfo.start <= libEnd) { processorFunc(prevEntry.name, prevEntry.start, funcInfo.start); } if (funcInfo.end && (!prevEntry || prevEntry.start != funcInfo.start) && funcInfo.start >= libStart && funcInfo.end <= libEnd) { processorFunc(funcInfo.name, funcInfo.start, funcInfo.end); } prevEntry = funcInfo; } while (true) { var funcInfo = this.parseNextLine(); if (funcInfo === null) { continue; } else if (funcInfo === false) { break; } if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) { funcInfo.start += libStart; } if (funcInfo.size) { funcInfo.end = funcInfo.start + funcInfo.size; } addEntry(funcInfo); } addEntry({name: '', start: libEnd}); }; CppEntriesProvider.prototype.loadSymbols = function(libName) { }; CppEntriesProvider.prototype.parseNextLine = function() { return false; }; function UnixCppEntriesProvider(nmExec, targetRootFS) { this.symbols = []; this.parsePos = 0; this.nmExec = nmExec; this.targetRootFS = targetRootFS; this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ([0-9a-fA-F]{8,16} )?[tTwW] (.*)$/; }; inherits(UnixCppEntriesProvider, CppEntriesProvider); UnixCppEntriesProvider.prototype.loadSymbols = function(libName) { this.parsePos = 0; libName = this.targetRootFS + libName; try { this.symbols = [ os.system(this.nmExec, ['-C', '-n', '-S', libName], -1, -1), os.system(this.nmExec, ['-C', '-n', '-S', '-D', libName], -1, -1) ]; } catch (e) { // If the library cannot be found on this system let's not panic. this.symbols = ['', '']; } }; UnixCppEntriesProvider.prototype.parseNextLine = function() { if (this.symbols.length == 0) { return false; } var lineEndPos = this.symbols[0].indexOf('\n', this.parsePos); if (lineEndPos == -1) { this.symbols.shift(); this.parsePos = 0; return this.parseNextLine(); } var line = this.symbols[0].substring(this.parsePos, lineEndPos); this.parsePos = lineEndPos + 1; var fields = line.match(this.FUNC_RE); var funcInfo = null; if (fields) { funcInfo = { name: fields[3], start: parseInt(fields[1], 16) }; if (fields[2]) { funcInfo.size = parseInt(fields[2], 16); } } return funcInfo; }; function MacCppEntriesProvider(nmExec, targetRootFS) { UnixCppEntriesProvider.call(this, nmExec, targetRootFS); // Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups. this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ()[iItT] (.*)$/; }; inherits(MacCppEntriesProvider, UnixCppEntriesProvider); MacCppEntriesProvider.prototype.loadSymbols = function(libName) { this.parsePos = 0; libName = this.targetRootFS + libName; try { this.symbols = [os.system(this.nmExec, ['-n', '-f', libName], -1, -1), '']; } catch (e) { // If the library cannot be found on this system let's not panic. this.symbols = ''; } }; function WindowsCppEntriesProvider(_ignored_nmExec, targetRootFS) { this.targetRootFS = targetRootFS; this.symbols = ''; this.parsePos = 0; }; inherits(WindowsCppEntriesProvider, CppEntriesProvider); WindowsCppEntriesProvider.FILENAME_RE = /^(.*)\.([^.]+)$/; WindowsCppEntriesProvider.FUNC_RE = /^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/; WindowsCppEntriesProvider.IMAGE_BASE_RE = /^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/; // This is almost a constant on Windows. WindowsCppEntriesProvider.EXE_IMAGE_BASE = 0x00400000; WindowsCppEntriesProvider.prototype.loadSymbols = function(libName) { libName = this.targetRootFS + libName; var fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE); if (!fileNameFields) return; var mapFileName = fileNameFields[1] + '.map'; this.moduleType_ = fileNameFields[2].toLowerCase(); try { this.symbols = read(mapFileName); } catch (e) { // If .map file cannot be found let's not panic. this.symbols = ''; } }; WindowsCppEntriesProvider.prototype.parseNextLine = function() { var lineEndPos = this.symbols.indexOf('\r\n', this.parsePos); if (lineEndPos == -1) { return false; } var line = this.symbols.substring(this.parsePos, lineEndPos); this.parsePos = lineEndPos + 2; // Image base entry is above all other symbols, so we can just // terminate parsing. var imageBaseFields = line.match(WindowsCppEntriesProvider.IMAGE_BASE_RE); if (imageBaseFields) { var imageBase = parseInt(imageBaseFields[1], 16); if ((this.moduleType_ == 'exe') != (imageBase == WindowsCppEntriesProvider.EXE_IMAGE_BASE)) { return false; } } var fields = line.match(WindowsCppEntriesProvider.FUNC_RE); return fields ? { name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } : null; }; /** * Performs very simple unmangling of C++ names. * * Does not handle arguments and template arguments. The mangled names have * the form: * * ?LookupInDescriptor@JSObject@internal@v8@@...arguments info... */ WindowsCppEntriesProvider.prototype.unmangleName = function(name) { // Empty or non-mangled name. if (name.length < 1 || name.charAt(0) != '?') return name; var nameEndPos = name.indexOf('@@'); var components = name.substring(1, nameEndPos).split('@'); components.reverse(); return components.join('::'); }; function ArgumentsProcessor(args) { this.args_ = args; this.result_ = ArgumentsProcessor.DEFAULTS; this.argsDispatch_ = { '-j': ['stateFilter', TickProcessor.VmStates.JS, 'Show only ticks from JS VM state'], '-g': ['stateFilter', TickProcessor.VmStates.GC, 'Show only ticks from GC VM state'], '-c': ['stateFilter', TickProcessor.VmStates.COMPILER, 'Show only ticks from COMPILER VM state'], '-o': ['stateFilter', TickProcessor.VmStates.OTHER, 'Show only ticks from OTHER VM state'], '-e': ['stateFilter', TickProcessor.VmStates.EXTERNAL, 'Show only ticks from EXTERNAL VM state'], '--call-graph-size': ['callGraphSize', TickProcessor.CALL_GRAPH_SIZE, 'Set the call graph size'], '--ignore-unknown': ['ignoreUnknown', true, 'Exclude ticks of unknown code entries from processing'], '--separate-ic': ['separateIc', true, 'Separate IC entries'], '--unix': ['platform', 'unix', 'Specify that we are running on *nix platform'], '--windows': ['platform', 'windows', 'Specify that we are running on Windows platform'], '--mac': ['platform', 'mac', 'Specify that we are running on Mac OS X platform'], '--nm': ['nm', 'nm', 'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)'], '--target': ['targetRootFS', '', 'Specify the target root directory for cross environment'], '--snapshot-log': ['snapshotLogFileName', 'snapshot.log', 'Specify snapshot log file to use (e.g. --snapshot-log=snapshot.log)'], '--range': ['range', 'auto,auto', 'Specify the range limit as [start],[end]'], '--distortion': ['distortion', 0, 'Specify the logging overhead in picoseconds'], '--source-map': ['sourceMap', null, 'Specify the source map that should be used for output'], '--timed-range': ['timedRange', true, 'Ignore ticks before first and after last Date.now() call'], '--pairwise-timed-range': ['pairwiseTimedRange', true, 'Ignore ticks outside pairs of Date.now() calls'] }; this.argsDispatch_['--js'] = this.argsDispatch_['-j']; this.argsDispatch_['--gc'] = this.argsDispatch_['-g']; this.argsDispatch_['--compiler'] = this.argsDispatch_['-c']; this.argsDispatch_['--other'] = this.argsDispatch_['-o']; this.argsDispatch_['--external'] = this.argsDispatch_['-e']; this.argsDispatch_['--ptr'] = this.argsDispatch_['--pairwise-timed-range']; }; ArgumentsProcessor.DEFAULTS = { logFileName: 'v8.log', snapshotLogFileName: null, platform: 'unix', stateFilter: null, callGraphSize: 5, ignoreUnknown: false, separateIc: false, targetRootFS: '', nm: 'nm', range: 'auto,auto', distortion: 0, timedRange: false, pairwiseTimedRange: false }; ArgumentsProcessor.prototype.parse = function() { while (this.args_.length) { var arg = this.args_.shift(); if (arg.charAt(0) != '-') { this.result_.logFileName = arg; continue; } var userValue = null; var eqPos = arg.indexOf('='); if (eqPos != -1) { userValue = arg.substr(eqPos + 1); arg = arg.substr(0, eqPos); } if (arg in this.argsDispatch_) { var dispatch = this.argsDispatch_[arg]; this.result_[dispatch[0]] = userValue == null ? dispatch[1] : userValue; } else { return false; } } return true; }; ArgumentsProcessor.prototype.result = function() { return this.result_; }; ArgumentsProcessor.prototype.printUsageAndExit = function() { function padRight(s, len) { s = s.toString(); if (s.length < len) { s = s + (new Array(len - s.length + 1).join(' ')); } return s; } print('Cmdline args: [options] [log-file-name]\n' + 'Default log file name is "' + ArgumentsProcessor.DEFAULTS.logFileName + '".\n'); print('Options:'); for (var arg in this.argsDispatch_) { var synonyms = [arg]; var dispatch = this.argsDispatch_[arg]; for (var synArg in this.argsDispatch_) { if (arg !== synArg && dispatch === this.argsDispatch_[synArg]) { synonyms.push(synArg); delete this.argsDispatch_[synArg]; } } print(' ' + padRight(synonyms.join(', '), 20) + " " + dispatch[2]); } quit(2); }; node-v4.2.6/deps/v8/tools/trace-maps-processor.py000755 000766 000024 00000011310 12650222326 022020 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import sys action = sys.argv[1] if action in ["help", "-h", "--help"] or len(sys.argv) != 3: print("Usage: %s , where action can be: \n" "help Print this message\n" "plain Print ASCII tree to stdout\n" "dot Print dot file to stdout\n" "count Count most frequent transition reasons\n" % sys.argv[0]) sys.exit(0) filename = sys.argv[2] maps = {} root_maps = [] transitions = {} annotations = {} class Map(object): def __init__(self, pointer, origin): self.pointer = pointer self.origin = origin def __str__(self): return "%s (%s)" % (self.pointer, self.origin) class Transition(object): def __init__(self, from_map, to_map, reason): self.from_map = from_map self.to_map = to_map self.reason = reason def RegisterNewMap(raw_map): if raw_map in annotations: annotations[raw_map] += 1 else: annotations[raw_map] = 0 return AnnotateExistingMap(raw_map) def AnnotateExistingMap(raw_map): return "%s_%d" % (raw_map, annotations[raw_map]) def AddMap(pointer, origin): pointer = RegisterNewMap(pointer) maps[pointer] = Map(pointer, origin) return pointer def AddTransition(from_map, to_map, reason): from_map = AnnotateExistingMap(from_map) to_map = AnnotateExistingMap(to_map) if from_map not in transitions: transitions[from_map] = {} targets = transitions[from_map] if to_map in targets: # Some events get printed twice, that's OK. In some cases, ignore the # second output... old_reason = targets[to_map].reason if old_reason.startswith("ReplaceDescriptors"): return # ...and in others use it for additional detail. if reason in []: targets[to_map].reason = reason return # Unexpected duplicate events? Warn. print("// warning: already have a transition from %s to %s, reason: %s" % (from_map, to_map, targets[to_map].reason)) return targets[to_map] = Transition(from_map, to_map, reason) with open(filename, "r") as f: last_to_map = "" for line in f: if not line.startswith("[TraceMaps: "): continue words = line.split(" ") event = words[1] if event == "InitialMap": assert words[2] == "map=" assert words[4] == "SFI=" new_map = AddMap(words[3], "SFI#%s" % words[5]) root_maps.append(new_map) continue if words[2] == "from=" and words[4] == "to=": from_map = words[3] to_map = words[5] if from_map not in annotations: print("// warning: unknown from_map %s" % from_map) new_map = AddMap(from_map, "") root_maps.append(new_map) if to_map != last_to_map: AddMap(to_map, " (%s)" % event) last_to_map = to_map if event in ["Transition", "NoTransition"]: assert words[6] == "name=", line reason = "%s: %s" % (event, words[7]) elif event in ["Normalize", "ReplaceDescriptors", "SlowToFast"]: assert words[6] == "reason=", line reason = "%s: %s" % (event, words[7]) if words[8].strip() != "]": reason = "%s_%s" % (reason, words[8]) else: reason = event AddTransition(from_map, to_map, reason) continue def PlainPrint(m, indent, label): print("%s%s (%s)" % (indent, m, label)) if m in transitions: for t in transitions[m]: PlainPrint(t, indent + " ", transitions[m][t].reason) def CountTransitions(m): if m not in transitions: return 0 return len(transitions[m]) def DotPrint(m, label): print("m%s [label=\"%s\"]" % (m[2:], label)) if m in transitions: for t in transitions[m]: # GraphViz doesn't like node labels looking like numbers, so use # "m..." instead of "0x...". print("m%s -> m%s" % (m[2:], t[2:])) reason = transitions[m][t].reason reason = reason.replace("\\", "BACKSLASH") reason = reason.replace("\"", "\\\"") DotPrint(t, reason) if action == "plain": root_maps = sorted(root_maps, key=CountTransitions, reverse=True) for m in root_maps: PlainPrint(m, "", maps[m].origin) elif action == "dot": print("digraph g {") for m in root_maps: DotPrint(m, maps[m].origin) print("}") elif action == "count": reasons = {} for s in transitions: for t in transitions[s]: reason = transitions[s][t].reason if reason not in reasons: reasons[reason] = 1 else: reasons[reason] += 1 reasons_list = [] for r in reasons: reasons_list.append("%8d %s" % (reasons[r], r)) reasons_list.sort(reverse=True) for r in reasons_list[:20]: print r node-v4.2.6/deps/v8/tools/try_perf.py000755 000766 000024 00000003576 12650222326 017620 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import find_depot_tools import sys find_depot_tools.add_depot_tools_to_path() from git_cl import Changelist BOTS = { '--arm32': 'v8_arm32_perf_try', '--linux32': 'v8_linux32_perf_try', '--linux64': 'v8_linux64_perf_try', '--linux64_haswell': 'v8_linux64_haswell_perf_try', '--nexus5': 'v8_nexus5_perf_try', '--nexus7': 'v8_nexus7_perf_try', '--nexus9': 'v8_nexus9_perf_try', '--nexus10': 'v8_nexus10_perf_try', } DEFAULT_BOTS = [ 'v8_linux32_perf_try', 'v8_linux64_haswell_perf_try', ] def main(): parser = argparse.ArgumentParser(description='') parser.add_argument("benchmarks", nargs="+", help="The benchmarks to run.") for option in sorted(BOTS): parser.add_argument( option, dest='bots', action='append_const', const=BOTS[option], help='Add %s trybot.' % BOTS[option]) options = parser.parse_args() if not options.bots: print 'No trybots specified. Using default %s.' % ','.join(DEFAULT_BOTS) options.bots = DEFAULT_BOTS cl = Changelist() if not cl.GetIssue(): print 'Need to upload first' return 1 props = cl.GetIssueProperties() if props.get('closed'): print 'Cannot send tryjobs for a closed CL' return 1 if props.get('private'): print 'Cannot use trybots with private issue' return 1 if not options.benchmarks: print 'Please specify the benchmarks to run as arguments.' return 1 masters = { 'internal.client.v8': dict((b, options.benchmarks) for b in options.bots), } cl.RpcServer().trigger_distributed_try_jobs( cl.GetIssue(), cl.GetMostRecentPatchset(), cl.GetBranch(), False, None, masters) return 0 if __name__ == "__main__": # pragma: no cover sys.exit(main()) node-v4.2.6/deps/v8/tools/unittests/000755 000766 000024 00000000000 12650222326 017440 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/v8-info.sh000755 000766 000024 00000010676 12650222326 017235 0ustar00iojsstaff000000 000000 #!/bin/bash # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ########## Global variable definitions BASE_URL="https://code.google.com/p/v8/source/list" VERSION="include/v8-version.h" MAJOR="V8_MAJOR_VERSION" MINOR="V8_MINOR_VERSION" BUILD="V8_BUILD_NUMBER" PATCH="V8_PATCH_LEVEL" V8="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ########## Function definitions cd $V8 usage() { cat << EOF usage: $0 OPTIONS Fetches V8 revision information from a git-svn checkout. OPTIONS: -h Show this message. -i Print revision info for all branches matching the V8 version. Example usage: $0 -i 3.19.10$ Output format: [Git hash] [SVN revision] [V8 version] -v Print the V8 version tag for a trunk SVN revision. Example usage: $0 -v 14981 Output format: [V8 version] -m Print all patches that were merged to the specified V8 branch. Example usage: $0 -m 3.18 Output format: [V8 version] [SVN revision] [SVN patch merged]*. -p Print all patches merged to a specific V8 point-release. Example usage: $0 -p 3.19.12.1 Output format: [SVN patch merged]* -u Print a link to all SVN revisions between two V8 revision tags. Example usage: $0 -u 3.19.10:3.19.11 EOF } tags() { git for-each-ref --format="%(objectname) %(refname:short)" refs/remotes/svn } tag_revision() { cut -d" " -f1 } tag_log() { git log --format="%h %ci %ce %s" -1 $1 } v8_hash() { tags | grep "svn/tags/$1$" | tag_revision } point_merges() { echo $1 | grep -o "r[0-9]\+" } hash_to_svn() { git svn log -1 --oneline $1 | cut -d" " -f1 } tag_version() { tags | grep svn/tags/$1 | while read tag; do id=$(echo $tag | grep -o "[^/]*$") rev=$(echo $tag | tag_revision) svn=$(hash_to_svn $rev) echo $rev $svn $id done } svn_rev() { git svn find-rev $2 svn/$1 } v8_rev() { cd $(git rev-parse --show-toplevel) rev=$(git show $1:$VERSION \ | grep "#define" \ | grep "$MAJOR\|$MINOR\|$BUILD\|$PATCH" \ | grep -o "[0-9]\+$" \ | tr "\\n" ".") echo ${rev%?} } merges_to_branch() { git cherry -v svn/trunk svn/$1 | while read merge; do h=$(echo $merge | cut -d" " -f2) svn=$(svn_rev $1 $h) merges=$(echo $merge | grep -o "r[0-9]\+") rev=$(v8_rev $h) echo $rev r$svn $merges done } url_for() { first=$(svn_rev trunk $(v8_hash $(echo $1 | cut -d":" -f1))) last=$(svn_rev trunk $(v8_hash $(echo $1 | cut -d":" -f2))) num=$[ $last - $first] echo "$BASE_URL?num=$num&start=$last" } ########## Option parsing while getopts ":hi:v:m:p:u:" OPTION ; do case $OPTION in h) usage exit 0 ;; i) tag_version $OPTARG ;; v) v8_rev $(svn_rev trunk r$OPTARG) ;; m) merges_to_branch $OPTARG ;; p) echo $(point_merges "$(tag_log $(v8_hash $OPTARG)^1)") ;; u) url_for $OPTARG ;; ?) echo "Illegal option: -$OPTARG" usage exit 1 ;; esac done node-v4.2.6/deps/v8/tools/v8-rolls.sh000755 000766 000024 00000006160 12650222326 017426 0ustar00iojsstaff000000 000000 #!/bin/bash # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ########## Global variable definitions DEPS_STRING='"v8_revision":' INFO=tools/v8-info.sh V8="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ########## Function definitions usage() { cat << EOF usage: $0 OPTIONS Run in chromium/src to get information about V8 rolls. OPTIONS: -h Show this message. -n Number of rolls to print information about. -s Chromium git hash to start printing V8 information about. EOF } v8_line() { git show $1:DEPS | grep -n $DEPS_STRING | cut -d":" -f1 } v8_info() { git blame -L$(v8_line $1),+1 $1 DEPS | grep $DEPS_STRING } v8_svn() { sed -e 's/^.*"\([0-9]\+\)",$/\1/' } v8_roll() { cut -d" " -f1 } find_rev() { git svn find-rev $1 } msg() { msg=$(git log --format="%h %ci %ce" -1 $1) h=$(echo $msg | cut -d" " -f1) d=$(echo $msg | cut -d" " -f2) t=$(echo $msg | cut -d" " -f3) a=$(echo $msg | cut -d" " -f5) a1=$(echo $a | cut -d"@" -f1) a2=$(echo $a | cut -d"@" -f2) echo $h $d $t $a1@$a2 } v8_revision() { cd $V8 $INFO -v $1 } rolls() { roll=$2 for i in $(seq 1 $1); do info=$(v8_info $roll) roll=$(echo $info | v8_roll $roll) trunk=$(echo $info | v8_svn $roll) echo "$(v8_revision $trunk) $trunk $(find_rev $roll) $(msg $roll)" roll=$roll^1 done } ########## Option parsing REVISIONS=1 START=HEAD while getopts ":hn:s:" OPTION ; do case $OPTION in h) usage exit 0 ;; n) REVISIONS=$OPTARG ;; s) START=$OPTARG ;; ?) echo "Illegal option: -$OPTARG" usage exit 1 ;; esac done rolls $REVISIONS $START node-v4.2.6/deps/v8/tools/v8heapconst.py000644 000766 000024 00000027523 12650222326 020223 0ustar00iojsstaff000000 000000 # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This file is automatically generated from the V8 source and should not # be modified manually, run 'make grokdump' instead to update this file. # List of known V8 instance types. INSTANCE_TYPES = { 64: "STRING_TYPE", 68: "ONE_BYTE_STRING_TYPE", 65: "CONS_STRING_TYPE", 69: "CONS_ONE_BYTE_STRING_TYPE", 67: "SLICED_STRING_TYPE", 71: "SLICED_ONE_BYTE_STRING_TYPE", 66: "EXTERNAL_STRING_TYPE", 70: "EXTERNAL_ONE_BYTE_STRING_TYPE", 74: "EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE", 82: "SHORT_EXTERNAL_STRING_TYPE", 86: "SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE", 90: "SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE", 0: "INTERNALIZED_STRING_TYPE", 4: "ONE_BYTE_INTERNALIZED_STRING_TYPE", 2: "EXTERNAL_INTERNALIZED_STRING_TYPE", 6: "EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE", 10: "EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE", 18: "SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE", 22: "SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE", 26: "SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE", 128: "SYMBOL_TYPE", 129: "MAP_TYPE", 130: "CODE_TYPE", 131: "ODDBALL_TYPE", 181: "CELL_TYPE", 183: "PROPERTY_CELL_TYPE", 132: "HEAP_NUMBER_TYPE", 133: "MUTABLE_HEAP_NUMBER_TYPE", 134: "FLOAT32X4_TYPE", 135: "FOREIGN_TYPE", 136: "BYTE_ARRAY_TYPE", 137: "FREE_SPACE_TYPE", 138: "EXTERNAL_INT8_ARRAY_TYPE", 139: "EXTERNAL_UINT8_ARRAY_TYPE", 140: "EXTERNAL_INT16_ARRAY_TYPE", 141: "EXTERNAL_UINT16_ARRAY_TYPE", 142: "EXTERNAL_INT32_ARRAY_TYPE", 143: "EXTERNAL_UINT32_ARRAY_TYPE", 144: "EXTERNAL_FLOAT32_ARRAY_TYPE", 145: "EXTERNAL_FLOAT64_ARRAY_TYPE", 146: "EXTERNAL_UINT8_CLAMPED_ARRAY_TYPE", 147: "FIXED_INT8_ARRAY_TYPE", 148: "FIXED_UINT8_ARRAY_TYPE", 149: "FIXED_INT16_ARRAY_TYPE", 150: "FIXED_UINT16_ARRAY_TYPE", 151: "FIXED_INT32_ARRAY_TYPE", 152: "FIXED_UINT32_ARRAY_TYPE", 153: "FIXED_FLOAT32_ARRAY_TYPE", 154: "FIXED_FLOAT64_ARRAY_TYPE", 155: "FIXED_UINT8_CLAMPED_ARRAY_TYPE", 157: "FILLER_TYPE", 158: "DECLARED_ACCESSOR_DESCRIPTOR_TYPE", 159: "DECLARED_ACCESSOR_INFO_TYPE", 160: "EXECUTABLE_ACCESSOR_INFO_TYPE", 161: "ACCESSOR_PAIR_TYPE", 162: "ACCESS_CHECK_INFO_TYPE", 163: "INTERCEPTOR_INFO_TYPE", 164: "CALL_HANDLER_INFO_TYPE", 165: "FUNCTION_TEMPLATE_INFO_TYPE", 166: "OBJECT_TEMPLATE_INFO_TYPE", 167: "SIGNATURE_INFO_TYPE", 168: "TYPE_SWITCH_INFO_TYPE", 170: "ALLOCATION_MEMENTO_TYPE", 169: "ALLOCATION_SITE_TYPE", 171: "SCRIPT_TYPE", 172: "CODE_CACHE_TYPE", 173: "POLYMORPHIC_CODE_CACHE_TYPE", 174: "TYPE_FEEDBACK_INFO_TYPE", 175: "ALIASED_ARGUMENTS_ENTRY_TYPE", 176: "BOX_TYPE", 184: "PROTOTYPE_INFO_TYPE", 179: "FIXED_ARRAY_TYPE", 156: "FIXED_DOUBLE_ARRAY_TYPE", 180: "SHARED_FUNCTION_INFO_TYPE", 182: "WEAK_CELL_TYPE", 188: "JS_MESSAGE_OBJECT_TYPE", 187: "JS_VALUE_TYPE", 189: "JS_DATE_TYPE", 190: "JS_OBJECT_TYPE", 191: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", 192: "JS_GENERATOR_OBJECT_TYPE", 193: "JS_MODULE_TYPE", 194: "JS_GLOBAL_OBJECT_TYPE", 195: "JS_BUILTINS_OBJECT_TYPE", 196: "JS_GLOBAL_PROXY_TYPE", 197: "JS_ARRAY_TYPE", 198: "JS_ARRAY_BUFFER_TYPE", 199: "JS_TYPED_ARRAY_TYPE", 200: "JS_DATA_VIEW_TYPE", 186: "JS_PROXY_TYPE", 201: "JS_SET_TYPE", 202: "JS_MAP_TYPE", 203: "JS_SET_ITERATOR_TYPE", 204: "JS_MAP_ITERATOR_TYPE", 205: "JS_WEAK_MAP_TYPE", 206: "JS_WEAK_SET_TYPE", 207: "JS_REGEXP_TYPE", 208: "JS_FUNCTION_TYPE", 185: "JS_FUNCTION_PROXY_TYPE", 177: "DEBUG_INFO_TYPE", 178: "BREAK_POINT_INFO_TYPE", } # List of known V8 maps. KNOWN_MAPS = { 0x08081: (136, "ByteArrayMap"), 0x080ad: (129, "MetaMap"), 0x080d9: (131, "NullMap"), 0x08105: (179, "FixedArrayMap"), 0x08131: (4, "OneByteInternalizedStringMap"), 0x0815d: (182, "WeakCellMap"), 0x08189: (131, "UndefinedMap"), 0x081b5: (132, "HeapNumberMap"), 0x081e1: (137, "FreeSpaceMap"), 0x0820d: (157, "OnePointerFillerMap"), 0x08239: (157, "TwoPointerFillerMap"), 0x08265: (131, "TheHoleMap"), 0x08291: (131, "BooleanMap"), 0x082bd: (131, "UninitializedMap"), 0x082e9: (181, "CellMap"), 0x08315: (183, "GlobalPropertyCellMap"), 0x08341: (180, "SharedFunctionInfoMap"), 0x0836d: (133, "MutableHeapNumberMap"), 0x08399: (134, "Float32x4Map"), 0x083c5: (179, "NativeContextMap"), 0x083f1: (130, "CodeMap"), 0x0841d: (179, "ScopeInfoMap"), 0x08449: (179, "FixedCOWArrayMap"), 0x08475: (156, "FixedDoubleArrayMap"), 0x084a1: (68, "OneByteStringMap"), 0x084cd: (179, "FunctionContextMap"), 0x084f9: (131, "NoInterceptorResultSentinelMap"), 0x08525: (131, "ArgumentsMarkerMap"), 0x08551: (131, "ExceptionMap"), 0x0857d: (131, "TerminationExceptionMap"), 0x085a9: (179, "HashTableMap"), 0x085d5: (179, "OrderedHashTableMap"), 0x08601: (128, "SymbolMap"), 0x0862d: (64, "StringMap"), 0x08659: (69, "ConsOneByteStringMap"), 0x08685: (65, "ConsStringMap"), 0x086b1: (67, "SlicedStringMap"), 0x086dd: (71, "SlicedOneByteStringMap"), 0x08709: (66, "ExternalStringMap"), 0x08735: (74, "ExternalStringWithOneByteDataMap"), 0x08761: (70, "ExternalOneByteStringMap"), 0x0878d: (70, "NativeSourceStringMap"), 0x087b9: (82, "ShortExternalStringMap"), 0x087e5: (90, "ShortExternalStringWithOneByteDataMap"), 0x08811: (0, "InternalizedStringMap"), 0x0883d: (2, "ExternalInternalizedStringMap"), 0x08869: (10, "ExternalInternalizedStringWithOneByteDataMap"), 0x08895: (6, "ExternalOneByteInternalizedStringMap"), 0x088c1: (18, "ShortExternalInternalizedStringMap"), 0x088ed: (26, "ShortExternalInternalizedStringWithOneByteDataMap"), 0x08919: (22, "ShortExternalOneByteInternalizedStringMap"), 0x08945: (86, "ShortExternalOneByteStringMap"), 0x08971: (138, "ExternalInt8ArrayMap"), 0x0899d: (139, "ExternalUint8ArrayMap"), 0x089c9: (140, "ExternalInt16ArrayMap"), 0x089f5: (141, "ExternalUint16ArrayMap"), 0x08a21: (142, "ExternalInt32ArrayMap"), 0x08a4d: (143, "ExternalUint32ArrayMap"), 0x08a79: (144, "ExternalFloat32ArrayMap"), 0x08aa5: (145, "ExternalFloat64ArrayMap"), 0x08ad1: (146, "ExternalUint8ClampedArrayMap"), 0x08afd: (148, "FixedUint8ArrayMap"), 0x08b29: (147, "FixedInt8ArrayMap"), 0x08b55: (150, "FixedUint16ArrayMap"), 0x08b81: (149, "FixedInt16ArrayMap"), 0x08bad: (152, "FixedUint32ArrayMap"), 0x08bd9: (151, "FixedInt32ArrayMap"), 0x08c05: (153, "FixedFloat32ArrayMap"), 0x08c31: (154, "FixedFloat64ArrayMap"), 0x08c5d: (155, "FixedUint8ClampedArrayMap"), 0x08c89: (179, "SloppyArgumentsElementsMap"), 0x08cb5: (179, "CatchContextMap"), 0x08ce1: (179, "WithContextMap"), 0x08d0d: (179, "BlockContextMap"), 0x08d39: (179, "ModuleContextMap"), 0x08d65: (179, "ScriptContextMap"), 0x08d91: (179, "ScriptContextTableMap"), 0x08dbd: (188, "JSMessageObjectMap"), 0x08de9: (135, "ForeignMap"), 0x08e15: (190, "NeanderMap"), 0x08e41: (190, "ExternalMap"), 0x08e6d: (170, "AllocationMementoMap"), 0x08e99: (169, "AllocationSiteMap"), 0x08ec5: (173, "PolymorphicCodeCacheMap"), 0x08ef1: (171, "ScriptMap"), 0x0907d: (176, "BoxMap"), 0x090a9: (160, "ExecutableAccessorInfoMap"), 0x090d5: (161, "AccessorPairMap"), 0x09101: (162, "AccessCheckInfoMap"), 0x0912d: (163, "InterceptorInfoMap"), 0x09159: (164, "CallHandlerInfoMap"), 0x09185: (165, "FunctionTemplateInfoMap"), 0x091b1: (166, "ObjectTemplateInfoMap"), 0x091dd: (168, "TypeSwitchInfoMap"), 0x09209: (172, "CodeCacheMap"), 0x09235: (174, "TypeFeedbackInfoMap"), 0x09261: (175, "AliasedArgumentsEntryMap"), 0x0928d: (177, "DebugInfoMap"), 0x092b9: (178, "BreakPointInfoMap"), 0x092e5: (184, "PrototypeInfoMap"), } # List of known V8 objects. KNOWN_OBJECTS = { ("OLD_SPACE", 0x08081): "NullValue", ("OLD_SPACE", 0x08091): "EmptyDescriptorArray", ("OLD_SPACE", 0x08099): "EmptyFixedArray", ("OLD_SPACE", 0x080bd): "UndefinedValue", ("OLD_SPACE", 0x080e5): "NanValue", ("OLD_SPACE", 0x080f1): "TheHoleValue", ("OLD_SPACE", 0x08111): "TrueValue", ("OLD_SPACE", 0x08131): "FalseValue", ("OLD_SPACE", 0x08155): "empty_string", ("OLD_SPACE", 0x08161): "UninitializedValue", ("OLD_SPACE", 0x0818d): "EmptyByteArray", ("OLD_SPACE", 0x08195): "NoInterceptorResultSentinel", ("OLD_SPACE", 0x081d1): "ArgumentsMarker", ("OLD_SPACE", 0x081fd): "Exception", ("OLD_SPACE", 0x08225): "TerminationException", ("OLD_SPACE", 0x08259): "NumberStringCache", ("OLD_SPACE", 0x08a61): "SingleCharacterStringCache", ("OLD_SPACE", 0x08ef9): "StringSplitCache", ("OLD_SPACE", 0x09301): "RegExpMultipleCache", ("OLD_SPACE", 0x09709): "EmptyExternalInt8Array", ("OLD_SPACE", 0x09715): "EmptyExternalUint8Array", ("OLD_SPACE", 0x09721): "EmptyExternalInt16Array", ("OLD_SPACE", 0x0972d): "EmptyExternalUint16Array", ("OLD_SPACE", 0x09739): "EmptyExternalInt32Array", ("OLD_SPACE", 0x09745): "EmptyExternalUint32Array", ("OLD_SPACE", 0x09751): "EmptyExternalFloat32Array", ("OLD_SPACE", 0x0975d): "EmptyExternalFloat64Array", ("OLD_SPACE", 0x09769): "EmptyExternalUint8ClampedArray", ("OLD_SPACE", 0x09775): "EmptyFixedUint8Array", ("OLD_SPACE", 0x0977d): "EmptyFixedInt8Array", ("OLD_SPACE", 0x09785): "EmptyFixedUint16Array", ("OLD_SPACE", 0x0978d): "EmptyFixedInt16Array", ("OLD_SPACE", 0x09795): "EmptyFixedUint32Array", ("OLD_SPACE", 0x0979d): "EmptyFixedInt32Array", ("OLD_SPACE", 0x097a5): "EmptyFixedFloat32Array", ("OLD_SPACE", 0x097ad): "EmptyFixedFloat64Array", ("OLD_SPACE", 0x097b5): "EmptyFixedUint8ClampedArray", ("OLD_SPACE", 0x097bd): "InfinityValue", ("OLD_SPACE", 0x097c9): "MinusZeroValue", ("OLD_SPACE", 0x097d5): "MessageListeners", ("OLD_SPACE", 0x097f1): "CodeStubs", ("OLD_SPACE", 0x12439): "ArrayProtector", ("OLD_SPACE", 0x12dfd): "KeyedLoadDummyVector", ("OLD_SPACE", 0x13cc5): "NonMonomorphicCache", ("OLD_SPACE", 0x14009): "PolymorphicCodeCache", ("OLD_SPACE", 0x14011): "NativesSourceCache", ("OLD_SPACE", 0x142d1): "ExperimentalNativesSourceCache", ("OLD_SPACE", 0x14309): "ExtraNativesSourceCache", ("OLD_SPACE", 0x14315): "EmptyScript", ("OLD_SPACE", 0x14351): "IntrinsicFunctionNames", ("OLD_SPACE", 0x233d5): "UndefinedCell", ("OLD_SPACE", 0x233dd): "ObservationState", ("OLD_SPACE", 0x233e9): "SymbolRegistry", ("OLD_SPACE", 0x2429d): "EmptySlowElementDictionary", ("OLD_SPACE", 0x242c5): "AllocationSitesScratchpad", ("OLD_SPACE", 0x246cd): "WeakObjectToCodeTable", ("OLD_SPACE", 0x4a5c1): "StringTable", ("CODE_SPACE", 0x180c1): "JsEntryCode", ("CODE_SPACE", 0x25c41): "JsConstructEntryCode", } node-v4.2.6/deps/v8/tools/v8heapconst.py.tmpl000644 000766 000024 00000003267 12650222326 021175 0ustar00iojsstaff000000 000000 # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This file is automatically generated from the V8 source and should not # be modified manually, run 'make grokdump' instead to update this file. node-v4.2.6/deps/v8/tools/verify_source_deps.py000755 000766 000024 00000006037 12650222326 021660 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ Script to print potentially missing source dependencies based on the actual .h and .cc files in the source tree and which files are included in the gyp and gn files. The latter inclusion is overapproximated. TODO(machenbach): Gyp files in src will point to source files in src without a src/ prefix. For simplicity, all paths relative to src are stripped. But this tool won't be accurate for other sources in other directories (e.g. cctest). """ import itertools import re import os V8_BASE = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) V8_SRC_BASE = os.path.join(V8_BASE, 'src') V8_INCLUDE_BASE = os.path.join(V8_BASE, 'include') GYP_FILES = [ os.path.join(V8_BASE, 'src', 'd8.gyp'), os.path.join(V8_BASE, 'src', 'third_party', 'vtune', 'v8vtune.gyp'), os.path.join(V8_BASE, 'test', 'cctest', 'cctest.gyp'), os.path.join(V8_BASE, 'test', 'unittests', 'unittests.gyp'), os.path.join(V8_BASE, 'tools', 'gyp', 'v8.gyp'), os.path.join(V8_BASE, 'tools', 'parser-shell.gyp'), ] def path_no_prefix(path): if path.startswith('../'): return path_no_prefix(path[3:]) elif path.startswith('src/'): return path_no_prefix(path[4:]) else: return path def isources(directory): for root, dirs, files in os.walk(directory): for f in files: if not (f.endswith('.h') or f.endswith('.cc')): continue yield path_no_prefix(os.path.relpath(os.path.join(root, f), V8_BASE)) def iflatten(obj): if isinstance(obj, dict): for value in obj.values(): for i in iflatten(value): yield i elif isinstance(obj, list): for value in obj: for i in iflatten(value): yield i elif isinstance(obj, basestring): yield path_no_prefix(obj) def iflatten_gyp_file(gyp_file): """Overaproximates all values in the gyp file. Iterates over all string values recursively. Removes '../' path prefixes. """ with open(gyp_file) as f: return iflatten(eval(f.read())) def iflatten_gn_file(gn_file): """Overaproximates all values in the gn file. Iterates over all double quoted strings. """ with open(gn_file) as f: for line in f.read().splitlines(): match = re.match(r'.*"([^"]*)".*', line) if match: yield path_no_prefix(match.group(1)) def icheck_values(values, *source_dirs): for source_file in itertools.chain( *[isources(source_dir) for source_dir in source_dirs] ): if source_file not in values: yield source_file gyp_values = set(itertools.chain( *[iflatten_gyp_file(gyp_file) for gyp_file in GYP_FILES] )) print "----------- Files not in gyp: ------------" for i in sorted(icheck_values(gyp_values, V8_SRC_BASE, V8_INCLUDE_BASE)): print i gn_values = set(iflatten_gn_file(os.path.join(V8_BASE, 'BUILD.gn'))) print "\n----------- Files not in gn: -------------" for i in sorted(icheck_values(gn_values, V8_SRC_BASE, V8_INCLUDE_BASE)): print i node-v4.2.6/deps/v8/tools/vim/000755 000766 000024 00000000000 12650222326 016171 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/visual_studio/000755 000766 000024 00000000000 12650222326 020270 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/whitespace.txt000644 000766 000024 00000000463 12650222326 020276 0ustar00iojsstaff000000 000000 You can modify this file to create no-op changelists. Try to write something funny. And please don't add trailing whitespace. A Smi balks into a war and says: "I'm so deoptimized today!" The doubles heard this and started to unbox. The Smi looked at them when a crazy v8-autoroll account showed up....... node-v4.2.6/deps/v8/tools/windows-tick-processor.bat000755 000766 000024 00000002433 12650222326 022532 0ustar00iojsstaff000000 000000 @echo off SET tools_dir=%~dp0 IF 1%D8_PATH% == 1 (SET D8_PATH=%tools_dir%..) SET log_file=v8.log rem find the name of the log file to process, it must not start with a dash. rem we prepend cmdline args with a number (in fact, any letter or number) rem to cope with empty arguments. SET arg1=1%1 IF NOT %arg1:~0,2% == 1 (IF NOT %arg1:~0,2% == 1- SET log_file=%1) SET arg2=2%2 IF NOT %arg2:~0,2% == 2 (IF NOT %arg2:~0,2% == 2- SET log_file=%2) SET arg3=3%3 IF NOT %arg3:~0,2% == 3 (IF NOT %arg3:~0,2% == 3- SET log_file=%3) SET arg4=4%4 IF NOT %arg4:~0,2% == 4 (IF NOT %arg4:~0,2% == 4- SET log_file=%4) SET arg5=5%5 IF NOT %arg5:~0,2% == 5 (IF NOT %arg5:~0,2% == 5- SET log_file=%5) SET arg6=6%6 IF NOT %arg6:~0,2% == 6 (IF NOT %arg6:~0,2% == 6- SET log_file=%6) SET arg7=7%7 IF NOT %arg7:~0,2% == 7 (IF NOT %arg7:~0,2% == 7- SET log_file=%7) SET arg8=8%8 IF NOT %arg8:~0,2% == 8 (IF NOT %arg8:~0,2% == 8- SET log_file=%8) SET arg9=9%9 IF NOT %arg9:~0,2% == 9 (IF NOT %arg9:~0,2% == 9- SET log_file=%9) type %log_file% | %D8_PATH%\d8 %tools_dir%splaytree.js %tools_dir%codemap.js %tools_dir%csvparser.js %tools_dir%consarray.js %tools_dir%profile.js %tools_dir%profile_view.js %tools_dir%logreader.js %tools_dir%SourceMap.js %tools_dir%tickprocessor.js %tools_dir%tickprocessor-driver.js -- --windows %* node-v4.2.6/deps/v8/tools/visual_studio/README.txt000644 000766 000024 00000001157 12650222326 021772 0ustar00iojsstaff000000 000000 The Microsoft Visual Studio project files for including V8 in a Visual Studio/Visual C++ Express solution has been retired. If a Visual Studio project/solution is needed there is the option of using GYP to generate these. Please look in the build directory in the root of the V8 project. It contains the required infrastructure and a README.txt file explaining how to get started. Generating Visual Studio projects using GYP is how the Chromium project integrated V8 into the Windows build. The main build system for V8 is still SCons, see the V8 wiki page http://code.google.com/p/v8/wiki/BuildingOnWindows for details. node-v4.2.6/deps/v8/tools/vim/ninja-build.vim000644 000766 000024 00000007753 12650222326 021116 0ustar00iojsstaff000000 000000 " Copyright (c) 2015 the V8 project authors. All rights reserved. " Use of this source code is governed by a BSD-style license that can be " found in the LICENSE file. " " Adds a "Compile this file" function, using ninja. On Mac, binds Cmd-k to " this command. On Windows, Ctrl-F7 (which is the same as the VS default). " On Linux, o, which is \o by default ("o"=creates .o files) " " Adds a "Build this target" function, using ninja. This is not bound " to any key by default, but can be used via the :CrBuild command. " It builds 'd8' by default, but :CrBuild target1 target2 etc works as well, " i.e. :CrBuild all or :CrBuild d8 cctest unittests. " " Requires that gyp has already generated build.ninja files, and that ninja is " in your path (which it is automatically if depot_tools is in your path). " Bumps the number of parallel jobs in ninja automatically if goma is " detected. " " Add the following to your .vimrc file: " so /path/to/src/tools/vim/ninja-build.vim python << endpython import os import vim def path_to_current_buffer(): """Returns the absolute path of the current buffer.""" return vim.current.buffer.name def path_to_source_root(): """Returns the absolute path to the V8 source root.""" candidate = os.path.dirname(path_to_current_buffer()) # This is a list of files that need to identify the src directory. The shorter # it is, the more likely it's wrong. The longer it is, the more likely it is to # break when we rename directories. fingerprints = ['.git', 'build', 'include', 'samples', 'src', 'testing', 'third_party', 'tools'] while candidate and not all( [os.path.isdir(os.path.join(candidate, fp)) for fp in fingerprints]): candidate = os.path.dirname(candidate) return candidate def path_to_build_dir(configuration): """Returns //(Release|Debug).""" v8_root = path_to_source_root() sys.path.append(os.path.join(v8_root, 'tools', 'ninja')) from ninja_output import GetNinjaOutputDirectory return GetNinjaOutputDirectory(v8_root, configuration) def compute_ninja_command_for_targets(targets='', configuration=None): flags = [] if "use_goma=1" in os.getenv('GYP_DEFINES', '').split(' '): flags = ['-j', '512'] build_dir = path_to_build_dir(configuration); build_cmd = ' '.join(['ninja'] + flags + ['-C', build_dir, targets]) vim.command('return "%s"' % build_cmd) def compute_ninja_command_for_current_buffer(configuration=None): """Returns the shell command to compile the file in the current buffer.""" build_dir = path_to_build_dir(configuration) # ninja needs filepaths for the ^ syntax to be relative to the # build directory. file_to_build = path_to_current_buffer() file_to_build = os.path.relpath(file_to_build, build_dir) + '^' if sys.platform == 'win32': # Escape \ for Vim, and ^ for both Vim and shell. file_to_build = file_to_build.replace('\\', '\\\\').replace('^', '^^^^') compute_ninja_command_for_targets(file_to_build, configuration) endpython fun! s:MakeWithCustomCommand(build_cmd) let l:oldmakepgr = &makeprg let &makeprg=a:build_cmd silent make | cwindow if !has('gui_running') redraw! endif let &makeprg = l:oldmakepgr endfun fun! s:NinjaCommandForCurrentBuffer() python compute_ninja_command_for_current_buffer() endfun fun! s:NinjaCommandForTargets(targets) python compute_ninja_command_for_targets(vim.eval('a:targets')) endfun fun! CrCompileFile() call s:MakeWithCustomCommand(s:NinjaCommandForCurrentBuffer()) endfun fun! CrBuild(...) let l:targets = a:0 > 0 ? join(a:000, ' ') : '' if (l:targets !~ '\i') let l:targets = 'd8' endif call s:MakeWithCustomCommand(s:NinjaCommandForTargets(l:targets)) endfun command! CrCompileFile call CrCompileFile() command! -nargs=* CrBuild call CrBuild() if has('mac') map :CrCompileFile imap :CrCompileFile elseif has('win32') map :CrCompileFile imap :CrCompileFile elseif has('unix') map o :CrCompileFile endif node-v4.2.6/deps/v8/tools/unittests/run_perf_test.py000644 000766 000024 00000035667 12650222326 022712 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from collections import namedtuple import coverage import json from mock import DEFAULT from mock import MagicMock import os from os import path, sys import shutil import tempfile import unittest # Requires python-coverage and python-mock. Native python coverage # version >= 3.7.1 should be installed to get the best speed. TEST_WORKSPACE = path.join(tempfile.gettempdir(), "test-v8-run-perf") V8_JSON = { "path": ["."], "binary": "d7", "flags": ["--flag"], "main": "run.js", "run_count": 1, "results_regexp": "^%s: (.+)$", "tests": [ {"name": "Richards"}, {"name": "DeltaBlue"}, ] } V8_NESTED_SUITES_JSON = { "path": ["."], "flags": ["--flag"], "run_count": 1, "units": "score", "tests": [ {"name": "Richards", "path": ["richards"], "binary": "d7", "main": "run.js", "resources": ["file1.js", "file2.js"], "run_count": 2, "results_regexp": "^Richards: (.+)$"}, {"name": "Sub", "path": ["sub"], "tests": [ {"name": "Leaf", "path": ["leaf"], "run_count_x64": 3, "units": "ms", "main": "run.js", "results_regexp": "^Simple: (.+) ms.$"}, ] }, {"name": "DeltaBlue", "path": ["delta_blue"], "main": "run.js", "flags": ["--flag2"], "results_regexp": "^DeltaBlue: (.+)$"}, {"name": "ShouldntRun", "path": ["."], "archs": ["arm"], "main": "run.js"}, ] } V8_GENERIC_JSON = { "path": ["."], "binary": "cc", "flags": ["--flag"], "generic": True, "run_count": 1, "units": "ms", } Output = namedtuple("Output", "stdout, stderr, timed_out") class PerfTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.base = path.dirname(path.dirname(path.abspath(__file__))) sys.path.append(cls.base) cls._cov = coverage.coverage( include=([os.path.join(cls.base, "run_perf.py")])) cls._cov.start() import run_perf from testrunner.local import commands global commands global run_perf @classmethod def tearDownClass(cls): cls._cov.stop() print "" print cls._cov.report() def setUp(self): self.maxDiff = None if path.exists(TEST_WORKSPACE): shutil.rmtree(TEST_WORKSPACE) os.makedirs(TEST_WORKSPACE) def tearDown(self): if path.exists(TEST_WORKSPACE): shutil.rmtree(TEST_WORKSPACE) def _WriteTestInput(self, json_content): self._test_input = path.join(TEST_WORKSPACE, "test.json") with open(self._test_input, "w") as f: f.write(json.dumps(json_content)) def _MockCommand(self, *args, **kwargs): # Fake output for each test run. test_outputs = [Output(stdout=arg, stderr=None, timed_out=kwargs.get("timed_out", False)) for arg in args[1]] def execute(*args, **kwargs): return test_outputs.pop() commands.Execute = MagicMock(side_effect=execute) # Check that d8 is called from the correct cwd for each test run. dirs = [path.join(TEST_WORKSPACE, arg) for arg in args[0]] def chdir(*args, **kwargs): self.assertEquals(dirs.pop(), args[0]) os.chdir = MagicMock(side_effect=chdir) def _CallMain(self, *args): self._test_output = path.join(TEST_WORKSPACE, "results.json") all_args=[ "--json-test-results", self._test_output, self._test_input, ] all_args += args return run_perf.Main(all_args) def _LoadResults(self): with open(self._test_output) as f: return json.load(f) def _VerifyResults(self, suite, units, traces): self.assertEquals([ {"units": units, "graphs": [suite, trace["name"]], "results": trace["results"], "stddev": trace["stddev"]} for trace in traces], self._LoadResults()["traces"]) def _VerifyErrors(self, errors): self.assertEquals(errors, self._LoadResults()["errors"]) def _VerifyMock(self, binary, *args, **kwargs): arg = [path.join(path.dirname(self.base), binary)] arg += args commands.Execute.assert_called_with( arg, timeout=kwargs.get("timeout", 60)) def _VerifyMockMultiple(self, *args, **kwargs): expected = [] for arg in args: a = [path.join(path.dirname(self.base), arg[0])] a += arg[1:] expected.append(((a,), {"timeout": kwargs.get("timeout", 60)})) self.assertEquals(expected, commands.Execute.call_args_list) def testOneRun(self): self._WriteTestInput(V8_JSON) self._MockCommand(["."], ["x\nRichards: 1.234\nDeltaBlue: 10657567\ny\n"]) self.assertEquals(0, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testOneRunWithTestFlags(self): test_input = dict(V8_JSON) test_input["test_flags"] = ["2", "test_name"] self._WriteTestInput(test_input) self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567"]) self.assertEquals(0, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js", "--", "2", "test_name") def testTwoRuns_Units_SuiteName(self): test_input = dict(V8_JSON) test_input["run_count"] = 2 test_input["name"] = "v8" test_input["units"] = "ms" self._WriteTestInput(test_input) self._MockCommand([".", "."], ["Richards: 100\nDeltaBlue: 200\n", "Richards: 50\nDeltaBlue: 300\n"]) self.assertEquals(0, self._CallMain()) self._VerifyResults("v8", "ms", [ {"name": "Richards", "results": ["50.0", "100.0"], "stddev": ""}, {"name": "DeltaBlue", "results": ["300.0", "200.0"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testTwoRuns_SubRegexp(self): test_input = dict(V8_JSON) test_input["run_count"] = 2 del test_input["results_regexp"] test_input["tests"][0]["results_regexp"] = "^Richards: (.+)$" test_input["tests"][1]["results_regexp"] = "^DeltaBlue: (.+)$" self._WriteTestInput(test_input) self._MockCommand([".", "."], ["Richards: 100\nDeltaBlue: 200\n", "Richards: 50\nDeltaBlue: 300\n"]) self.assertEquals(0, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["50.0", "100.0"], "stddev": ""}, {"name": "DeltaBlue", "results": ["300.0", "200.0"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testNestedSuite(self): self._WriteTestInput(V8_NESTED_SUITES_JSON) self._MockCommand(["delta_blue", "sub/leaf", "richards"], ["DeltaBlue: 200\n", "Simple: 1 ms.\n", "Simple: 2 ms.\n", "Simple: 3 ms.\n", "Richards: 100\n", "Richards: 50\n"]) self.assertEquals(0, self._CallMain()) self.assertEquals([ {"units": "score", "graphs": ["test", "Richards"], "results": ["50.0", "100.0"], "stddev": ""}, {"units": "ms", "graphs": ["test", "Sub", "Leaf"], "results": ["3.0", "2.0", "1.0"], "stddev": ""}, {"units": "score", "graphs": ["test", "DeltaBlue"], "results": ["200.0"], "stddev": ""}, ], self._LoadResults()["traces"]) self._VerifyErrors([]) self._VerifyMockMultiple( (path.join("out", "x64.release", "d7"), "--flag", "run.js"), (path.join("out", "x64.release", "d7"), "--flag", "run.js"), (path.join("out", "x64.release", "d8"), "--flag", "run.js"), (path.join("out", "x64.release", "d8"), "--flag", "run.js"), (path.join("out", "x64.release", "d8"), "--flag", "run.js"), (path.join("out", "x64.release", "d8"), "--flag", "--flag2", "run.js")) def testOneRunStdDevRegExp(self): test_input = dict(V8_JSON) test_input["stddev_regexp"] = "^%s\-stddev: (.+)$" self._WriteTestInput(test_input) self._MockCommand(["."], ["Richards: 1.234\nRichards-stddev: 0.23\n" "DeltaBlue: 10657567\nDeltaBlue-stddev: 106\n"]) self.assertEquals(0, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": "0.23"}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": "106"}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testTwoRunsStdDevRegExp(self): test_input = dict(V8_JSON) test_input["stddev_regexp"] = "^%s\-stddev: (.+)$" test_input["run_count"] = 2 self._WriteTestInput(test_input) self._MockCommand(["."], ["Richards: 3\nRichards-stddev: 0.7\n" "DeltaBlue: 6\nDeltaBlue-boom: 0.9\n", "Richards: 2\nRichards-stddev: 0.5\n" "DeltaBlue: 5\nDeltaBlue-stddev: 0.8\n"]) self.assertEquals(1, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["2.0", "3.0"], "stddev": "0.7"}, {"name": "DeltaBlue", "results": ["5.0", "6.0"], "stddev": "0.8"}, ]) self._VerifyErrors( ["Test Richards should only run once since a stddev is provided " "by the test.", "Test DeltaBlue should only run once since a stddev is provided " "by the test.", "Regexp \"^DeltaBlue\-stddev: (.+)$\" didn't match for test " "DeltaBlue."]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testBuildbot(self): self._WriteTestInput(V8_JSON) self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567\n"]) self.assertEquals(0, self._CallMain("--buildbot")) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js") def testBuildbotWithTotal(self): test_input = dict(V8_JSON) test_input["total"] = True self._WriteTestInput(test_input) self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567\n"]) self.assertEquals(0, self._CallMain("--buildbot")) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, {"name": "Total", "results": ["3626.49109719"], "stddev": ""}, ]) self._VerifyErrors([]) self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js") def testBuildbotWithTotalAndErrors(self): test_input = dict(V8_JSON) test_input["total"] = True self._WriteTestInput(test_input) self._MockCommand(["."], ["x\nRichards: bla\nDeltaBlue: 10657567\ny\n"]) self.assertEquals(1, self._CallMain("--buildbot")) self._VerifyResults("test", "score", [ {"name": "Richards", "results": [], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) self._VerifyErrors( ["Regexp \"^Richards: (.+)$\" " "returned a non-numeric for test Richards.", "Not all traces have the same number of results."]) self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js") def testRegexpNoMatch(self): self._WriteTestInput(V8_JSON) self._MockCommand(["."], ["x\nRichaards: 1.234\nDeltaBlue: 10657567\ny\n"]) self.assertEquals(1, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": [], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) self._VerifyErrors( ["Regexp \"^Richards: (.+)$\" didn't match for test Richards."]) self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js") def testOneRunGeneric(self): test_input = dict(V8_GENERIC_JSON) self._WriteTestInput(test_input) self._MockCommand(["."], [ "RESULT Infra: Constant1= 11 count\n" "RESULT Infra: Constant2= [10,5,10,15] count\n" "RESULT Infra: Constant3= {12,1.2} count\n" "RESULT Infra: Constant4= [10,5,error,15] count\n"]) self.assertEquals(1, self._CallMain()) self.assertEquals([ {"units": "count", "graphs": ["test", "Infra", "Constant1"], "results": ["11.0"], "stddev": ""}, {"units": "count", "graphs": ["test", "Infra", "Constant2"], "results": ["10.0", "5.0", "10.0", "15.0"], "stddev": ""}, {"units": "count", "graphs": ["test", "Infra", "Constant3"], "results": ["12.0"], "stddev": "1.2"}, {"units": "count", "graphs": ["test", "Infra", "Constant4"], "results": [], "stddev": ""}, ], self._LoadResults()["traces"]) self._VerifyErrors(["Found non-numeric in test/Infra/Constant4"]) self._VerifyMock(path.join("out", "x64.release", "cc"), "--flag", "") def testOneRunTimingOut(self): test_input = dict(V8_JSON) test_input["timeout"] = 70 self._WriteTestInput(test_input) self._MockCommand(["."], [""], timed_out=True) self.assertEquals(1, self._CallMain()) self._VerifyResults("test", "score", [ {"name": "Richards", "results": [], "stddev": ""}, {"name": "DeltaBlue", "results": [], "stddev": ""}, ]) self._VerifyErrors([ "Regexp \"^Richards: (.+)$\" didn't match for test Richards.", "Regexp \"^DeltaBlue: (.+)$\" didn't match for test DeltaBlue.", ]) self._VerifyMock( path.join("out", "x64.release", "d7"), "--flag", "run.js", timeout=70) # Simple test that mocks out the android platform. Testing the platform would # require lots of complicated mocks for the android tools. def testAndroid(self): self._WriteTestInput(V8_JSON) platform = run_perf.Platform platform.PreExecution = MagicMock(return_value=None) platform.PostExecution = MagicMock(return_value=None) platform.PreTests = MagicMock(return_value=None) platform.Run = MagicMock( return_value="Richards: 1.234\nDeltaBlue: 10657567\n") run_perf.AndroidPlatform = MagicMock(return_value=platform) self.assertEquals( 0, self._CallMain("--android-build-tools", "/some/dir", "--arch", "android_arm")) self._VerifyResults("test", "score", [ {"name": "Richards", "results": ["1.234"], "stddev": ""}, {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""}, ]) node-v4.2.6/deps/v8/tools/testrunner/__init__.py000644 000766 000024 00000003043 12650222326 021720 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/v8/tools/testrunner/local/000755 000766 000024 00000000000 12650222326 020701 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/testrunner/network/000755 000766 000024 00000000000 12650222326 021300 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/testrunner/objects/000755 000766 000024 00000000000 12650222326 021240 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/testrunner/README000644 000766 000024 00000014640 12650222326 020474 0ustar00iojsstaff000000 000000 Test suite runner for V8, including support for distributed running. ==================================================================== Local usage instructions: ========================= Run the main script with --help to get detailed usage instructions: $ tools/run-tests.py --help The interface is mostly the same as it was for the old test runner. You'll likely want something like this: $ tools/run-tests.py --nonetwork --arch ia32 --mode release --nonetwork is the default on Mac and Windows. If you don't specify --arch and/or --mode, all available values will be used and run in turn (e.g., omitting --mode from the above example will run ia32 in both Release and Debug modes). Networked usage instructions: ============================= Networked running is only supported on Linux currently. Make sure that all machines participating in the cluster are binary-compatible (e.g. mixing Ubuntu Lucid and Precise doesn't work). Setup: ------ 1.) Copy tools/test-server.py to a new empty directory anywhere on your hard drive (preferably not inside your V8 checkout just to keep things clean). Please do create a copy, not just a symlink. 2.) Navigate to the new directory and let the server setup itself: $ ./test-server.py setup This will install PIP and UltraJSON, create a V8 working directory, and generate a keypair. 3.) Swap public keys with someone who's already part of the networked cluster. $ cp trusted/`cat data/mypubkey`.pem /where/peers/can/see/it/myname.pem $ ./test-server.py approve /wherever/they/put/it/yourname.pem Usage: ------ 1.) Start your server: $ ./test-server.py start 2.) (Optionally) inspect the server's status: $ ./test-server.py status 3.) From your regular V8 working directory, run tests: $ tool/run-tests.py --arch ia32 --mode debug 4.) (Optionally) enjoy the speeeeeeeeeeeeeeeed Architecture overview: ====================== Code organization: ------------------ This section is written from the point of view of the tools/ directory. ./run-tests.py: Main script. Parses command-line options and drives the test execution procedure from a high level. Imports the actual implementation of all steps from the testrunner/ directory. ./test-server.py: Interface to interact with the server. Contains code to setup the server's working environment and can start and stop server daemon processes. Imports some stuff from the testrunner/server/ directory. ./testrunner/local/*: Implementation needed to run tests locally. Used by run-tests.py. Inspired by (and partly copied verbatim from) the original test.py script. ./testrunner/objects/*: A bunch of data container classes, used by the scripts in the various other directories; serializable for transmission over the network. ./testrunner/network/*: Equivalents and extensions of some of the functionality in ./testrunner/local/ as required when dispatching tests to peers on the network. ./testrunner/network/network_execution.py: Drop-in replacement for ./testrunner/local/execution that distributes test jobs to network peers instead of running them locally. ./testrunner/network/endpoint.py: Receiving end of a network distributed job, uses the implementation in ./testrunner/local/execution.py for actually running the tests. ./testrunner/server/*: Implementation of the daemon that accepts and runs test execution jobs from peers on the network. Should ideally have no dependencies on any of the other directories, but that turned out to be impractical, so there are a few exceptions. ./testrunner/server/compression.py: Defines a wrapper around Python TCP sockets that provides JSON based serialization, gzip based compression, and ensures message completeness. Networking architecture: ------------------------ The distribution stuff is designed to be a layer between deciding which tests to run on the one side, and actually running them on the other. The frontend that the user interacts with is the same for local and networked execution, and the actual test execution and result gathering code is the same too. The server daemon starts four separate servers, each listening on another port: - "Local": Communication with a run-tests.py script running on the same host. The test driving script e.g. needs to ask for available peers. It then talks to those peers directly (one of them will be the locally running server). - "Work": Listens for test job requests from run-tests.py scripts on the network (including localhost). Accepts an arbitrary number of connections at the same time, but only works on them in a serialized fashion. - "Status": Used for communication with other servers on the network, e.g. for exchanging trusted public keys to create the transitive trust closure. - "Discovery": Used to detect presence of other peers on the network. In contrast to the other three, this uses UDP (as opposed to TCP). Give us a diagram! We love diagrams! ------------------------------------ . Machine A . Machine B . +------------------------------+ . | run-tests.py | . | with flag: | . |--nonetwork --network | . | | / | | . | | / | | . | v / v | . |BACKEND / distribution | . +--------- / --------| \ ------+ . / | \_____________________ / | . \ / | . \ +----- v ----------- v --------+ . +---- v -----------------------+ | LocalHandler | WorkHandler | . | WorkHandler | LocalHandler | | | | | . | | | | | | v | . | v | | | | BACKEND | . | BACKEND | | |------------- +---------------| . |---------------+--------------| | Discovery | StatusHandler <----------> StatusHandler | Discovery | +---- ^ -----------------------+ . +-------------------- ^ -------+ | . | +---------------------------------------------------------+ Note that the three occurrences of "BACKEND" are the same code (testrunner/local/execution.py and its imports), but running from three distinct directories (and on two different machines). node-v4.2.6/deps/v8/tools/testrunner/server/000755 000766 000024 00000000000 12650222326 021115 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/tools/testrunner/server/__init__.py000644 000766 000024 00000003043 12650222326 023226 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/v8/tools/testrunner/server/compression.py000644 000766 000024 00000006763 12650222326 024044 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import cStringIO as StringIO try: import ujson as json except ImportError: import json import os import struct import zlib from . import constants def Send(obj, sock): """ Sends a JSON encodable object over the specified socket (zlib-compressed). """ obj = json.dumps(obj) compression_level = 2 # 1 = fastest, 9 = best compression compressed = zlib.compress(obj, compression_level) payload = struct.pack('>i', len(compressed)) + compressed sock.sendall(payload) class Receiver(object): def __init__(self, sock): self.sock = sock self.data = StringIO.StringIO() self.datalength = 0 self._next = self._GetNext() def IsDone(self): return self._next == None def Current(self): return self._next def Advance(self): try: self._next = self._GetNext() except: raise def _GetNext(self): try: while self.datalength < constants.SIZE_T: try: chunk = self.sock.recv(8192) except: raise if not chunk: return None self._AppendData(chunk) size = self._PopData(constants.SIZE_T) size = struct.unpack(">i", size)[0] while self.datalength < size: try: chunk = self.sock.recv(8192) except: raise if not chunk: return None self._AppendData(chunk) result = self._PopData(size) result = zlib.decompress(result) result = json.loads(result) if result == constants.END_OF_STREAM: return None return result except: raise def _AppendData(self, new): self.data.seek(0, os.SEEK_END) self.data.write(new) self.datalength += len(new) def _PopData(self, length): self.data.seek(0) chunk = self.data.read(length) remaining = self.data.read() self.data.close() self.data = StringIO.StringIO() self.data.write(remaining) assert self.datalength - length == len(remaining) self.datalength = len(remaining) return chunk node-v4.2.6/deps/v8/tools/testrunner/server/constants.py000644 000766 000024 00000004741 12650222326 023511 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. CLIENT_PORT = 9991 # Port for the local client to connect to. PEER_PORT = 9992 # Port for peers on the network to connect to. PRESENCE_PORT = 9993 # Port for presence daemon. STATUS_PORT = 9994 # Port for network requests not related to workpackets. END_OF_STREAM = "end of dtest stream" # Marker for end of network requests. SIZE_T = 4 # Number of bytes used for network request size header. # Messages understood by the local request handler. ADD_TRUSTED = "add trusted" INFORM_DURATION = "inform about duration" REQUEST_PEERS = "get peers" UNRESPONSIVE_PEER = "unresponsive peer" REQUEST_PUBKEY_FINGERPRINT = "get pubkey fingerprint" REQUEST_STATUS = "get status" UPDATE_PERF = "update performance" # Messages understood by the status request handler. LIST_TRUSTED_PUBKEYS = "list trusted pubkeys" GET_SIGNED_PUBKEY = "pass on signed pubkey" NOTIFY_NEW_TRUSTED = "new trusted peer" TRUST_YOU_NOW = "trust you now" DO_YOU_TRUST = "do you trust" node-v4.2.6/deps/v8/tools/testrunner/server/daemon.py000644 000766 000024 00000007251 12650222326 022737 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # This code has been written by Sander Marechal and published at: # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ # where the author has placed it in the public domain (see comment #6 at # http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/#c6 # ). # Some minor modifications have been made by the V8 authors. The work remains # in the public domain. import atexit import os from signal import SIGTERM from signal import SIGINT import sys import time class Daemon(object): """ A generic daemon class. Usage: subclass the Daemon class and override the run() method """ def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile def daemonize(self): """ do the UNIX double-fork magic, see Stevens' "Advanced Programming in the UNIX Environment" for details (ISBN 0201563177) http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 """ try: pid = os.fork() if pid > 0: # exit first parent sys.exit(0) except OSError, e: sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # decouple from parent environment os.chdir("/") os.setsid() os.umask(0) # do second fork try: pid = os.fork() if pid > 0: # exit from second parent sys.exit(0) except OSError, e: sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) sys.exit(1) # redirect standard file descriptors sys.stdout.flush() sys.stderr.flush() si = file(self.stdin, 'r') so = file(self.stdout, 'a+') se = file(self.stderr, 'a+', 0) # TODO: (debug) re-enable this! #os.dup2(si.fileno(), sys.stdin.fileno()) #os.dup2(so.fileno(), sys.stdout.fileno()) #os.dup2(se.fileno(), sys.stderr.fileno()) # write pidfile atexit.register(self.delpid) pid = str(os.getpid()) file(self.pidfile, 'w+').write("%s\n" % pid) def delpid(self): os.remove(self.pidfile) def start(self): """ Start the daemon """ # Check for a pidfile to see if the daemon already runs try: pf = file(self.pidfile, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if pid: message = "pidfile %s already exist. Daemon already running?\n" sys.stderr.write(message % self.pidfile) sys.exit(1) # Start the daemon self.daemonize() self.run() def stop(self): """ Stop the daemon """ # Get the pid from the pidfile try: pf = file(self.pidfile, 'r') pid = int(pf.read().strip()) pf.close() except IOError: pid = None if not pid: message = "pidfile %s does not exist. Daemon not running?\n" sys.stderr.write(message % self.pidfile) return # not an error in a restart # Try killing the daemon process try: # Give the process a one-second chance to exit gracefully. os.kill(pid, SIGINT) time.sleep(1) while 1: os.kill(pid, SIGTERM) time.sleep(0.1) except OSError, err: err = str(err) if err.find("No such process") > 0: if os.path.exists(self.pidfile): os.remove(self.pidfile) else: print str(err) sys.exit(1) def restart(self): """ Restart the daemon """ self.stop() self.start() def run(self): """ You should override this method when you subclass Daemon. It will be called after the process has been daemonized by start() or restart(). """ node-v4.2.6/deps/v8/tools/testrunner/server/local_handler.py000644 000766 000024 00000010707 12650222326 024263 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import socket import SocketServer import StringIO from . import compression from . import constants def LocalQuery(query): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) code = sock.connect_ex(("localhost", constants.CLIENT_PORT)) if code != 0: return None compression.Send(query, sock) compression.Send(constants.END_OF_STREAM, sock) rec = compression.Receiver(sock) data = None while not rec.IsDone(): data = rec.Current() assert data[0] == query[0] data = data[1] rec.Advance() sock.close() return data class LocalHandler(SocketServer.BaseRequestHandler): def handle(self): rec = compression.Receiver(self.request) while not rec.IsDone(): data = rec.Current() action = data[0] if action == constants.REQUEST_PEERS: with self.server.daemon.peer_list_lock: response = [ p.Pack() for p in self.server.daemon.peers if p.trusting_me ] compression.Send([action, response], self.request) elif action == constants.UNRESPONSIVE_PEER: self.server.daemon.DeletePeer(data[1]) elif action == constants.REQUEST_PUBKEY_FINGERPRINT: compression.Send([action, self.server.daemon.pubkey_fingerprint], self.request) elif action == constants.REQUEST_STATUS: compression.Send([action, self._GetStatusMessage()], self.request) elif action == constants.ADD_TRUSTED: fingerprint = self.server.daemon.CopyToTrusted(data[1]) compression.Send([action, fingerprint], self.request) elif action == constants.INFORM_DURATION: test_key = data[1] test_duration = data[2] arch = data[3] mode = data[4] self.server.daemon.AddPerfData(test_key, test_duration, arch, mode) elif action == constants.UPDATE_PERF: address = data[1] perf = data[2] self.server.daemon.UpdatePeerPerformance(data[1], data[2]) rec.Advance() compression.Send(constants.END_OF_STREAM, self.request) def _GetStatusMessage(self): sio = StringIO.StringIO() sio.write("Peers:\n") with self.server.daemon.peer_list_lock: for p in self.server.daemon.peers: sio.write("%s\n" % p) sio.write("My own jobs: %d, relative performance: %.2f\n" % (self.server.daemon.jobs, self.server.daemon.relative_perf)) # Low-priority TODO: Return more information. Ideas: # - currently running anything, # - time since last job, # - time since last repository fetch # - number of workpackets/testcases handled since startup # - slowest test(s) result = sio.getvalue() sio.close() return result class LocalSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): def __init__(self, daemon): SocketServer.TCPServer.__init__(self, ("localhost", constants.CLIENT_PORT), LocalHandler) self.daemon = daemon node-v4.2.6/deps/v8/tools/testrunner/server/main.py000644 000766 000024 00000021400 12650222326 022410 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import multiprocessing import os import shutil import subprocess import threading import time from . import daemon from . import local_handler from . import presence_handler from . import signatures from . import status_handler from . import work_handler from ..network import perfdata class Server(daemon.Daemon): def __init__(self, pidfile, root, stdin="/dev/null", stdout="/dev/null", stderr="/dev/null"): super(Server, self).__init__(pidfile, stdin, stdout, stderr) self.root = root self.local_handler = None self.local_handler_thread = None self.work_handler = None self.work_handler_thread = None self.status_handler = None self.status_handler_thread = None self.presence_daemon = None self.presence_daemon_thread = None self.peers = [] self.jobs = multiprocessing.cpu_count() self.peer_list_lock = threading.Lock() self.perf_data_lock = None self.presence_daemon_lock = None self.datadir = os.path.join(self.root, "data") pubkey_fingerprint_filename = os.path.join(self.datadir, "mypubkey") with open(pubkey_fingerprint_filename) as f: self.pubkey_fingerprint = f.read().strip() self.relative_perf_filename = os.path.join(self.datadir, "myperf") if os.path.exists(self.relative_perf_filename): with open(self.relative_perf_filename) as f: try: self.relative_perf = float(f.read()) except: self.relative_perf = 1.0 else: self.relative_perf = 1.0 def run(self): os.nice(20) self.ip = presence_handler.GetOwnIP() self.perf_data_manager = perfdata.PerfDataManager(self.datadir) self.perf_data_lock = threading.Lock() self.local_handler = local_handler.LocalSocketServer(self) self.local_handler_thread = threading.Thread( target=self.local_handler.serve_forever) self.local_handler_thread.start() self.work_handler = work_handler.WorkSocketServer(self) self.work_handler_thread = threading.Thread( target=self.work_handler.serve_forever) self.work_handler_thread.start() self.status_handler = status_handler.StatusSocketServer(self) self.status_handler_thread = threading.Thread( target=self.status_handler.serve_forever) self.status_handler_thread.start() self.presence_daemon = presence_handler.PresenceDaemon(self) self.presence_daemon_thread = threading.Thread( target=self.presence_daemon.serve_forever) self.presence_daemon_thread.start() self.presence_daemon.FindPeers() time.sleep(0.5) # Give those peers some time to reply. with self.peer_list_lock: for p in self.peers: if p.address == self.ip: continue status_handler.RequestTrustedPubkeys(p, self) while True: try: self.PeriodicTasks() time.sleep(60) except Exception, e: print("MAIN LOOP EXCEPTION: %s" % e) self.Shutdown() break except KeyboardInterrupt: self.Shutdown() break def Shutdown(self): with open(self.relative_perf_filename, "w") as f: f.write("%s" % self.relative_perf) self.presence_daemon.shutdown() self.presence_daemon.server_close() self.local_handler.shutdown() self.local_handler.server_close() self.work_handler.shutdown() self.work_handler.server_close() self.status_handler.shutdown() self.status_handler.server_close() def PeriodicTasks(self): # If we know peers we don't trust, see if someone else trusts them. with self.peer_list_lock: for p in self.peers: if p.trusted: continue if self.IsTrusted(p.pubkey): p.trusted = True status_handler.ITrustYouNow(p) continue for p2 in self.peers: if not p2.trusted: continue status_handler.TryTransitiveTrust(p2, p.pubkey, self) # TODO: Ping for more peers waiting to be discovered. # TODO: Update the checkout (if currently idle). def AddPeer(self, peer): with self.peer_list_lock: for p in self.peers: if p.address == peer.address: return self.peers.append(peer) if peer.trusted: status_handler.ITrustYouNow(peer) def DeletePeer(self, peer_address): with self.peer_list_lock: for i in xrange(len(self.peers)): if self.peers[i].address == peer_address: del self.peers[i] return def MarkPeerAsTrusting(self, peer_address): with self.peer_list_lock: for p in self.peers: if p.address == peer_address: p.trusting_me = True break def UpdatePeerPerformance(self, peer_address, performance): with self.peer_list_lock: for p in self.peers: if p.address == peer_address: p.relative_performance = performance def CopyToTrusted(self, pubkey_filename): with open(pubkey_filename, "r") as f: lines = f.readlines() fingerprint = lines[-1].strip() target_filename = self._PubkeyFilename(fingerprint) shutil.copy(pubkey_filename, target_filename) with self.peer_list_lock: for peer in self.peers: if peer.address == self.ip: continue if peer.pubkey == fingerprint: status_handler.ITrustYouNow(peer) else: result = self.SignTrusted(fingerprint) status_handler.NotifyNewTrusted(peer, result) return fingerprint def _PubkeyFilename(self, pubkey_fingerprint): return os.path.join(self.root, "trusted", "%s.pem" % pubkey_fingerprint) def IsTrusted(self, pubkey_fingerprint): return os.path.exists(self._PubkeyFilename(pubkey_fingerprint)) def ListTrusted(self): path = os.path.join(self.root, "trusted") if not os.path.exists(path): return [] return [ f[:-4] for f in os.listdir(path) if f.endswith(".pem") ] def SignTrusted(self, pubkey_fingerprint): if not self.IsTrusted(pubkey_fingerprint): return [] filename = self._PubkeyFilename(pubkey_fingerprint) result = signatures.ReadFileAndSignature(filename) # Format: [key, sig]. return [pubkey_fingerprint, result[0], result[1], self.pubkey_fingerprint] def AcceptNewTrusted(self, data): # The format of |data| matches the return value of |SignTrusted()|. if not data: return fingerprint = data[0] pubkey = data[1] signature = data[2] signer = data[3] if not self.IsTrusted(signer): return if self.IsTrusted(fingerprint): return # Already trust this guy. filename = self._PubkeyFilename(fingerprint) signer_pubkeyfile = self._PubkeyFilename(signer) if not signatures.VerifySignature(filename, pubkey, signature, signer_pubkeyfile): return return # Nothing more to do. def AddPerfData(self, test_key, duration, arch, mode): data_store = self.perf_data_manager.GetStore(arch, mode) data_store.RawUpdatePerfData(str(test_key), duration) def CompareOwnPerf(self, test, arch, mode): data_store = self.perf_data_manager.GetStore(arch, mode) observed = data_store.FetchPerfData(test) if not observed: return own_perf_estimate = observed / test.duration with self.perf_data_lock: kLearnRateLimiter = 9999 self.relative_perf *= kLearnRateLimiter self.relative_perf += own_perf_estimate self.relative_perf /= (kLearnRateLimiter + 1) node-v4.2.6/deps/v8/tools/testrunner/server/presence_handler.py000644 000766 000024 00000010533 12650222326 024772 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import socket import SocketServer import threading try: import ujson as json except: import json from . import constants from ..objects import peer STARTUP_REQUEST = "V8 test peer starting up" STARTUP_RESPONSE = "Let's rock some tests!" EXIT_REQUEST = "V8 testing peer going down" def GetOwnIP(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(("8.8.8.8", 80)) ip = s.getsockname()[0] s.close() return ip class PresenceHandler(SocketServer.BaseRequestHandler): def handle(self): data = json.loads(self.request[0].strip()) if data[0] == STARTUP_REQUEST: jobs = data[1] relative_perf = data[2] pubkey_fingerprint = data[3] trusted = self.server.daemon.IsTrusted(pubkey_fingerprint) response = [STARTUP_RESPONSE, self.server.daemon.jobs, self.server.daemon.relative_perf, self.server.daemon.pubkey_fingerprint, trusted] response = json.dumps(response) self.server.SendTo(self.client_address[0], response) p = peer.Peer(self.client_address[0], jobs, relative_perf, pubkey_fingerprint) p.trusted = trusted self.server.daemon.AddPeer(p) elif data[0] == STARTUP_RESPONSE: jobs = data[1] perf = data[2] pubkey_fingerprint = data[3] p = peer.Peer(self.client_address[0], jobs, perf, pubkey_fingerprint) p.trusted = self.server.daemon.IsTrusted(pubkey_fingerprint) p.trusting_me = data[4] self.server.daemon.AddPeer(p) elif data[0] == EXIT_REQUEST: self.server.daemon.DeletePeer(self.client_address[0]) if self.client_address[0] == self.server.daemon.ip: self.server.shutdown_lock.release() class PresenceDaemon(SocketServer.ThreadingMixIn, SocketServer.UDPServer): def __init__(self, daemon): self.daemon = daemon address = (daemon.ip, constants.PRESENCE_PORT) SocketServer.UDPServer.__init__(self, address, PresenceHandler) self.shutdown_lock = threading.Lock() def shutdown(self): self.shutdown_lock.acquire() self.SendToAll(json.dumps([EXIT_REQUEST])) self.shutdown_lock.acquire() self.shutdown_lock.release() SocketServer.UDPServer.shutdown(self) def SendTo(self, target, message): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(message, (target, constants.PRESENCE_PORT)) sock.close() def SendToAll(self, message): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ip = self.daemon.ip.split(".") for i in range(1, 254): ip[-1] = str(i) sock.sendto(message, (".".join(ip), constants.PRESENCE_PORT)) sock.close() def FindPeers(self): request = [STARTUP_REQUEST, self.daemon.jobs, self.daemon.relative_perf, self.daemon.pubkey_fingerprint] request = json.dumps(request) self.SendToAll(request) node-v4.2.6/deps/v8/tools/testrunner/server/signatures.py000644 000766 000024 00000005400 12650222326 023652 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 import os import subprocess def ReadFileAndSignature(filename): with open(filename, "rb") as f: file_contents = base64.b64encode(f.read()) signature_file = filename + ".signature" if (not os.path.exists(signature_file) or os.path.getmtime(signature_file) < os.path.getmtime(filename)): private_key = "~/.ssh/v8_dtest" code = subprocess.call("openssl dgst -out %s -sign %s %s" % (signature_file, private_key, filename), shell=True) if code != 0: return [None, code] with open(signature_file) as f: signature = base64.b64encode(f.read()) return [file_contents, signature] def VerifySignature(filename, file_contents, signature, pubkeyfile): with open(filename, "wb") as f: f.write(base64.b64decode(file_contents)) signature_file = filename + ".foreign_signature" with open(signature_file, "wb") as f: f.write(base64.b64decode(signature)) code = subprocess.call("openssl dgst -verify %s -signature %s %s" % (pubkeyfile, signature_file, filename), shell=True) matched = (code == 0) if not matched: os.remove(signature_file) os.remove(filename) return matched node-v4.2.6/deps/v8/tools/testrunner/server/status_handler.py000644 000766 000024 00000010072 12650222326 024507 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import socket import SocketServer from . import compression from . import constants def _StatusQuery(peer, query): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) code = sock.connect_ex((peer.address, constants.STATUS_PORT)) if code != 0: # TODO(jkummerow): disconnect (after 3 failures?) return compression.Send(query, sock) compression.Send(constants.END_OF_STREAM, sock) rec = compression.Receiver(sock) data = None while not rec.IsDone(): data = rec.Current() assert data[0] == query[0] data = data[1] rec.Advance() sock.close() return data def RequestTrustedPubkeys(peer, server): pubkey_list = _StatusQuery(peer, [constants.LIST_TRUSTED_PUBKEYS]) for pubkey in pubkey_list: if server.IsTrusted(pubkey): continue result = _StatusQuery(peer, [constants.GET_SIGNED_PUBKEY, pubkey]) server.AcceptNewTrusted(result) def NotifyNewTrusted(peer, data): _StatusQuery(peer, [constants.NOTIFY_NEW_TRUSTED] + data) def ITrustYouNow(peer): _StatusQuery(peer, [constants.TRUST_YOU_NOW]) def TryTransitiveTrust(peer, pubkey, server): if _StatusQuery(peer, [constants.DO_YOU_TRUST, pubkey]): result = _StatusQuery(peer, [constants.GET_SIGNED_PUBKEY, pubkey]) server.AcceptNewTrusted(result) class StatusHandler(SocketServer.BaseRequestHandler): def handle(self): rec = compression.Receiver(self.request) while not rec.IsDone(): data = rec.Current() action = data[0] if action == constants.LIST_TRUSTED_PUBKEYS: response = self.server.daemon.ListTrusted() compression.Send([action, response], self.request) elif action == constants.GET_SIGNED_PUBKEY: response = self.server.daemon.SignTrusted(data[1]) compression.Send([action, response], self.request) elif action == constants.NOTIFY_NEW_TRUSTED: self.server.daemon.AcceptNewTrusted(data[1:]) pass # No response. elif action == constants.TRUST_YOU_NOW: self.server.daemon.MarkPeerAsTrusting(self.client_address[0]) pass # No response. elif action == constants.DO_YOU_TRUST: response = self.server.daemon.IsTrusted(data[1]) compression.Send([action, response], self.request) rec.Advance() compression.Send(constants.END_OF_STREAM, self.request) class StatusSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): def __init__(self, daemon): address = (daemon.ip, constants.STATUS_PORT) SocketServer.TCPServer.__init__(self, address, StatusHandler) self.daemon = daemon node-v4.2.6/deps/v8/tools/testrunner/server/work_handler.py000644 000766 000024 00000012701 12650222326 024147 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import SocketServer import stat import subprocess import threading from . import compression from . import constants from . import signatures from ..network import endpoint from ..objects import workpacket class WorkHandler(SocketServer.BaseRequestHandler): def handle(self): rec = compression.Receiver(self.request) while not rec.IsDone(): data = rec.Current() with self.server.job_lock: self._WorkOnWorkPacket(data) rec.Advance() def _WorkOnWorkPacket(self, data): server_root = self.server.daemon.root v8_root = os.path.join(server_root, "v8") os.chdir(v8_root) packet = workpacket.WorkPacket.Unpack(data) self.ctx = packet.context self.ctx.shell_dir = os.path.join("out", "%s.%s" % (self.ctx.arch, self.ctx.mode)) if not os.path.isdir(self.ctx.shell_dir): os.makedirs(self.ctx.shell_dir) for binary in packet.binaries: if not self._UnpackBinary(binary, packet.pubkey_fingerprint): return if not self._CheckoutRevision(packet.base_revision): return if not self._ApplyPatch(packet.patch): return tests = packet.tests endpoint.Execute(v8_root, self.ctx, tests, self.request, self.server.daemon) self._SendResponse() def _SendResponse(self, error_message=None): try: if error_message: compression.Send([[-1, error_message]], self.request) compression.Send(constants.END_OF_STREAM, self.request) return except Exception, e: pass # Peer is gone. There's nothing we can do. # Clean up. self._Call("git checkout -f") self._Call("git clean -f -d") self._Call("rm -rf %s" % self.ctx.shell_dir) def _UnpackBinary(self, binary, pubkey_fingerprint): binary_name = binary["name"] if binary_name == "libv8.so": libdir = os.path.join(self.ctx.shell_dir, "lib.target") if not os.path.exists(libdir): os.makedirs(libdir) target = os.path.join(libdir, binary_name) else: target = os.path.join(self.ctx.shell_dir, binary_name) pubkeyfile = "../trusted/%s.pem" % pubkey_fingerprint if not signatures.VerifySignature(target, binary["blob"], binary["sign"], pubkeyfile): self._SendResponse("Signature verification failed") return False os.chmod(target, stat.S_IRWXU) return True def _CheckoutRevision(self, base_svn_revision): get_hash_cmd = ( "git log -1 --format=%%H --remotes --grep='^git-svn-id:.*@%s'" % base_svn_revision) try: base_revision = subprocess.check_output(get_hash_cmd, shell=True) if not base_revision: raise ValueError except: self._Call("git fetch") try: base_revision = subprocess.check_output(get_hash_cmd, shell=True) if not base_revision: raise ValueError except: self._SendResponse("Base revision not found.") return False code = self._Call("git checkout -f %s" % base_revision) if code != 0: self._SendResponse("Error trying to check out base revision.") return False code = self._Call("git clean -f -d") if code != 0: self._SendResponse("Failed to reset checkout") return False return True def _ApplyPatch(self, patch): if not patch: return True # Just skip if the patch is empty. patchfilename = "_dtest_incoming_patch.patch" with open(patchfilename, "w") as f: f.write(patch) code = self._Call("git apply %s" % patchfilename) if code != 0: self._SendResponse("Error applying patch.") return False return True def _Call(self, cmd): return subprocess.call(cmd, shell=True) class WorkSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): def __init__(self, daemon): address = (daemon.ip, constants.PEER_PORT) SocketServer.TCPServer.__init__(self, address, WorkHandler) self.job_lock = threading.Lock() self.daemon = daemon node-v4.2.6/deps/v8/tools/testrunner/objects/__init__.py000644 000766 000024 00000003043 12650222326 023351 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/v8/tools/testrunner/objects/context.py000644 000766 000024 00000005726 12650222326 023310 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class Context(): def __init__(self, arch, mode, shell_dir, mode_flags, verbose, timeout, isolates, command_prefix, extra_flags, noi18n, random_seed, no_sorting, rerun_failures_count, rerun_failures_max, predictable, no_harness): self.arch = arch self.mode = mode self.shell_dir = shell_dir self.mode_flags = mode_flags self.verbose = verbose self.timeout = timeout self.isolates = isolates self.command_prefix = command_prefix self.extra_flags = extra_flags self.noi18n = noi18n self.random_seed = random_seed self.no_sorting = no_sorting self.rerun_failures_count = rerun_failures_count self.rerun_failures_max = rerun_failures_max self.predictable = predictable self.no_harness = no_harness def Pack(self): return [self.arch, self.mode, self.mode_flags, self.timeout, self.isolates, self.command_prefix, self.extra_flags, self.noi18n, self.random_seed, self.no_sorting, self.rerun_failures_count, self.rerun_failures_max, self.predictable, self.no_harness] @staticmethod def Unpack(packed): # For the order of the fields, refer to Pack() above. return Context(packed[0], packed[1], None, packed[2], False, packed[3], packed[4], packed[5], packed[6], packed[7], packed[8], packed[9], packed[10], packed[11], packed[12], packed[13]) node-v4.2.6/deps/v8/tools/testrunner/objects/output.py000644 000766 000024 00000004613 12650222326 023156 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import signal from ..local import utils class Output(object): def __init__(self, exit_code, timed_out, stdout, stderr): self.exit_code = exit_code self.timed_out = timed_out self.stdout = stdout self.stderr = stderr def HasCrashed(self): if utils.IsWindows(): return 0x80000000 & self.exit_code and not (0x3FFFFF00 & self.exit_code) else: # Timed out tests will have exit_code -signal.SIGTERM. if self.timed_out: return False return (self.exit_code < 0 and self.exit_code != -signal.SIGABRT) def HasTimedOut(self): return self.timed_out def Pack(self): return [self.exit_code, self.timed_out, self.stdout, self.stderr] @staticmethod def Unpack(packed): # For the order of the fields, refer to Pack() above. return Output(packed[0], packed[1], packed[2], packed[3]) node-v4.2.6/deps/v8/tools/testrunner/objects/peer.py000644 000766 000024 00000006751 12650222326 022556 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class Peer(object): def __init__(self, address, jobs, rel_perf, pubkey): self.address = address # string: IP address self.jobs = jobs # integer: number of CPUs self.relative_performance = rel_perf self.pubkey = pubkey # string: pubkey's fingerprint self.shells = set() # set of strings self.needed_work = 0 self.assigned_work = 0 self.tests = [] # list of TestCase objects self.trusting_me = False # This peer trusts my public key. self.trusted = False # I trust this peer's public key. def __str__(self): return ("Peer at %s, jobs: %d, performance: %.2f, trust I/O: %s/%s" % (self.address, self.jobs, self.relative_performance, self.trusting_me, self.trusted)) def AddTests(self, shell): """Adds tests from |shell| to this peer. Stops when self.needed_work reaches zero, or when all of shell's tests are assigned.""" assert self.needed_work > 0 if shell.shell not in self.shells: self.shells.add(shell.shell) while len(shell.tests) > 0 and self.needed_work > 0: t = shell.tests.pop() self.needed_work -= t.duration self.assigned_work += t.duration shell.total_duration -= t.duration self.tests.append(t) def ForceAddOneTest(self, test, shell): """Forcibly adds another test to this peer, disregarding needed_work.""" if shell.shell not in self.shells: self.shells.add(shell.shell) self.needed_work -= test.duration self.assigned_work += test.duration shell.total_duration -= test.duration self.tests.append(test) def Pack(self): """Creates a JSON serializable representation of this Peer.""" return [self.address, self.jobs, self.relative_performance] @staticmethod def Unpack(packed): """Creates a Peer object built from a packed representation.""" pubkey_dummy = "" # Callers of this don't care (only the server does). return Peer(packed[0], packed[1], packed[2], pubkey_dummy) node-v4.2.6/deps/v8/tools/testrunner/objects/testcase.py000644 000766 000024 00000007023 12650222326 023427 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from . import output class TestCase(object): def __init__(self, suite, path, flags=None, dependency=None): self.suite = suite # TestSuite object self.path = path # string, e.g. 'div-mod', 'test-api/foo' self.flags = flags or [] # list of strings, flags specific to this test self.dependency = dependency # |path| for testcase that must be run first self.outcomes = set([]) self.output = None self.id = None # int, used to map result back to TestCase instance self.duration = None # assigned during execution self.run = 1 # The nth time this test is executed. def CopyAddingFlags(self, flags): copy = TestCase(self.suite, self.path, self.flags + flags, self.dependency) copy.outcomes = self.outcomes return copy def PackTask(self): """ Extracts those parts of this object that are required to run the test and returns them as a JSON serializable object. """ assert self.id is not None return [self.suitename(), self.path, self.flags, self.dependency, list(self.outcomes or []), self.id] @staticmethod def UnpackTask(task): """Creates a new TestCase object based on packed task data.""" # For the order of the fields, refer to PackTask() above. test = TestCase(str(task[0]), task[1], task[2], task[3]) test.outcomes = set(task[4]) test.id = task[5] test.run = 1 return test def SetSuiteObject(self, suites): self.suite = suites[self.suite] def PackResult(self): """Serializes the output of the TestCase after it has run.""" self.suite.StripOutputForTransmit(self) return [self.id, self.output.Pack(), self.duration] def MergeResult(self, result): """Applies the contents of a Result to this object.""" assert result[0] == self.id self.output = output.Output.Unpack(result[1]) self.duration = result[2] def suitename(self): return self.suite.name def GetLabel(self): return self.suitename() + "/" + self.suite.CommonTestName(self) node-v4.2.6/deps/v8/tools/testrunner/objects/workpacket.py000644 000766 000024 00000006760 12650222326 023775 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from . import context from . import testcase class WorkPacket(object): def __init__(self, peer=None, context=None, tests=None, binaries=None, base_revision=None, patch=None, pubkey=None): self.peer = peer self.context = context self.tests = tests self.binaries = binaries self.base_revision = base_revision self.patch = patch self.pubkey_fingerprint = pubkey def Pack(self, binaries_dict): """ Creates a JSON serializable object containing the data of this work packet. """ need_libv8 = False binaries = [] for shell in self.peer.shells: prefetched_binary = binaries_dict[shell] binaries.append({"name": shell, "blob": prefetched_binary[0], "sign": prefetched_binary[1]}) if prefetched_binary[2]: need_libv8 = True if need_libv8: libv8 = binaries_dict["libv8.so"] binaries.append({"name": "libv8.so", "blob": libv8[0], "sign": libv8[1]}) tests = [] test_map = {} for t in self.peer.tests: test_map[t.id] = t tests.append(t.PackTask()) result = { "binaries": binaries, "pubkey": self.pubkey_fingerprint, "context": self.context.Pack(), "base_revision": self.base_revision, "patch": self.patch, "tests": tests } return result, test_map @staticmethod def Unpack(packed): """ Creates a WorkPacket object from the given packed representation. """ binaries = packed["binaries"] pubkey_fingerprint = packed["pubkey"] ctx = context.Context.Unpack(packed["context"]) base_revision = packed["base_revision"] patch = packed["patch"] tests = [ testcase.TestCase.UnpackTask(t) for t in packed["tests"] ] return WorkPacket(context=ctx, tests=tests, binaries=binaries, base_revision=base_revision, patch=patch, pubkey=pubkey_fingerprint) node-v4.2.6/deps/v8/tools/testrunner/network/__init__.py000644 000766 000024 00000003043 12650222326 023411 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/v8/tools/testrunner/network/distro.py000644 000766 000024 00000007313 12650222326 023162 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class Shell(object): def __init__(self, shell): self.shell = shell self.tests = [] self.total_duration = 0.0 def AddSuite(self, suite): self.tests += suite.tests self.total_duration += suite.total_duration def SortTests(self): self.tests.sort(cmp=lambda x, y: cmp(x.duration, y.duration)) def Assign(suites, peers): total_work = 0.0 for s in suites: total_work += s.CalculateTotalDuration() total_power = 0.0 for p in peers: p.assigned_work = 0.0 total_power += p.jobs * p.relative_performance for p in peers: p.needed_work = total_work * p.jobs * p.relative_performance / total_power shells = {} for s in suites: shell = s.shell() if not shell in shells: shells[shell] = Shell(shell) shells[shell].AddSuite(s) # Convert |shells| to list and sort it, shortest total_duration first. shells = [ shells[s] for s in shells ] shells.sort(cmp=lambda x, y: cmp(x.total_duration, y.total_duration)) # Sort tests within each shell, longest duration last (so it's # pop()'ed first). for s in shells: s.SortTests() # Sort peers, least needed_work first. peers.sort(cmp=lambda x, y: cmp(x.needed_work, y.needed_work)) index = 0 for shell in shells: while len(shell.tests) > 0: while peers[index].needed_work <= 0: index += 1 if index == len(peers): print("BIG FAT WARNING: Assigning tests to peers failed. " "Remaining tests: %d. Going to slow mode." % len(shell.tests)) # Pick the least-busy peer. Sorting the list for each test # is terribly slow, but this is just an emergency fallback anyway. peers.sort(cmp=lambda x, y: cmp(x.needed_work, y.needed_work)) peers[0].ForceAddOneTest(shell.tests.pop(), shell) # If the peer already has a shell assigned and would need this one # and then yet another, try to avoid it. peer = peers[index] if (shell.total_duration < peer.needed_work and len(peer.shells) > 0 and index < len(peers) - 1 and shell.total_duration <= peers[index + 1].needed_work): peers[index + 1].AddTests(shell) else: peer.AddTests(shell) node-v4.2.6/deps/v8/tools/testrunner/network/endpoint.py000644 000766 000024 00000010624 12650222326 023475 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import multiprocessing import os import Queue import threading import time from ..local import execution from ..local import progress from ..local import testsuite from ..local import utils from ..server import compression class EndpointProgress(progress.ProgressIndicator): def __init__(self, sock, server, ctx): super(EndpointProgress, self).__init__() self.sock = sock self.server = server self.context = ctx self.results_queue = [] # Accessors must synchronize themselves. self.sender_lock = threading.Lock() self.senderthread = threading.Thread(target=self._SenderThread) self.senderthread.start() def HasRun(self, test, has_unexpected_output): # The runners that call this have a lock anyway, so this is safe. self.results_queue.append(test) def _SenderThread(self): keep_running = True tests = [] self.sender_lock.acquire() while keep_running: time.sleep(0.1) # This should be "atomic enough" without locking :-) # (We don't care which list any new elements get appended to, as long # as we don't lose any and the last one comes last.) current = self.results_queue self.results_queue = [] for c in current: if c is None: keep_running = False else: tests.append(c) if keep_running and len(tests) < 1: continue # Wait for more results. if len(tests) < 1: break # We're done here. result = [] for t in tests: result.append(t.PackResult()) try: compression.Send(result, self.sock) except: self.runner.terminate = True for t in tests: self.server.CompareOwnPerf(t, self.context.arch, self.context.mode) tests = [] self.sender_lock.release() def Execute(workspace, ctx, tests, sock, server): suite_paths = utils.GetSuitePaths(os.path.join(workspace, "test")) suites = [] for root in suite_paths: suite = testsuite.TestSuite.LoadTestSuite( os.path.join(workspace, "test", root)) if suite: suites.append(suite) suites_dict = {} for s in suites: suites_dict[s.name] = s s.tests = [] for t in tests: suite = suites_dict[t.suite] t.suite = suite suite.tests.append(t) suites = [ s for s in suites if len(s.tests) > 0 ] for s in suites: s.DownloadData() progress_indicator = EndpointProgress(sock, server, ctx) runner = execution.Runner(suites, progress_indicator, ctx) try: runner.Run(server.jobs) except IOError, e: if e.errno == 2: message = ("File not found: %s, maybe you forgot to 'git add' it?" % e.filename) else: message = "%s" % e compression.Send([[-1, message]], sock) progress_indicator.HasRun(None, None) # Sentinel to signal the end. progress_indicator.sender_lock.acquire() # Released when sending is done. progress_indicator.sender_lock.release() node-v4.2.6/deps/v8/tools/testrunner/network/network_execution.py000644 000766 000024 00000024207 12650222326 025433 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import socket import subprocess import threading import time from . import distro from ..local import execution from ..local import perfdata from ..objects import peer from ..objects import workpacket from ..server import compression from ..server import constants from ..server import local_handler from ..server import signatures def GetPeers(): data = local_handler.LocalQuery([constants.REQUEST_PEERS]) if not data: return [] return [ peer.Peer.Unpack(p) for p in data ] class NetworkedRunner(execution.Runner): def __init__(self, suites, progress_indicator, context, peers, workspace): self.suites = suites datapath = os.path.join("out", "testrunner_data") # TODO(machenbach): These fields should exist now in the superclass. # But there is no super constructor call. Check if this is a problem. self.perf_data_manager = perfdata.PerfDataManager(datapath) self.perfdata = self.perf_data_manager.GetStore(context.arch, context.mode) for s in suites: for t in s.tests: t.duration = self.perfdata.FetchPerfData(t) or 1.0 self._CommonInit(suites, progress_indicator, context) self.tests = [] # Only used if we need to fall back to local execution. self.tests_lock = threading.Lock() self.peers = peers self.pubkey_fingerprint = None # Fetched later. self.base_rev = subprocess.check_output( "cd %s; git log -1 --format=%%H --grep=git-svn-id" % workspace, shell=True).strip() self.base_svn_rev = subprocess.check_output( "cd %s; git log -1 %s" # Get commit description. " | grep -e '^\s*git-svn-id:'" # Extract "git-svn-id" line. " | awk '{print $2}'" # Extract "repository@revision" part. " | sed -e 's/.*@//'" % # Strip away "repository@". (workspace, self.base_rev), shell=True).strip() self.patch = subprocess.check_output( "cd %s; git diff %s" % (workspace, self.base_rev), shell=True) self.binaries = {} self.initialization_lock = threading.Lock() self.initialization_lock.acquire() # Released when init is done. self._OpenLocalConnection() self.local_receiver_thread = threading.Thread( target=self._ListenLocalConnection) self.local_receiver_thread.daemon = True self.local_receiver_thread.start() self.initialization_lock.acquire() self.initialization_lock.release() def _OpenLocalConnection(self): self.local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) code = self.local_socket.connect_ex(("localhost", constants.CLIENT_PORT)) if code != 0: raise RuntimeError("Failed to connect to local server") compression.Send([constants.REQUEST_PUBKEY_FINGERPRINT], self.local_socket) def _ListenLocalConnection(self): release_lock_countdown = 1 # Pubkey. self.local_receiver = compression.Receiver(self.local_socket) while not self.local_receiver.IsDone(): data = self.local_receiver.Current() if data[0] == constants.REQUEST_PUBKEY_FINGERPRINT: pubkey = data[1] if not pubkey: raise RuntimeError("Received empty public key") self.pubkey_fingerprint = pubkey release_lock_countdown -= 1 if release_lock_countdown == 0: self.initialization_lock.release() release_lock_countdown -= 1 # Prevent repeated triggering. self.local_receiver.Advance() def Run(self, jobs): self.indicator.Starting() need_libv8 = False for s in self.suites: shell = s.shell() if shell not in self.binaries: path = os.path.join(self.context.shell_dir, shell) # Check if this is a shared library build. try: ldd = subprocess.check_output("ldd %s | grep libv8\\.so" % (path), shell=True) ldd = ldd.strip().split(" ") assert ldd[0] == "libv8.so" assert ldd[1] == "=>" need_libv8 = True binary_needs_libv8 = True libv8 = signatures.ReadFileAndSignature(ldd[2]) except: binary_needs_libv8 = False binary = signatures.ReadFileAndSignature(path) if binary[0] is None: print("Error: Failed to create signature.") assert binary[1] != 0 return binary[1] binary.append(binary_needs_libv8) self.binaries[shell] = binary if need_libv8: self.binaries["libv8.so"] = libv8 distro.Assign(self.suites, self.peers) # Spawn one thread for each peer. threads = [] for p in self.peers: thread = threading.Thread(target=self._TalkToPeer, args=[p]) threads.append(thread) thread.start() try: for thread in threads: # Use a timeout so that signals (Ctrl+C) will be processed. thread.join(timeout=10000000) self._AnalyzePeerRuntimes() except KeyboardInterrupt: self.terminate = True raise except Exception, _e: # If there's an exception we schedule an interruption for any # remaining threads... self.terminate = True # ...and then reraise the exception to bail out. raise compression.Send(constants.END_OF_STREAM, self.local_socket) self.local_socket.close() if self.tests: self._RunInternal(jobs) self.indicator.Done() return not self.failed def _TalkToPeer(self, peer): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(self.context.timeout + 10) code = sock.connect_ex((peer.address, constants.PEER_PORT)) if code == 0: try: peer.runtime = None start_time = time.time() packet = workpacket.WorkPacket(peer=peer, context=self.context, base_revision=self.base_svn_rev, patch=self.patch, pubkey=self.pubkey_fingerprint) data, test_map = packet.Pack(self.binaries) compression.Send(data, sock) compression.Send(constants.END_OF_STREAM, sock) rec = compression.Receiver(sock) while not rec.IsDone() and not self.terminate: data_list = rec.Current() for data in data_list: test_id = data[0] if test_id < 0: # The peer is reporting an error. with self.lock: print("\nPeer %s reports error: %s" % (peer.address, data[1])) continue test = test_map.pop(test_id) test.MergeResult(data) try: self.perfdata.UpdatePerfData(test) except Exception, e: print("UpdatePerfData exception: %s" % e) pass # Just keep working. with self.lock: perf_key = self.perfdata.GetKey(test) compression.Send( [constants.INFORM_DURATION, perf_key, test.duration, self.context.arch, self.context.mode], self.local_socket) self.indicator.AboutToRun(test) has_unexpected_output = test.suite.HasUnexpectedOutput(test) if has_unexpected_output: self.failed.append(test) if test.output.HasCrashed(): self.crashed += 1 else: self.succeeded += 1 self.remaining -= 1 self.indicator.HasRun(test, has_unexpected_output) rec.Advance() peer.runtime = time.time() - start_time except KeyboardInterrupt: sock.close() raise except Exception, e: print("Got exception: %s" % e) pass # Fall back to local execution. else: compression.Send([constants.UNRESPONSIVE_PEER, peer.address], self.local_socket) sock.close() if len(test_map) > 0: # Some tests have not received any results. Run them locally. print("\nNo results for %d tests, running them locally." % len(test_map)) self._EnqueueLocally(test_map) def _EnqueueLocally(self, test_map): with self.tests_lock: for test in test_map: self.tests.append(test_map[test]) def _AnalyzePeerRuntimes(self): total_runtime = 0.0 total_work = 0.0 for p in self.peers: if p.runtime is None: return total_runtime += p.runtime total_work += p.assigned_work for p in self.peers: p.assigned_work /= total_work p.runtime /= total_runtime perf_correction = p.assigned_work / p.runtime old_perf = p.relative_performance p.relative_performance = (old_perf + perf_correction) / 2.0 compression.Send([constants.UPDATE_PERF, p.address, p.relative_performance], self.local_socket) node-v4.2.6/deps/v8/tools/testrunner/local/__init__.py000644 000766 000024 00000003043 12650222326 023012 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/v8/tools/testrunner/local/commands.py000644 000766 000024 00000010050 12650222326 023050 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import subprocess import sys from threading import Timer from ..local import utils from ..objects import output SEM_INVALID_VALUE = -1 SEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h def Win32SetErrorMode(mode): prev_error_mode = SEM_INVALID_VALUE try: import ctypes prev_error_mode = \ ctypes.windll.kernel32.SetErrorMode(mode) #@UndefinedVariable except ImportError: pass return prev_error_mode def RunProcess(verbose, timeout, args, **rest): if verbose: print "#", " ".join(args) popen_args = args prev_error_mode = SEM_INVALID_VALUE if utils.IsWindows(): popen_args = subprocess.list2cmdline(args) # Try to change the error mode to avoid dialogs on fatal errors. Don't # touch any existing error mode flags by merging the existing error mode. # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. error_mode = SEM_NOGPFAULTERRORBOX prev_error_mode = Win32SetErrorMode(error_mode) Win32SetErrorMode(error_mode | prev_error_mode) process = subprocess.Popen( args=popen_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **rest ) if (utils.IsWindows() and prev_error_mode != SEM_INVALID_VALUE): Win32SetErrorMode(prev_error_mode) def kill_process(process, timeout_result): timeout_result[0] = True try: if utils.IsWindows(): if verbose: print "Attempting to kill process %d" % process.pid sys.stdout.flush() tk = subprocess.Popen( 'taskkill /T /F /PID %d' % process.pid, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout, stderr = tk.communicate() if verbose: print "Taskkill results for %d" % process.pid print stdout print stderr print "Return code: %d" % tk.returncode sys.stdout.flush() else: process.kill() except OSError: sys.stderr.write('Error: Process %s already ended.\n' % process.pid) # Pseudo object to communicate with timer thread. timeout_result = [False] timer = Timer(timeout, kill_process, [process, timeout_result]) timer.start() stdout, stderr = process.communicate() timer.cancel() return process.returncode, timeout_result[0], stdout, stderr def Execute(args, verbose=False, timeout=None): args = [ c for c in args if c != "" ] exit_code, timed_out, stdout, stderr = RunProcess( verbose, timeout, args=args, ) return output.Output(exit_code, timed_out, stdout, stderr) node-v4.2.6/deps/v8/tools/testrunner/local/execution.py000644 000766 000024 00000025122 12650222326 023260 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import shutil import sys import time from pool import Pool from . import commands from . import perfdata from . import statusfile from . import utils class Job(object): def __init__(self, command, dep_command, test_id, timeout, verbose): self.command = command self.dep_command = dep_command self.id = test_id self.timeout = timeout self.verbose = verbose def RunTest(job): start_time = time.time() if job.dep_command is not None: dep_output = commands.Execute(job.dep_command, job.verbose, job.timeout) # TODO(jkummerow): We approximate the test suite specific function # IsFailureOutput() by just checking the exit code here. Currently # only cctests define dependencies, for which this simplification is # correct. if dep_output.exit_code != 0: return (job.id, dep_output, time.time() - start_time) output = commands.Execute(job.command, job.verbose, job.timeout) return (job.id, output, time.time() - start_time) class Runner(object): def __init__(self, suites, progress_indicator, context): self.datapath = os.path.join("out", "testrunner_data") self.perf_data_manager = perfdata.PerfDataManager(self.datapath) self.perfdata = self.perf_data_manager.GetStore(context.arch, context.mode) self.perf_failures = False self.printed_allocations = False self.tests = [ t for s in suites for t in s.tests ] if not context.no_sorting: for t in self.tests: t.duration = self.perfdata.FetchPerfData(t) or 1.0 self.tests.sort(key=lambda t: t.duration, reverse=True) self._CommonInit(suites, progress_indicator, context) def _CommonInit(self, suites, progress_indicator, context): self.total = 0 for s in suites: for t in s.tests: t.id = self.total self.total += 1 self.indicator = progress_indicator progress_indicator.SetRunner(self) self.context = context self.succeeded = 0 self.remaining = self.total self.failed = [] self.crashed = 0 self.reran_tests = 0 def _RunPerfSafe(self, fun): try: fun() except Exception, e: print("PerfData exception: %s" % e) self.perf_failures = True def _GetJob(self, test): command = self.GetCommand(test) timeout = self.context.timeout if ("--stress-opt" in test.flags or "--stress-opt" in self.context.mode_flags or "--stress-opt" in self.context.extra_flags): timeout *= 4 # FIXME(machenbach): Make this more OO. Don't expose default outcomes or # the like. if statusfile.IsSlow(test.outcomes or [statusfile.PASS]): timeout *= 2 if test.dependency is not None: dep_command = [ c.replace(test.path, test.dependency) for c in command ] else: dep_command = None return Job(command, dep_command, test.id, timeout, self.context.verbose) def _MaybeRerun(self, pool, test): if test.run <= self.context.rerun_failures_count: # Possibly rerun this test if its run count is below the maximum per # test. <= as the flag controls reruns not including the first run. if test.run == 1: # Count the overall number of reran tests on the first rerun. if self.reran_tests < self.context.rerun_failures_max: self.reran_tests += 1 else: # Don't rerun this if the overall number of rerun tests has been # reached. return if test.run >= 2 and test.duration > self.context.timeout / 20.0: # Rerun slow tests at most once. return # Rerun this test. test.duration = None test.output = None test.run += 1 pool.add([self._GetJob(test)]) self.remaining += 1 self.total += 1 def _ProcessTestNormal(self, test, result, pool): self.indicator.AboutToRun(test) test.output = result[1] test.duration = result[2] has_unexpected_output = test.suite.HasUnexpectedOutput(test) if has_unexpected_output: self.failed.append(test) if test.output.HasCrashed(): self.crashed += 1 else: self.succeeded += 1 self.remaining -= 1 # For the indicator, everything that happens after the first run is treated # as unexpected even if it flakily passes in order to include it in the # output. self.indicator.HasRun(test, has_unexpected_output or test.run > 1) if has_unexpected_output: # Rerun test failures after the indicator has processed the results. self._VerbosePrint("Attempting to rerun test after failure.") self._MaybeRerun(pool, test) # Update the perf database if the test succeeded. return not has_unexpected_output def _ProcessTestPredictable(self, test, result, pool): def HasDifferentAllocations(output1, output2): def AllocationStr(stdout): for line in reversed((stdout or "").splitlines()): if line.startswith("### Allocations = "): self.printed_allocations = True return line return "" return (AllocationStr(output1.stdout) != AllocationStr(output2.stdout)) # Always pass the test duration for the database update. test.duration = result[2] if test.run == 1 and result[1].HasTimedOut(): # If we get a timeout in the first run, we are already in an # unpredictable state. Just report it as a failure and don't rerun. self.indicator.AboutToRun(test) test.output = result[1] self.remaining -= 1 self.failed.append(test) self.indicator.HasRun(test, True) if test.run > 1 and HasDifferentAllocations(test.output, result[1]): # From the second run on, check for different allocations. If a # difference is found, call the indicator twice to report both tests. # All runs of each test are counted as one for the statistic. self.indicator.AboutToRun(test) self.remaining -= 1 self.failed.append(test) self.indicator.HasRun(test, True) self.indicator.AboutToRun(test) test.output = result[1] self.indicator.HasRun(test, True) elif test.run >= 3: # No difference on the third run -> report a success. self.indicator.AboutToRun(test) self.remaining -= 1 self.succeeded += 1 test.output = result[1] self.indicator.HasRun(test, False) else: # No difference yet and less than three runs -> add another run and # remember the output for comparison. test.run += 1 test.output = result[1] pool.add([self._GetJob(test)]) # Always update the perf database. return True def Run(self, jobs): self.indicator.Starting() self._RunInternal(jobs) self.indicator.Done() if self.failed or self.remaining: return 1 return 0 def _RunInternal(self, jobs): pool = Pool(jobs) test_map = {} queued_exception = [None] def gen_tests(): for test in self.tests: assert test.id >= 0 test_map[test.id] = test try: yield [self._GetJob(test)] except Exception, e: # If this failed, save the exception and re-raise it later (after # all other tests have had a chance to run). queued_exception[0] = e continue try: it = pool.imap_unordered(RunTest, gen_tests()) for result in it: if result.heartbeat: self.indicator.Heartbeat() continue test = test_map[result.value[0]] if self.context.predictable: update_perf = self._ProcessTestPredictable(test, result.value, pool) else: update_perf = self._ProcessTestNormal(test, result.value, pool) if update_perf: self._RunPerfSafe(lambda: self.perfdata.UpdatePerfData(test)) finally: self._VerbosePrint("Closing process pool.") pool.terminate() self._VerbosePrint("Closing database connection.") self._RunPerfSafe(lambda: self.perf_data_manager.close()) if self.perf_failures: # Nuke perf data in case of failures. This might not work on windows as # some files might still be open. print "Deleting perf test data due to db corruption." shutil.rmtree(self.datapath) if queued_exception[0]: raise queued_exception[0] # Make sure that any allocations were printed in predictable mode (if we # ran any tests). assert ( not self.total or not self.context.predictable or self.printed_allocations ) def _VerbosePrint(self, text): if self.context.verbose: print text sys.stdout.flush() def GetCommand(self, test): d8testflag = [] shell = test.suite.shell() if shell == "d8": d8testflag = ["--test"] if utils.IsWindows(): shell += ".exe" if self.context.random_seed: d8testflag += ["--random-seed=%s" % self.context.random_seed] cmd = (self.context.command_prefix + [os.path.abspath(os.path.join(self.context.shell_dir, shell))] + d8testflag + test.suite.GetFlagsForTestCase(test, self.context) + self.context.extra_flags) return cmd class BreakNowException(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) node-v4.2.6/deps/v8/tools/testrunner/local/junit_output.py000644 000766 000024 00000004346 12650222326 024033 0ustar00iojsstaff000000 000000 # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import xml.etree.ElementTree as xml class JUnitTestOutput: def __init__(self, test_suite_name): self.root = xml.Element("testsuite") self.root.attrib["name"] = test_suite_name def HasRunTest(self, test_name, test_duration, test_failure): testCaseElement = xml.Element("testcase") testCaseElement.attrib["name"] = " ".join(test_name) testCaseElement.attrib["time"] = str(round(test_duration, 3)) if len(test_failure): failureElement = xml.Element("failure") failureElement.text = test_failure testCaseElement.append(failureElement) self.root.append(testCaseElement) def FinishAndWrite(self, file): xml.ElementTree(self.root).write(file, "UTF-8") node-v4.2.6/deps/v8/tools/testrunner/local/perfdata.py000644 000766 000024 00000010164 12650222326 023043 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import shelve import threading class PerfDataEntry(object): def __init__(self): self.avg = 0.0 self.count = 0 def AddResult(self, result): kLearnRateLimiter = 99 # Greater value means slower learning. # We use an approximation of the average of the last 100 results here: # The existing average is weighted with kLearnRateLimiter (or less # if there are fewer data points). effective_count = min(self.count, kLearnRateLimiter) self.avg = self.avg * effective_count + result self.count = effective_count + 1 self.avg /= self.count class PerfDataStore(object): def __init__(self, datadir, arch, mode): filename = os.path.join(datadir, "%s.%s.perfdata" % (arch, mode)) self.database = shelve.open(filename, protocol=2) self.closed = False self.lock = threading.Lock() def __del__(self): self.close() def close(self): if self.closed: return self.database.close() self.closed = True def GetKey(self, test): """Computes the key used to access data for the given testcase.""" flags = "".join(test.flags) return str("%s.%s.%s" % (test.suitename(), test.path, flags)) def FetchPerfData(self, test): """Returns the observed duration for |test| as read from the store.""" key = self.GetKey(test) if key in self.database: return self.database[key].avg return None def UpdatePerfData(self, test): """Updates the persisted value in the store with test.duration.""" testkey = self.GetKey(test) self.RawUpdatePerfData(testkey, test.duration) def RawUpdatePerfData(self, testkey, duration): with self.lock: if testkey in self.database: entry = self.database[testkey] else: entry = PerfDataEntry() entry.AddResult(duration) self.database[testkey] = entry class PerfDataManager(object): def __init__(self, datadir): self.datadir = os.path.abspath(datadir) if not os.path.exists(self.datadir): os.makedirs(self.datadir) self.stores = {} # Keyed by arch, then mode. self.closed = False self.lock = threading.Lock() def __del__(self): self.close() def close(self): if self.closed: return for arch in self.stores: modes = self.stores[arch] for mode in modes: store = modes[mode] store.close() self.closed = True def GetStore(self, arch, mode): with self.lock: if not arch in self.stores: self.stores[arch] = {} modes = self.stores[arch] if not mode in modes: modes[mode] = PerfDataStore(self.datadir, arch, mode) return modes[mode] node-v4.2.6/deps/v8/tools/testrunner/local/pool.py000644 000766 000024 00000012355 12650222326 022232 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from Queue import Empty from multiprocessing import Event, Process, Queue class NormalResult(): def __init__(self, result): self.result = result self.exception = False self.break_now = False class ExceptionResult(): def __init__(self): self.exception = True self.break_now = False class BreakResult(): def __init__(self): self.exception = False self.break_now = True class MaybeResult(): def __init__(self, heartbeat, value): self.heartbeat = heartbeat self.value = value @staticmethod def create_heartbeat(): return MaybeResult(True, None) @staticmethod def create_result(value): return MaybeResult(False, value) def Worker(fn, work_queue, done_queue, done): """Worker to be run in a child process. The worker stops on two conditions. 1. When the poison pill "STOP" is reached or 2. when the event "done" is set.""" try: for args in iter(work_queue.get, "STOP"): if done.is_set(): break try: done_queue.put(NormalResult(fn(*args))) except Exception, e: print(">>> EXCEPTION: %s" % e) done_queue.put(ExceptionResult()) except KeyboardInterrupt: done_queue.put(BreakResult()) class Pool(): """Distributes tasks to a number of worker processes. New tasks can be added dynamically even after the workers have been started. Requirement: Tasks can only be added from the parent process, e.g. while consuming the results generator.""" # Factor to calculate the maximum number of items in the work/done queue. # Necessary to not overflow the queue's pipe if a keyboard interrupt happens. BUFFER_FACTOR = 4 def __init__(self, num_workers, heartbeat_timeout=30): self.num_workers = num_workers self.processes = [] self.terminated = False # Invariant: count >= #work_queue + #done_queue. It is greater when a # worker takes an item from the work_queue and before the result is # submitted to the done_queue. It is equal when no worker is working, # e.g. when all workers have finished, and when no results are processed. # Count is only accessed by the parent process. Only the parent process is # allowed to remove items from the done_queue and to add items to the # work_queue. self.count = 0 self.work_queue = Queue() self.done_queue = Queue() self.done = Event() self.heartbeat_timeout = heartbeat_timeout def imap_unordered(self, fn, gen): """Maps function "fn" to items in generator "gen" on the worker processes in an arbitrary order. The items are expected to be lists of arguments to the function. Returns a results iterator. A result value of type MaybeResult either indicates a heartbeat of the runner, i.e. indicating that the runner is still waiting for the result to be computed, or it wraps the real result.""" try: gen = iter(gen) self.advance = self._advance_more for w in xrange(self.num_workers): p = Process(target=Worker, args=(fn, self.work_queue, self.done_queue, self.done)) self.processes.append(p) p.start() self.advance(gen) while self.count > 0: while True: try: result = self.done_queue.get(timeout=self.heartbeat_timeout) break except Empty: # Indicate a heartbeat. The iterator will continue fetching the # next result. yield MaybeResult.create_heartbeat() self.count -= 1 if result.exception: # Ignore items with unexpected exceptions. continue elif result.break_now: # A keyboard interrupt happened in one of the worker processes. raise KeyboardInterrupt else: yield MaybeResult.create_result(result.result) self.advance(gen) finally: self.terminate() def _advance_more(self, gen): while self.count < self.num_workers * self.BUFFER_FACTOR: try: self.work_queue.put(gen.next()) self.count += 1 except StopIteration: self.advance = self._advance_empty break def _advance_empty(self, gen): pass def add(self, args): """Adds an item to the work queue. Can be called dynamically while processing the results from imap_unordered.""" self.work_queue.put(args) self.count += 1 def terminate(self): if self.terminated: return self.terminated = True # For exceptional tear down set the "done" event to stop the workers before # they empty the queue buffer. self.done.set() for p in self.processes: # During normal tear down the workers block on get(). Feed a poison pill # per worker to make them stop. self.work_queue.put("STOP") for p in self.processes: p.join() # Drain the queues to prevent failures when queues are garbage collected. try: while True: self.work_queue.get(False) except: pass try: while True: self.done_queue.get(False) except: pass node-v4.2.6/deps/v8/tools/testrunner/local/pool_unittest.py000644 000766 000024 00000002344 12650222326 024166 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import unittest from pool import Pool def Run(x): if x == 10: raise Exception("Expected exception triggered by test.") return x class PoolTest(unittest.TestCase): def testNormal(self): results = set() pool = Pool(3) for result in pool.imap_unordered(Run, [[x] for x in range(0, 10)]): results.add(result.value) self.assertEquals(set(range(0, 10)), results) def testException(self): results = set() pool = Pool(3) for result in pool.imap_unordered(Run, [[x] for x in range(0, 12)]): # Item 10 will not appear in results due to an internal exception. results.add(result.value) expect = set(range(0, 12)) expect.remove(10) self.assertEquals(expect, results) def testAdd(self): results = set() pool = Pool(3) for result in pool.imap_unordered(Run, [[x] for x in range(0, 10)]): results.add(result.value) if result.value < 30: pool.add([result.value + 20]) self.assertEquals(set(range(0, 10) + range(20, 30) + range(40, 50)), results) node-v4.2.6/deps/v8/tools/testrunner/local/progress.py000644 000766 000024 00000026753 12650222326 023134 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from functools import wraps import json import os import sys import time from . import junit_output ABS_PATH_PREFIX = os.getcwd() + os.sep def EscapeCommand(command): parts = [] for part in command: if ' ' in part: # Escape spaces. We may need to escape more characters for this # to work properly. parts.append('"%s"' % part) else: parts.append(part) return " ".join(parts) class ProgressIndicator(object): def __init__(self): self.runner = None def SetRunner(self, runner): self.runner = runner def Starting(self): pass def Done(self): pass def AboutToRun(self, test): pass def HasRun(self, test, has_unexpected_output): pass def Heartbeat(self): pass def PrintFailureHeader(self, test): if test.suite.IsNegativeTest(test): negative_marker = '[negative] ' else: negative_marker = '' print "=== %(label)s %(negative)s===" % { 'label': test.GetLabel(), 'negative': negative_marker } class IndicatorNotifier(object): """Holds a list of progress indicators and notifies them all on events.""" def __init__(self): self.indicators = [] def Register(self, indicator): self.indicators.append(indicator) # Forge all generic event-dispatching methods in IndicatorNotifier, which are # part of the ProgressIndicator interface. for func_name in ProgressIndicator.__dict__: func = getattr(ProgressIndicator, func_name) if callable(func) and not func.__name__.startswith('_'): def wrap_functor(f): @wraps(f) def functor(self, *args, **kwargs): """Generic event dispatcher.""" for indicator in self.indicators: getattr(indicator, f.__name__)(*args, **kwargs) return functor setattr(IndicatorNotifier, func_name, wrap_functor(func)) class SimpleProgressIndicator(ProgressIndicator): """Abstract base class for {Verbose,Dots}ProgressIndicator""" def Starting(self): print 'Running %i tests' % self.runner.total def Done(self): print for failed in self.runner.failed: self.PrintFailureHeader(failed) if failed.output.stderr: print "--- stderr ---" print failed.output.stderr.strip() if failed.output.stdout: print "--- stdout ---" print failed.output.stdout.strip() print "Command: %s" % EscapeCommand(self.runner.GetCommand(failed)) if failed.output.HasCrashed(): print "exit code: %d" % failed.output.exit_code print "--- CRASHED ---" if failed.output.HasTimedOut(): print "--- TIMEOUT ---" if len(self.runner.failed) == 0: print "===" print "=== All tests succeeded" print "===" else: print print "===" print "=== %i tests failed" % len(self.runner.failed) if self.runner.crashed > 0: print "=== %i tests CRASHED" % self.runner.crashed print "===" class VerboseProgressIndicator(SimpleProgressIndicator): def AboutToRun(self, test): print 'Starting %s...' % test.GetLabel() sys.stdout.flush() def HasRun(self, test, has_unexpected_output): if has_unexpected_output: if test.output.HasCrashed(): outcome = 'CRASH' else: outcome = 'FAIL' else: outcome = 'pass' print 'Done running %s: %s' % (test.GetLabel(), outcome) sys.stdout.flush() def Heartbeat(self): print 'Still working...' sys.stdout.flush() class DotsProgressIndicator(SimpleProgressIndicator): def HasRun(self, test, has_unexpected_output): total = self.runner.succeeded + len(self.runner.failed) if (total > 1) and (total % 50 == 1): sys.stdout.write('\n') if has_unexpected_output: if test.output.HasCrashed(): sys.stdout.write('C') sys.stdout.flush() elif test.output.HasTimedOut(): sys.stdout.write('T') sys.stdout.flush() else: sys.stdout.write('F') sys.stdout.flush() else: sys.stdout.write('.') sys.stdout.flush() class CompactProgressIndicator(ProgressIndicator): """Abstract base class for {Color,Monochrome}ProgressIndicator""" def __init__(self, templates): super(CompactProgressIndicator, self).__init__() self.templates = templates self.last_status_length = 0 self.start_time = time.time() def Done(self): self.PrintProgress('Done') print "" # Line break. def AboutToRun(self, test): self.PrintProgress(test.GetLabel()) def HasRun(self, test, has_unexpected_output): if has_unexpected_output: self.ClearLine(self.last_status_length) self.PrintFailureHeader(test) stdout = test.output.stdout.strip() if len(stdout): print self.templates['stdout'] % stdout stderr = test.output.stderr.strip() if len(stderr): print self.templates['stderr'] % stderr print "Command: %s" % EscapeCommand(self.runner.GetCommand(test)) if test.output.HasCrashed(): print "exit code: %d" % test.output.exit_code print "--- CRASHED ---" if test.output.HasTimedOut(): print "--- TIMEOUT ---" def Truncate(self, string, length): if length and (len(string) > (length - 3)): return string[:(length - 3)] + "..." else: return string def PrintProgress(self, name): self.ClearLine(self.last_status_length) elapsed = time.time() - self.start_time progress = 0 if not self.runner.total else ( ((self.runner.total - self.runner.remaining) * 100) // self.runner.total) status = self.templates['status_line'] % { 'passed': self.runner.succeeded, 'progress': progress, 'failed': len(self.runner.failed), 'test': name, 'mins': int(elapsed) / 60, 'secs': int(elapsed) % 60 } status = self.Truncate(status, 78) self.last_status_length = len(status) print status, sys.stdout.flush() class ColorProgressIndicator(CompactProgressIndicator): def __init__(self): templates = { 'status_line': ("[%(mins)02i:%(secs)02i|" "\033[34m%%%(progress) 4d\033[0m|" "\033[32m+%(passed) 4d\033[0m|" "\033[31m-%(failed) 4d\033[0m]: %(test)s"), 'stdout': "\033[1m%s\033[0m", 'stderr': "\033[31m%s\033[0m", } super(ColorProgressIndicator, self).__init__(templates) def ClearLine(self, last_line_length): print "\033[1K\r", class MonochromeProgressIndicator(CompactProgressIndicator): def __init__(self): templates = { 'status_line': ("[%(mins)02i:%(secs)02i|%%%(progress) 4d|" "+%(passed) 4d|-%(failed) 4d]: %(test)s"), 'stdout': '%s', 'stderr': '%s', } super(MonochromeProgressIndicator, self).__init__(templates) def ClearLine(self, last_line_length): print ("\r" + (" " * last_line_length) + "\r"), class JUnitTestProgressIndicator(ProgressIndicator): def __init__(self, junitout, junittestsuite): self.outputter = junit_output.JUnitTestOutput(junittestsuite) if junitout: self.outfile = open(junitout, "w") else: self.outfile = sys.stdout def Done(self): self.outputter.FinishAndWrite(self.outfile) if self.outfile != sys.stdout: self.outfile.close() def HasRun(self, test, has_unexpected_output): fail_text = "" if has_unexpected_output: stdout = test.output.stdout.strip() if len(stdout): fail_text += "stdout:\n%s\n" % stdout stderr = test.output.stderr.strip() if len(stderr): fail_text += "stderr:\n%s\n" % stderr fail_text += "Command: %s" % EscapeCommand(self.runner.GetCommand(test)) if test.output.HasCrashed(): fail_text += "exit code: %d\n--- CRASHED ---" % test.output.exit_code if test.output.HasTimedOut(): fail_text += "--- TIMEOUT ---" self.outputter.HasRunTest( [test.GetLabel()] + self.runner.context.mode_flags + test.flags, test.duration, fail_text) class JsonTestProgressIndicator(ProgressIndicator): def __init__(self, json_test_results, arch, mode): self.json_test_results = json_test_results self.arch = arch self.mode = mode self.results = [] self.tests = [] def Done(self): complete_results = [] if os.path.exists(self.json_test_results): with open(self.json_test_results, "r") as f: # Buildbot might start out with an empty file. complete_results = json.loads(f.read() or "[]") # Sort tests by duration. timed_tests = [t for t in self.tests if t.duration is not None] timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) slowest_tests = [ { "name": test.GetLabel(), "flags": test.flags, "command": EscapeCommand(self.runner.GetCommand(test)).replace( ABS_PATH_PREFIX, ""), "duration": test.duration, } for test in timed_tests[:20] ] complete_results.append({ "arch": self.arch, "mode": self.mode, "results": self.results, "slowest_tests": slowest_tests, }) with open(self.json_test_results, "w") as f: f.write(json.dumps(complete_results)) def HasRun(self, test, has_unexpected_output): # Buffer all tests for sorting the durations in the end. self.tests.append(test) if not has_unexpected_output: # Omit tests that run as expected. Passing tests of reruns after failures # will have unexpected_output to be reported here has well. return self.results.append({ "name": test.GetLabel(), "flags": test.flags, "command": EscapeCommand(self.runner.GetCommand(test)).replace( ABS_PATH_PREFIX, ""), "run": test.run, "stdout": test.output.stdout, "stderr": test.output.stderr, "exit_code": test.output.exit_code, "result": test.suite.GetOutcome(test), "expected": list(test.outcomes or ["PASS"]), "duration": test.duration, }) PROGRESS_INDICATORS = { 'verbose': VerboseProgressIndicator, 'dots': DotsProgressIndicator, 'color': ColorProgressIndicator, 'mono': MonochromeProgressIndicator } node-v4.2.6/deps/v8/tools/testrunner/local/statusfile.py000644 000766 000024 00000011046 12650222326 023440 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # These outcomes can occur in a TestCase's outcomes list: SKIP = "SKIP" FAIL = "FAIL" PASS = "PASS" OKAY = "OKAY" TIMEOUT = "TIMEOUT" CRASH = "CRASH" SLOW = "SLOW" FLAKY = "FLAKY" FAST_VARIANTS = "FAST_VARIANTS" NO_VARIANTS = "NO_VARIANTS" # These are just for the status files and are mapped below in DEFS: FAIL_OK = "FAIL_OK" PASS_OR_FAIL = "PASS_OR_FAIL" FAIL_SLOPPY = "FAIL_SLOPPY" ALWAYS = "ALWAYS" KEYWORDS = {} for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FLAKY, FAIL_OK, FAST_VARIANTS, NO_VARIANTS, PASS_OR_FAIL, FAIL_SLOPPY, ALWAYS]: KEYWORDS[key] = key DEFS = {FAIL_OK: [FAIL, OKAY], PASS_OR_FAIL: [PASS, FAIL]} # Support arches, modes to be written as keywords instead of strings. VARIABLES = {ALWAYS: True} for var in ["debug", "release", "big", "little", "android_arm", "android_arm64", "android_ia32", "android_x87", "android_x64", "arm", "arm64", "ia32", "mips", "mipsel", "mips64el", "x64", "x87", "nacl_ia32", "nacl_x64", "ppc", "ppc64", "macos", "windows", "linux", "aix"]: VARIABLES[var] = var def DoSkip(outcomes): return SKIP in outcomes def IsSlow(outcomes): return SLOW in outcomes def OnlyStandardVariant(outcomes): return NO_VARIANTS in outcomes def OnlyFastVariants(outcomes): return FAST_VARIANTS in outcomes def IsFlaky(outcomes): return FLAKY in outcomes def IsPassOrFail(outcomes): return ((PASS in outcomes) and (FAIL in outcomes) and (not CRASH in outcomes) and (not OKAY in outcomes)) def IsFailOk(outcomes): return (FAIL in outcomes) and (OKAY in outcomes) def _AddOutcome(result, new): global DEFS if new in DEFS: mapped = DEFS[new] if type(mapped) == list: for m in mapped: _AddOutcome(result, m) elif type(mapped) == str: _AddOutcome(result, mapped) else: result.add(new) def _ParseOutcomeList(rule, outcomes, target_dict, variables): result = set([]) if type(outcomes) == str: outcomes = [outcomes] for item in outcomes: if type(item) == str: _AddOutcome(result, item) elif type(item) == list: if not eval(item[0], variables): continue for outcome in item[1:]: assert type(outcome) == str _AddOutcome(result, outcome) else: assert False if len(result) == 0: return if rule in target_dict: target_dict[rule] |= result else: target_dict[rule] = result def ReadStatusFile(path, variables): with open(path) as f: global KEYWORDS contents = eval(f.read(), KEYWORDS) rules = {} wildcards = {} variables.update(VARIABLES) for section in contents: assert type(section) == list assert len(section) == 2 if not eval(section[0], variables): continue section = section[1] assert type(section) == dict for rule in section: assert type(rule) == str if rule[-1] == '*': _ParseOutcomeList(rule, section[rule], wildcards, variables) else: _ParseOutcomeList(rule, section[rule], rules, variables) return rules, wildcards node-v4.2.6/deps/v8/tools/testrunner/local/testsuite.py000644 000766 000024 00000022631 12650222326 023310 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import imp import os from . import commands from . import statusfile from . import utils from ..objects import testcase # Use this to run several variants of the tests. VARIANT_FLAGS = { "default": [], "stress": ["--stress-opt", "--always-opt"], "turbofan": ["--turbo", "--always-opt"], "nocrankshaft": ["--nocrankshaft"]} FAST_VARIANT_FLAGS = [ f for v, f in VARIANT_FLAGS.iteritems() if v in ["default", "turbofan"] ] class TestSuite(object): @staticmethod def LoadTestSuite(root): name = root.split(os.path.sep)[-1] f = None try: (f, pathname, description) = imp.find_module("testcfg", [root]) module = imp.load_module("testcfg", f, pathname, description) return module.GetSuite(name, root) except: # Use default if no testcfg is present. return GoogleTestSuite(name, root) finally: if f: f.close() def __init__(self, name, root): self.name = name # string self.root = root # string containing path self.tests = None # list of TestCase objects self.rules = None # dictionary mapping test path to list of outcomes self.wildcards = None # dictionary mapping test paths to list of outcomes self.total_duration = None # float, assigned on demand def shell(self): return "d8" def suffix(self): return ".js" def status_file(self): return "%s/%s.status" % (self.root, self.name) # Used in the status file and for stdout printing. def CommonTestName(self, testcase): if utils.IsWindows(): return testcase.path.replace("\\", "/") else: return testcase.path def ListTests(self, context): raise NotImplementedError def VariantFlags(self, testcase, default_flags): if testcase.outcomes and statusfile.OnlyStandardVariant(testcase.outcomes): return [[]] if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes): # FAST_VARIANTS implies no --always-opt. return [ filter(lambda flag: flag != "--always-opt", f) for f in filter(lambda flags: flags in FAST_VARIANT_FLAGS, default_flags) ] return default_flags def DownloadData(self): pass def ReadStatusFile(self, variables): (self.rules, self.wildcards) = \ statusfile.ReadStatusFile(self.status_file(), variables) def ReadTestCases(self, context): self.tests = self.ListTests(context) @staticmethod def _FilterFlaky(flaky, mode): return (mode == "run" and not flaky) or (mode == "skip" and flaky) @staticmethod def _FilterSlow(slow, mode): return (mode == "run" and not slow) or (mode == "skip" and slow) @staticmethod def _FilterPassFail(pass_fail, mode): return (mode == "run" and not pass_fail) or (mode == "skip" and pass_fail) def FilterTestCasesByStatus(self, warn_unused_rules, flaky_tests="dontcare", slow_tests="dontcare", pass_fail_tests="dontcare"): filtered = [] used_rules = set() for t in self.tests: flaky = False slow = False pass_fail = False testname = self.CommonTestName(t) if testname in self.rules: used_rules.add(testname) # Even for skipped tests, as the TestCase object stays around and # PrintReport() uses it. t.outcomes = self.rules[testname] if statusfile.DoSkip(t.outcomes): continue # Don't add skipped tests to |filtered|. for outcome in t.outcomes: if outcome.startswith('Flags: '): t.flags += outcome[7:].split() flaky = statusfile.IsFlaky(t.outcomes) slow = statusfile.IsSlow(t.outcomes) pass_fail = statusfile.IsPassOrFail(t.outcomes) skip = False for rule in self.wildcards: assert rule[-1] == '*' if testname.startswith(rule[:-1]): used_rules.add(rule) t.outcomes |= self.wildcards[rule] if statusfile.DoSkip(t.outcomes): skip = True break # "for rule in self.wildcards" flaky = flaky or statusfile.IsFlaky(t.outcomes) slow = slow or statusfile.IsSlow(t.outcomes) pass_fail = pass_fail or statusfile.IsPassOrFail(t.outcomes) if (skip or self._FilterFlaky(flaky, flaky_tests) or self._FilterSlow(slow, slow_tests) or self._FilterPassFail(pass_fail, pass_fail_tests)): continue # "for t in self.tests" filtered.append(t) self.tests = filtered if not warn_unused_rules: return for rule in self.rules: if rule not in used_rules: print("Unused rule: %s -> %s" % (rule, self.rules[rule])) for rule in self.wildcards: if rule not in used_rules: print("Unused rule: %s -> %s" % (rule, self.wildcards[rule])) def FilterTestCasesByArgs(self, args): filtered = [] filtered_args = [] for a in args: argpath = a.split(os.path.sep) if argpath[0] != self.name: continue if len(argpath) == 1 or (len(argpath) == 2 and argpath[1] == '*'): return # Don't filter, run all tests in this suite. path = os.path.sep.join(argpath[1:]) if path[-1] == '*': path = path[:-1] filtered_args.append(path) for t in self.tests: for a in filtered_args: if t.path.startswith(a): filtered.append(t) break self.tests = filtered def GetFlagsForTestCase(self, testcase, context): raise NotImplementedError def GetSourceForTest(self, testcase): return "(no source available)" def IsFailureOutput(self, output, testpath): return output.exit_code != 0 def IsNegativeTest(self, testcase): return False def HasFailed(self, testcase): execution_failed = self.IsFailureOutput(testcase.output, testcase.path) if self.IsNegativeTest(testcase): return not execution_failed else: return execution_failed def GetOutcome(self, testcase): if testcase.output.HasCrashed(): return statusfile.CRASH elif testcase.output.HasTimedOut(): return statusfile.TIMEOUT elif self.HasFailed(testcase): return statusfile.FAIL else: return statusfile.PASS def HasUnexpectedOutput(self, testcase): outcome = self.GetOutcome(testcase) return not outcome in (testcase.outcomes or [statusfile.PASS]) def StripOutputForTransmit(self, testcase): if not self.HasUnexpectedOutput(testcase): testcase.output.stdout = "" testcase.output.stderr = "" def CalculateTotalDuration(self): self.total_duration = 0.0 for t in self.tests: self.total_duration += t.duration return self.total_duration class GoogleTestSuite(TestSuite): def __init__(self, name, root): super(GoogleTestSuite, self).__init__(name, root) def ListTests(self, context): shell = os.path.abspath(os.path.join(context.shell_dir, self.shell())) if utils.IsWindows(): shell += ".exe" output = commands.Execute(context.command_prefix + [shell, "--gtest_list_tests"] + context.extra_flags) if output.exit_code != 0: print output.stdout print output.stderr raise Exception("Test executable failed to list the tests.") tests = [] test_case = '' for line in output.stdout.splitlines(): test_desc = line.strip().split()[0] if test_desc.endswith('.'): test_case = test_desc elif test_case and test_desc: test = testcase.TestCase(self, test_case + test_desc, dependency=None) tests.append(test) tests.sort() return tests def GetFlagsForTestCase(self, testcase, context): return (testcase.flags + ["--gtest_filter=" + testcase.path] + ["--gtest_random_seed=%s" % context.random_seed] + ["--gtest_print_time=0"] + context.mode_flags) def VariantFlags(self, testcase, default_flags): return [[]] def shell(self): return self.name node-v4.2.6/deps/v8/tools/testrunner/local/utils.py000644 000766 000024 00000010334 12650222326 022414 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os from os.path import exists from os.path import isdir from os.path import join import platform import re import subprocess import urllib2 def GetSuitePaths(test_root): return [ f for f in os.listdir(test_root) if isdir(join(test_root, f)) ] # Reads a file into an array of strings def ReadLinesFrom(name): lines = [] with open(name) as f: for line in f: if line.startswith('#'): continue if '#' in line: line = line[:line.find('#')] line = line.strip() if not line: continue lines.append(line) return lines def GuessOS(): system = platform.system() if system == 'Linux': return 'linux' elif system == 'Darwin': return 'macos' elif system.find('CYGWIN') >= 0: return 'cygwin' elif system == 'Windows' or system == 'Microsoft': # On Windows Vista platform.system() can return 'Microsoft' with some # versions of Python, see http://bugs.python.org/issue1082 return 'windows' elif system == 'FreeBSD': return 'freebsd' elif system == 'OpenBSD': return 'openbsd' elif system == 'SunOS': return 'solaris' elif system == 'NetBSD': return 'netbsd' elif system == 'AIX': return 'aix' else: return None def UseSimulator(arch): machine = platform.machine() return (machine and (arch == "mipsel" or arch == "arm" or arch == "arm64") and not arch.startswith(machine)) # This will default to building the 32 bit VM even on machines that are # capable of running the 64 bit VM. def DefaultArch(): machine = platform.machine() machine = machine.lower() # Windows 7 capitalizes 'AMD64'. if machine.startswith('arm'): return 'arm' elif (not machine) or (not re.match('(x|i[3-6])86$', machine) is None): return 'ia32' elif machine == 'i86pc': return 'ia32' elif machine == 'x86_64': return 'ia32' elif machine == 'amd64': return 'ia32' elif machine == 'ppc64': return 'ppc' else: return None def GuessWordsize(): if '64' in platform.machine(): return '64' else: return '32' def IsWindows(): return GuessOS() == 'windows' def URLRetrieve(source, destination): """urllib is broken for SSL connections via a proxy therefore we can't use urllib.urlretrieve().""" if IsWindows(): try: # In python 2.7.6 on windows, urlopen has a problem with redirects. # Try using curl instead. Note, this is fixed in 2.7.8. subprocess.check_call(["curl", source, '-k', '-L', '-o', destination]) return except: # If there's no curl, fall back to urlopen. print "Curl is currently not installed. Falling back to python." pass with open(destination, 'w') as f: f.write(urllib2.urlopen(source).read()) node-v4.2.6/deps/v8/tools/testrunner/local/verbose.py000644 000766 000024 00000007145 12650222326 022727 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys import time from . import statusfile REPORT_TEMPLATE = ( """Total: %(total)i tests * %(skipped)4d tests will be skipped * %(timeout)4d tests are expected to timeout sometimes * %(nocrash)4d tests are expected to be flaky but not crash * %(pass)4d tests are expected to pass * %(fail_ok)4d tests are expected to fail that we won't fix * %(fail)4d tests are expected to fail that we should fix""") def PrintReport(tests): total = len(tests) skipped = timeout = nocrash = passes = fail_ok = fail = 0 for t in tests: if "outcomes" not in dir(t) or not t.outcomes: passes += 1 continue o = t.outcomes if statusfile.DoSkip(o): skipped += 1 continue if statusfile.TIMEOUT in o: timeout += 1 if statusfile.IsPassOrFail(o): nocrash += 1 if list(o) == [statusfile.PASS]: passes += 1 if statusfile.IsFailOk(o): fail_ok += 1 if list(o) == [statusfile.FAIL]: fail += 1 print REPORT_TEMPLATE % { "total": total, "skipped": skipped, "timeout": timeout, "nocrash": nocrash, "pass": passes, "fail_ok": fail_ok, "fail": fail } def PrintTestSource(tests): for test in tests: suite = test.suite source = suite.GetSourceForTest(test).strip() if len(source) > 0: print "--- begin source: %s/%s ---" % (suite.name, test.path) print source print "--- end source: %s/%s ---" % (suite.name, test.path) def FormatTime(d): millis = round(d * 1000) % 1000 return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) def PrintTestDurations(suites, overall_time): # Write the times to stderr to make it easy to separate from the # test output. print sys.stderr.write("--- Total time: %s ---\n" % FormatTime(overall_time)) timed_tests = [ t for s in suites for t in s.tests if t.duration is not None ] timed_tests.sort(lambda a, b: cmp(b.duration, a.duration)) index = 1 for entry in timed_tests[:20]: t = FormatTime(entry.duration) sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel())) index += 1 node-v4.2.6/deps/v8/tools/sodium/index.html000644 000766 000024 00000002273 12650222326 020677 0ustar00iojsstaff000000 000000 Sodium

node-v4.2.6/deps/v8/tools/sodium/sodium.js000644 000766 000024 00000033510 12650222326 020536 0ustar00iojsstaff000000 000000 // Copyright 2013 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. var Sodium = (function() { "use strict"; var kinds = ["FUNCTION", "OPTIMIZED_FUNCTION", "STUB", "BUILTIN", "LOAD_IC", "KEYED_LOAD_IC", "CALL_IC", "KEYED_CALL_IC", "STORE_IC", "KEYED_STORE_IC", "BINARY_OP_IC", "COMPARE_IC", "COMPARE_NIL_IC", "TO_BOOLEAN_IC"]; var kindsWithSource = { 'FUNCTION': true, 'OPTIMIZED_FUNCTION': true }; var addressRegEx = "0x[0-9a-f]{8,16}"; var nameFinder = new RegExp("^name = (.+)$"); var kindFinder = new RegExp("^kind = (.+)$"); var firstPositionFinder = new RegExp("^source_position = (\\d+)$"); var separatorFilter = new RegExp("^--- (.)+ ---$"); var rawSourceFilter = new RegExp("^--- Raw source ---$"); var codeEndFinder = new RegExp("^--- End code ---$"); var whiteSpaceLineFinder = new RegExp("^\\W*$"); var instructionBeginFinder = new RegExp("^Instructions\\W+\\(size = \\d+\\)"); var instructionFinder = new RegExp("^\(" + addressRegEx + "\)\(\\W+\\d+\\W+.+\)"); var positionFinder = new RegExp("^(" + addressRegEx + ")\\W+position\\W+\\((\\d+)\\)"); var addressFinder = new RegExp("\(" + addressRegEx + "\)"); var addressReplacer = new RegExp("\(" + addressRegEx + "\)", "gi"); var fileContent = ""; var selectedFunctionKind = ""; var currentFunctionKind = ""; var currentFunctionName = ""; var firstSourcePosition = 0; var startAddress = ""; var readingSource = false; var readingAsm = false; var sourceBegin = -1; var sourceEnd = -1; var asmBegin = -1; var asmEnd = -1; var codeObjects = []; var selectedAsm = null; var selectedSource = null; var selectedSourceClass = ""; function Code(name, kind, sourceBegin, sourceEnd, asmBegin, asmEnd, firstSourcePosition, startAddress) { this.name = name; this.kind = kind; this.sourceBegin = sourceBegin; this.sourceEnd = sourceEnd; this.asmBegin = asmBegin; this.asmEnd = asmEnd; this.firstSourcePosition = firstSourcePosition; this.startAddress = startAddress; } function getCurrentCodeObject() { var functionSelect = document.getElementById('function-selector-id'); return functionSelect.options[functionSelect.selectedIndex].codeObject; } function getCurrentSourceText() { var code = getCurrentCodeObject(); if (code.sourceBegin == -1 || code.sourceEnd == -1) return ""; return fileContent.substring(code.sourceBegin, code.sourceEnd); } function getCurrentAsmText() { var code = getCurrentCodeObject(); if (code.asmBegin == -1 || code.asmEnd == -1) return ""; return fileContent.substring(code.asmBegin, code.asmEnd); } function setKindByIndex(index) { selectedFunctionKind = kinds[index]; } function processLine(text, begin, end) { var line = text.substring(begin, end); if (readingSource) { if (separatorFilter.exec(line) != null) { readingSource = false; } else { if (sourceBegin == -1) { sourceBegin = begin; } sourceEnd = end; } } else { if (readingAsm) { if (codeEndFinder.exec(line) != null) { readingAsm = false; asmEnd = begin; var newCode = new Code(currentFunctionName, currentFunctionKind, sourceBegin, sourceEnd, asmBegin, asmEnd, firstSourcePosition, startAddress); codeObjects.push(newCode); currentFunctionKind = null; } else { if (asmBegin == -1) { matches = instructionBeginFinder.exec(line); if (matches != null) { asmBegin = begin; } } if (startAddress == "") { matches = instructionFinder.exec(line); if (matches != null) { startAddress = matches[1]; } } } } else { var matches = kindFinder.exec(line); if (matches != null) { currentFunctionKind = matches[1]; if (!kindsWithSource[currentFunctionKind]) { sourceBegin = -1; sourceEnd = -1; } } else if (currentFunctionKind != null) { matches = nameFinder.exec(line); if (matches != null) { readingAsm = true; asmBegin = -1; currentFunctionName = matches[1]; } } else if (rawSourceFilter.exec(line) != null) { readingSource = true; sourceBegin = -1; } else { var matches = firstPositionFinder.exec(line); if (matches != null) { firstSourcePosition = parseInt(matches[1]); } } } } } function processLines(source, size, processLine) { var firstChar = 0; for (var x = 0; x < size; x++) { var curChar = source[x]; if (curChar == '\n' || curChar == '\r') { processLine(source, firstChar, x); firstChar = x + 1; } } if (firstChar != size - 1) { processLine(source, firstChar, size - 1); } } function processFileContent() { document.getElementById('source-text-pre').innerHTML = ''; sourceBegin = -1; codeObjects = []; processLines(fileContent, fileContent.length, processLine); var functionSelectElement = document.getElementById('function-selector-id'); functionSelectElement.innerHTML = ''; var length = codeObjects.length; for (var i = 0; i < codeObjects.length; ++i) { var code = codeObjects[i]; if (code.kind == selectedFunctionKind) { var optionElement = document.createElement("option"); optionElement.codeObject = code; optionElement.text = code.name; functionSelectElement.add(optionElement, null); } } } function asmClick(element) { if (element == selectedAsm) return; if (selectedAsm != null) { selectedAsm.classList.remove('highlight-yellow'); } selectedAsm = element; selectedAsm.classList.add('highlight-yellow'); var pc = element.firstChild.innerText; var sourceLine = null; if (addressFinder.exec(pc) != null) { var position = findSourcePosition(pc); var line = findSourceLine(position); sourceLine = document.getElementById('source-line-' + line); var sourceLineTop = sourceLine.offsetTop; makeSourcePosVisible(sourceLineTop); } if (selectedSource == sourceLine) return; if (selectedSource != null) { selectedSource.classList.remove('highlight-yellow'); selectedSource.classList.add(selectedSourceClass); } if (sourceLine != null) { selectedSourceClass = sourceLine.classList[0]; sourceLine.classList.remove(selectedSourceClass); sourceLine.classList.add('highlight-yellow'); } selectedSource = sourceLine; } function makeContainerPosVisible(container, newTop) { var height = container.offsetHeight; var margin = Math.floor(height / 4); if (newTop < container.scrollTop + margin) { newTop -= margin; if (newTop < 0) newTop = 0; container.scrollTop = newTop; return; } if (newTop > (container.scrollTop + 3 * margin)) { newTop = newTop - 3 * margin; container.scrollTop = newTop; } } function makeAsmPosVisible(newTop) { var asmContainer = document.getElementById('asm-container'); makeContainerPosVisible(asmContainer, newTop); } function makeSourcePosVisible(newTop) { var sourceContainer = document.getElementById('source-container'); makeContainerPosVisible(sourceContainer, newTop); } function addressClick(element, event) { event.stopPropagation(); var asmLineId = 'address-' + element.innerText; var asmLineElement = document.getElementById(asmLineId); if (asmLineElement != null) { var asmLineTop = asmLineElement.parentNode.offsetTop; makeAsmPosVisible(asmLineTop); asmLineElement.classList.add('highlight-flash-blue'); window.setTimeout(function() { asmLineElement.classList.remove('highlight-flash-blue'); }, 1500); } } function prepareAsm(originalSource) { var newSource = ""; var lineNumber = 1; var functionProcessLine = function(text, begin, end) { var currentLine = text.substring(begin, end); var matches = instructionFinder.exec(currentLine); var clickHandler = ""; if (matches != null) { var restOfLine = matches[2]; restOfLine = restOfLine.replace( addressReplacer, '\$1'); currentLine = '' + matches[1] + '' + restOfLine; clickHandler = 'onclick=\'Sodium.asmClick(this)\' '; } else if (whiteSpaceLineFinder.exec(currentLine)) { currentLine = "
"; } newSource += '
' +
        currentLine + '
'; lineNumber++; } processLines(originalSource, originalSource.length, functionProcessLine); return newSource; } function findSourcePosition(pcToSearch) { var position = 0; var distance = 0x7FFFFFFF; var pcToSearchOffset = parseInt(pcToSearch); var processOneLine = function(text, begin, end) { var currentLine = text.substring(begin, end); var matches = positionFinder.exec(currentLine); if (matches != null) { var pcOffset = parseInt(matches[1]); if (pcOffset <= pcToSearchOffset) { var dist = pcToSearchOffset - pcOffset; var pos = parseInt(matches[2]); if ((dist < distance) || (dist == distance && pos > position)) { position = pos; distance = dist; } } } } var asmText = getCurrentAsmText(); processLines(asmText, asmText.length, processOneLine); var code = getCurrentCodeObject(); if (position == 0) return 0; return position - code.firstSourcePosition; } function findSourceLine(position) { if (position == 0) return 1; var line = 0; var processOneLine = function(text, begin, end) { if (begin < position) { line++; } } var sourceText = getCurrentSourceText(); processLines(sourceText, sourceText.length, processOneLine); return line; } function functionChangedHandler() { var functionSelect = document.getElementById('function-selector-id'); var source = getCurrentSourceText(); var sourceDivElement = document.getElementById('source-text'); var code = getCurrentCodeObject(); var newHtml = "
"
      + 'function ' + code.name + source + "
"; sourceDivElement.innerHTML = newHtml; try { // Wrap in try to work when offline. PR.prettyPrint(); } catch (e) { } var sourceLineContainer = sourceDivElement.firstChild.firstChild; var lineCount = sourceLineContainer.childElementCount; var current = sourceLineContainer.firstChild; for (var i = 1; i < lineCount; ++i) { current.id = "source-line-" + i; current = current.nextElementSibling; } var asm = getCurrentAsmText(); document.getElementById('asm-text').innerHTML = prepareAsm(asm); } function kindChangedHandler(element) { setKindByIndex(element.selectedIndex); processFileContent(); functionChangedHandler(); } function readLog(evt) { //Retrieve the first (and only!) File from the FileList object var f = evt.target.files[0]; if (f) { var r = new FileReader(); r.onload = function(e) { var file = evt.target.files[0]; currentFunctionKind = ""; fileContent = e.target.result; processFileContent(); functionChangedHandler(); } r.readAsText(f); } else { alert("Failed to load file"); } } function buildFunctionKindSelector(kindSelectElement) { for (var x = 0; x < kinds.length; ++x) { var optionElement = document.createElement("option"); optionElement.value = x; optionElement.text = kinds[x]; kindSelectElement.add(optionElement, null); } kindSelectElement.selectedIndex = 1; setKindByIndex(1); } return { buildFunctionKindSelector: buildFunctionKindSelector, kindChangedHandler: kindChangedHandler, functionChangedHandler: functionChangedHandler, asmClick: asmClick, addressClick: addressClick, readLog: readLog }; })(); node-v4.2.6/deps/v8/tools/sodium/styles.css000755 000766 000024 00000002560 12650222326 020741 0ustar00iojsstaff000000 000000 #table-header { background-color: rgba(150, 150, 255, 0.4); } #asm-container { background-color: rgba(200, 200, 255, 0.4); position:absolute; overflow:auto; cursor:default; width:50%; height:92%; } #source-container { position:absolute; overflow:auto; width:48%; left:51%; height:92%; } table { border-collapse: collapse; } .hover-underline:hover { text-decoration: underline; } .highlight-flash-blue { -webkit-transition: all 1s ease; background-color: rgba(50, 50, 245, 0.4); border-radius: 10px; -o-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } .highlight-green { background-color: rgba(0, 255, 0, 0.4); border-radius: 10px; -o-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } .highlight-yellow { background-color: rgba(255, 255, 0, 0.4); border-radius: 10px; -o-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } .highlight-gray { background-color: rgba(128, 128, 128, 0.4); border-radius: 10px; -o-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } .highlight-red { background-color: rgba(255, 0, 0, 0.4); border-radius: 10px; -o-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } node-v4.2.6/deps/v8/tools/sanitizers/tsan_suppressions.txt000644 000766 000024 00000000402 12650222326 024130 0ustar00iojsstaff000000 000000 # Suppressions for TSan v2 # https://code.google.com/p/thread-sanitizer/wiki/Suppressions # Incorrectly detected lock cycles in test-lockers # https://code.google.com/p/thread-sanitizer/issues/detail?id=81 deadlock:LockAndUnlockDifferentIsolatesThread::Run node-v4.2.6/deps/v8/tools/release/auto_push.py000755 000766 000024 00000007320 12650222326 021404 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import json import os import re import sys import urllib from common_includes import * import create_release class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): # Fetch unfetched revisions. self.vc.Fetch() class FetchCandidate(Step): MESSAGE = "Fetching V8 roll ref." def RunStep(self): # The roll ref points to the candidate to be rolled. self.Git("fetch origin +refs/heads/roll:refs/heads/roll") self["candidate"] = self.Git("show-ref -s refs/heads/roll").strip() class LastReleaseBailout(Step): MESSAGE = "Checking last V8 release base." def RunStep(self): last_release = self.GetLatestReleaseBase() commits = self.GitLog( format="%H", git_hash="%s..%s" % (last_release, self["candidate"])) if not commits: print "Already pushed current candidate %s" % self["candidate"] return True class CreateRelease(Step): MESSAGE = "Creating release if specified." def RunStep(self): print "Creating release for %s." % self["candidate"] args = [ "--author", self._options.author, "--reviewer", self._options.reviewer, "--revision", self["candidate"], "--force", ] if self._options.work_dir: args.extend(["--work-dir", self._options.work_dir]) if self._options.push: self._side_effect_handler.Call( create_release.CreateRelease().Run, args) class AutoPush(ScriptsBase): def _PrepareOptions(self, parser): parser.add_argument("-p", "--push", help="Create release. Dry run if unspecified.", default=False, action="store_true") def _ProcessOptions(self, options): if not options.author or not options.reviewer: # pragma: no cover print "You need to specify author and reviewer." return False options.requires_editor = False return True def _Config(self): return { "PERSISTFILE_BASENAME": "/tmp/v8-auto-push-tempfile", } def _Steps(self): return [ Preparation, FetchCandidate, LastReleaseBailout, CreateRelease, ] if __name__ == "__main__": # pragma: no cover sys.exit(AutoPush().Run()) node-v4.2.6/deps/v8/tools/release/auto_roll.py000755 000766 000024 00000010272 12650222326 021375 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import json import os import sys import urllib from common_includes import * import chromium_roll class CheckActiveRoll(Step): MESSAGE = "Check active roll." @staticmethod def ContainsChromiumRoll(changes): for change in changes: if change["subject"].startswith("Update V8 to"): return True return False def RunStep(self): params = { "closed": 3, "owner": self._options.author, "limit": 30, "format": "json", } params = urllib.urlencode(params) search_url = "https://codereview.chromium.org/search" result = self.ReadURL(search_url, params, wait_plan=[5, 20]) if self.ContainsChromiumRoll(json.loads(result)["results"]): print "Stop due to existing Chromium roll." return True class DetectLastRoll(Step): MESSAGE = "Detect commit ID of the last Chromium roll." def RunStep(self): # The revision that should be rolled. Check for the latest of the most # recent releases based on commit timestamp. revisions = self.GetRecentReleases( max_age=self._options.max_age * DAY_IN_SECONDS) assert revisions, "Didn't find any recent release." # Interpret the DEPS file to retrieve the v8 revision. # TODO(machenbach): This should be part or the roll-deps api of # depot_tools. Var = lambda var: '%s' exec(FileToText(os.path.join(self._options.chromium, "DEPS"))) # The revision rolled last. self["last_roll"] = vars['v8_revision'] last_version = self.GetVersionTag(self["last_roll"]) assert last_version, "The last rolled v8 revision is not tagged." # There must be some progress between the last roll and the new candidate # revision (i.e. we don't go backwards). The revisions are ordered newest # to oldest. It is possible that the newest timestamp has no progress # compared to the last roll, i.e. if the newest release is a cherry-pick # on a release branch. Then we look further. for revision in revisions: version = self.GetVersionTag(revision) assert version, "Internal error. All recent releases should have a tag" if SortingKey(last_version) < SortingKey(version): self["roll"] = revision break else: print("There is no newer v8 revision than the one in Chromium (%s)." % self["last_roll"]) return True class RollChromium(Step): MESSAGE = "Roll V8 into Chromium." def RunStep(self): if self._options.roll: args = [ "--author", self._options.author, "--reviewer", self._options.reviewer, "--chromium", self._options.chromium, "--last-roll", self["last_roll"], "--use-commit-queue", self["roll"], ] if self._options.sheriff: args.append("--sheriff") if self._options.dry_run: args.append("--dry-run") if self._options.work_dir: args.extend(["--work-dir", self._options.work_dir]) self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args) class AutoRoll(ScriptsBase): def _PrepareOptions(self, parser): parser.add_argument("-c", "--chromium", required=True, help=("The path to your Chromium src/ " "directory to automate the V8 roll.")) parser.add_argument("--max-age", default=3, type=int, help="Maximum age in days of the latest release.") parser.add_argument("--roll", help="Call Chromium roll script.", default=False, action="store_true") def _ProcessOptions(self, options): # pragma: no cover if not options.reviewer: print "A reviewer (-r) is required." return False if not options.author: print "An author (-a) is required." return False return True def _Config(self): return { "PERSISTFILE_BASENAME": "/tmp/v8-auto-roll-tempfile", } def _Steps(self): return [ CheckActiveRoll, DetectLastRoll, RollChromium, ] if __name__ == "__main__": # pragma: no cover sys.exit(AutoRoll().Run()) node-v4.2.6/deps/v8/tools/release/auto_tag.py000755 000766 000024 00000013347 12650222326 021206 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import sys from common_includes import * class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): # TODO(machenbach): Remove after the git switch. if self.Config("PERSISTFILE_BASENAME") == "/tmp/v8-auto-tag-tempfile": print "This script is disabled until after the v8 git migration." return True self.CommonPrepare() self.PrepareBranch() self.GitCheckout("master") self.vc.Pull() class GetTags(Step): MESSAGE = "Get all V8 tags." def RunStep(self): self.GitCreateBranch(self._config["BRANCHNAME"]) self["tags"] = self.vc.GetTags() class GetOldestUntaggedVersion(Step): MESSAGE = "Check if there's a version on bleeding edge without a tag." def RunStep(self): tags = set(self["tags"]) self["candidate"] = None self["candidate_version"] = None self["next"] = None self["next_version"] = None # Iterate backwards through all automatic version updates. for git_hash in self.GitLog( format="%H", grep="\\[Auto\\-roll\\] Bump up version to").splitlines(): # Get the version. if not self.GitCheckoutFileSafe(VERSION_FILE, git_hash): continue self.ReadAndPersistVersion() version = self.ArrayToVersion("") # Strip off trailing patch level (tags don't include tag level 0). if version.endswith(".0"): version = version[:-2] # Clean up checked-out version file. self.GitCheckoutFileSafe(VERSION_FILE, "HEAD") if version in tags: if self["candidate"]: # Revision "git_hash" is tagged already and "candidate" was the next # newer revision without a tag. break else: print("Stop as %s is the latest version and it has been tagged." % version) self.CommonCleanup() return True else: # This is the second oldest version without a tag. self["next"] = self["candidate"] self["next_version"] = self["candidate_version"] # This is the oldest version without a tag. self["candidate"] = git_hash self["candidate_version"] = version if not self["candidate"] or not self["candidate_version"]: print "Nothing found to tag." self.CommonCleanup() return True print("Candidate for tagging is %s with version %s" % (self["candidate"], self["candidate_version"])) class GetLKGRs(Step): MESSAGE = "Get the last lkgrs." def RunStep(self): revision_url = "https://v8-status.appspot.com/revisions?format=json" status_json = self.ReadURL(revision_url, wait_plan=[5, 20]) self["lkgrs"] = [entry["revision"] for entry in json.loads(status_json) if entry["status"]] class CalculateTagRevision(Step): MESSAGE = "Calculate the revision to tag." def LastLKGR(self, min_rev, max_rev): """Finds the newest lkgr between min_rev (inclusive) and max_rev (exclusive). """ for lkgr in self["lkgrs"]: # LKGRs are reverse sorted. if int(min_rev) <= int(lkgr) and int(lkgr) < int(max_rev): return lkgr return None def RunStep(self): # Get the lkgr after the tag candidate and before the next tag candidate. candidate_svn = self.vc.GitSvn(self["candidate"]) if self["next"]: next_svn = self.vc.GitSvn(self["next"]) else: # Don't include the version change commit itself if there is no upper # limit yet. candidate_svn = str(int(candidate_svn) + 1) next_svn = sys.maxint lkgr_svn = self.LastLKGR(candidate_svn, next_svn) if not lkgr_svn: print "There is no lkgr since the candidate version yet." self.CommonCleanup() return True # Let's check if the lkgr is at least three hours old. self["lkgr"] = self.vc.SvnGit(lkgr_svn) if not self["lkgr"]: print "Couldn't find git hash for lkgr %s" % lkgr_svn self.CommonCleanup() return True lkgr_utc_time = int(self.GitLog(n=1, format="%at", git_hash=self["lkgr"])) current_utc_time = self._side_effect_handler.GetUTCStamp() if current_utc_time < lkgr_utc_time + 10800: print "Candidate lkgr %s is too recent for tagging." % lkgr_svn self.CommonCleanup() return True print "Tagging revision %s with %s" % (lkgr_svn, self["candidate_version"]) class MakeTag(Step): MESSAGE = "Tag the version." def RunStep(self): if not self._options.dry_run: self.GitReset(self["lkgr"]) # FIXME(machenbach): Make this work with the git repo. self.vc.Tag(self["candidate_version"], "svn/bleeding_edge", "This won't work!") class CleanUp(Step): MESSAGE = "Clean up." def RunStep(self): self.CommonCleanup() class AutoTag(ScriptsBase): def _PrepareOptions(self, parser): parser.add_argument("--dry_run", help="Don't tag the new version.", default=False, action="store_true") def _ProcessOptions(self, options): # pragma: no cover if not options.dry_run and not options.author: print "Specify your chromium.org email with -a" return False options.wait_for_lgtm = False options.force_readline_defaults = True options.force_upload = True return True def _Config(self): return { "BRANCHNAME": "auto-tag-v8", "PERSISTFILE_BASENAME": "/tmp/v8-auto-tag-tempfile", } def _Steps(self): return [ Preparation, GetTags, GetOldestUntaggedVersion, GetLKGRs, CalculateTagRevision, MakeTag, CleanUp, ] if __name__ == "__main__": # pragma: no cover sys.exit(AutoTag().Run()) node-v4.2.6/deps/v8/tools/release/check_clusterfuzz.py000755 000766 000024 00000012002 12650222326 023123 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ Script to check for new clusterfuzz issues since the last rolled v8 revision. Returns a json list with test case IDs if any. Security considerations: The security key and request data must never be written to public logs. Public automated callers of this script should suppress stdout and stderr and only process contents of the results_file. """ import argparse import httplib import json import os import re import sys import urllib import urllib2 # Constants to git repos. BASE_URL = "https://chromium.googlesource.com" DEPS_LOG = BASE_URL + "/chromium/src/+log/master/DEPS?format=JSON" # Constants for retrieving v8 rolls. CRREV = "https://cr-rev.appspot.com/_ah/api/crrev/v1/commit/%s" V8_COMMIT_RE = re.compile( r"^Update V8 to version \d+\.\d+\.\d+ \(based on ([a-fA-F0-9]+)\)\..*") # Constants for the clusterfuzz backend. HOSTNAME = "backend-dot-cluster-fuzz.appspot.com" # Crash patterns. V8_INTERNAL_RE = re.compile(r"^v8::internal.*") ANY_RE = re.compile(r".*") # List of all api requests. BUG_SPECS = [ { "args": { "job_type": "linux_asan_chrome_v8", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": V8_INTERNAL_RE, }, { "args": { "job_type": "linux_asan_d8", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": ANY_RE, }, { "args": { "job_type": "linux_asan_d8_dbg", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": ANY_RE, }, { "args": { "job_type": "linux_asan_d8_v8_arm_dbg", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": ANY_RE, }, { "args": { "job_type": "linux_asan_d8_v8_arm64_dbg", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": ANY_RE, }, { "args": { "job_type": "linux_asan_d8_v8_mipsel_dbg", "reproducible": "True", "open": "True", "bug_information": "", }, "crash_state": ANY_RE, }, ] def GetRequest(url): url_fh = urllib2.urlopen(url, None, 60) try: return url_fh.read() finally: url_fh.close() def GetLatestV8InChromium(): """Returns the commit position number of the latest v8 roll in chromium.""" # Check currently rolled v8 revision. result = GetRequest(DEPS_LOG) if not result: return None # Strip security header and load json. commits = json.loads(result[5:]) git_revision = None for commit in commits["log"]: # Get latest commit that matches the v8 roll pattern. Ignore cherry-picks. match = re.match(V8_COMMIT_RE, commit["message"]) if match: git_revision = match.group(1) break else: return None # Get commit position number for v8 revision. result = GetRequest(CRREV % git_revision) if not result: return None commit = json.loads(result) assert commit["repo"] == "v8/v8" return commit["number"] def APIRequest(key, **params): """Send a request to the clusterfuzz api. Returns a json dict of the response. """ params["api_key"] = key params = urllib.urlencode(params) headers = {"Content-type": "application/x-www-form-urlencoded"} try: conn = httplib.HTTPSConnection(HOSTNAME) conn.request("POST", "/_api/", params, headers) response = conn.getresponse() # Never leak "data" into public logs. data = response.read() except: raise Exception("ERROR: Connection problem.") try: return json.loads(data) except: raise Exception("ERROR: Could not read response. Is your key valid?") return None def Main(): parser = argparse.ArgumentParser() parser.add_argument("-k", "--key-file", required=True, help="A file with the clusterfuzz api key.") parser.add_argument("-r", "--results-file", help="A file to write the results to.") options = parser.parse_args() # Get api key. The key's content must never be logged. assert options.key_file with open(options.key_file) as f: key = f.read().strip() assert key revision_number = GetLatestV8InChromium() results = [] for spec in BUG_SPECS: args = dict(spec["args"]) # Use incremented revision as we're interested in all revision greater than # what's currently rolled into chromium. if revision_number: args["revision_greater_or_equal"] = str(int(revision_number) + 1) # Never print issue details in public logs. issues = APIRequest(key, **args) assert issues is not None for issue in issues: if re.match(spec["crash_state"], issue["crash_state"]): results.append(issue["id"]) if options.results_file: with open(options.results_file, "w") as f: f.write(json.dumps(results)) else: print results if __name__ == "__main__": sys.exit(Main()) node-v4.2.6/deps/v8/tools/release/chromium_roll.py000755 000766 000024 00000011462 12650222326 022252 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import os import sys from common_includes import * ROLL_SUMMARY = ("Summary of changes available at:\n" "https://chromium.googlesource.com/v8/v8/+log/%s..%s") ISSUE_MSG = ( """Please follow these instructions for assigning/CC'ing issues: https://code.google.com/p/v8-wiki/wiki/TriagingIssues Please close rolling in case of a roll revert: https://v8-roll.appspot.com/""") class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): # Update v8 remote tracking branches. self.GitFetchOrigin() self.Git("fetch origin +refs/tags/*:refs/tags/*") class PrepareRollCandidate(Step): MESSAGE = "Robustness checks of the roll candidate." def RunStep(self): self["roll_title"] = self.GitLog(n=1, format="%s", git_hash=self._options.roll) # Make sure the last roll and the roll candidate are releases. version = self.GetVersionTag(self._options.roll) assert version, "The revision to roll is not tagged." version = self.GetVersionTag(self._options.last_roll) assert version, "The revision used as last roll is not tagged." class SwitchChromium(Step): MESSAGE = "Switch to Chromium checkout." def RunStep(self): cwd = self._options.chromium self.InitialEnvironmentChecks(cwd) # Check for a clean workdir. if not self.GitIsWorkdirClean(cwd=cwd): # pragma: no cover self.Die("Workspace is not clean. Please commit or undo your changes.") # Assert that the DEPS file is there. if not os.path.exists(os.path.join(cwd, "DEPS")): # pragma: no cover self.Die("DEPS file not present.") class UpdateChromiumCheckout(Step): MESSAGE = "Update the checkout and create a new branch." def RunStep(self): cwd = self._options.chromium self.GitCheckout("master", cwd=cwd) self.DeleteBranch("work-branch", cwd=cwd) self.Command("gclient", "sync --nohooks", cwd=cwd) self.GitPull(cwd=cwd) # Update v8 remotes. self.GitFetchOrigin() self.GitCreateBranch("work-branch", cwd=cwd) class UploadCL(Step): MESSAGE = "Create and upload CL." def RunStep(self): cwd = self._options.chromium # Patch DEPS file. if self.Command("roll-dep-svn", "v8 %s" % self._options.roll, cwd=cwd) is None: self.Die("Failed to create deps for %s" % self._options.roll) message = [] message.append("Update V8 to %s." % self["roll_title"].lower()) message.append( ROLL_SUMMARY % (self._options.last_roll[:8], self._options.roll[:8])) message.append(ISSUE_MSG) message.append("TBR=%s" % self._options.reviewer) self.GitCommit("\n\n".join(message), author=self._options.author, cwd=cwd) if not self._options.dry_run: self.GitUpload(author=self._options.author, force=True, cq=self._options.use_commit_queue, cwd=cwd) print "CL uploaded." else: print "Dry run - don't upload." self.GitCheckout("master", cwd=cwd) self.GitDeleteBranch("work-branch", cwd=cwd) class CleanUp(Step): MESSAGE = "Done!" def RunStep(self): print("Congratulations, you have successfully rolled %s into " "Chromium." % self._options.roll) # Clean up all temporary files. Command("rm", "-f %s*" % self._config["PERSISTFILE_BASENAME"]) class ChromiumRoll(ScriptsBase): def _PrepareOptions(self, parser): parser.add_argument("-c", "--chromium", required=True, help=("The path to your Chromium src/ " "directory to automate the V8 roll.")) parser.add_argument("--last-roll", required=True, help="The git commit ID of the last rolled version.") parser.add_argument("roll", nargs=1, help="Revision to roll."), parser.add_argument("--use-commit-queue", help="Check the CQ bit on upload.", default=False, action="store_true") def _ProcessOptions(self, options): # pragma: no cover if not options.author or not options.reviewer: print "A reviewer (-r) and an author (-a) are required." return False options.requires_editor = False options.force = True options.manual = False options.roll = options.roll[0] return True def _Config(self): return { "PERSISTFILE_BASENAME": "/tmp/v8-chromium-roll-tempfile", } def _Steps(self): return [ Preparation, PrepareRollCandidate, DetermineV8Sheriff, SwitchChromium, UpdateChromiumCheckout, UploadCL, CleanUp, ] if __name__ == "__main__": # pragma: no cover sys.exit(ChromiumRoll().Run()) node-v4.2.6/deps/v8/tools/release/common_includes.py000644 000766 000024 00000071056 12650222326 022557 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import datetime import httplib import glob import imp import json import os import re import shutil import subprocess import sys import textwrap import time import urllib import urllib2 from git_recipes import GitRecipesMixin from git_recipes import GitFailedException CHANGELOG_FILE = "ChangeLog" DAY_IN_SECONDS = 24 * 60 * 60 PUSH_MSG_GIT_RE = re.compile(r".* \(based on (?P[a-fA-F0-9]+)\)$") PUSH_MSG_NEW_RE = re.compile(r"^Version \d+\.\d+\.\d+$") VERSION_FILE = os.path.join("include", "v8-version.h") VERSION_RE = re.compile(r"^\d+\.\d+\.\d+(?:\.\d+)?$") # V8 base directory. V8_BASE = os.path.dirname( os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def TextToFile(text, file_name): with open(file_name, "w") as f: f.write(text) def AppendToFile(text, file_name): with open(file_name, "a") as f: f.write(text) def LinesInFile(file_name): with open(file_name) as f: for line in f: yield line def FileToText(file_name): with open(file_name) as f: return f.read() def MSub(rexp, replacement, text): return re.sub(rexp, replacement, text, flags=re.MULTILINE) def Fill80(line): # Replace tabs and remove surrounding space. line = re.sub(r"\t", r" ", line.strip()) # Format with 8 characters indentation and line width 80. return textwrap.fill(line, width=80, initial_indent=" ", subsequent_indent=" ") def MakeComment(text): return MSub(r"^( ?)", "#", text) def StripComments(text): # Use split not splitlines to keep terminal newlines. return "\n".join(filter(lambda x: not x.startswith("#"), text.split("\n"))) def MakeChangeLogBody(commit_messages, auto_format=False): result = "" added_titles = set() for (title, body, author) in commit_messages: # TODO(machenbach): Better check for reverts. A revert should remove the # original CL from the actual log entry. title = title.strip() if auto_format: # Only add commits that set the LOG flag correctly. log_exp = r"^[ \t]*LOG[ \t]*=[ \t]*(?:(?:Y(?:ES)?)|TRUE)" if not re.search(log_exp, body, flags=re.I | re.M): continue # Never include reverts. if title.startswith("Revert "): continue # Don't include duplicates. if title in added_titles: continue # Add and format the commit's title and bug reference. Move dot to the end. added_titles.add(title) raw_title = re.sub(r"(\.|\?|!)$", "", title) bug_reference = MakeChangeLogBugReference(body) space = " " if bug_reference else "" result += "%s\n" % Fill80("%s%s%s." % (raw_title, space, bug_reference)) # Append the commit's author for reference if not in auto-format mode. if not auto_format: result += "%s\n" % Fill80("(%s)" % author.strip()) result += "\n" return result def MakeChangeLogBugReference(body): """Grep for "BUG=xxxx" lines in the commit message and convert them to "(issue xxxx)". """ crbugs = [] v8bugs = [] def AddIssues(text): ref = re.match(r"^BUG[ \t]*=[ \t]*(.+)$", text.strip()) if not ref: return for bug in ref.group(1).split(","): bug = bug.strip() match = re.match(r"^v8:(\d+)$", bug) if match: v8bugs.append(int(match.group(1))) else: match = re.match(r"^(?:chromium:)?(\d+)$", bug) if match: crbugs.append(int(match.group(1))) # Add issues to crbugs and v8bugs. map(AddIssues, body.splitlines()) # Filter duplicates, sort, stringify. crbugs = map(str, sorted(set(crbugs))) v8bugs = map(str, sorted(set(v8bugs))) bug_groups = [] def FormatIssues(prefix, bugs): if len(bugs) > 0: plural = "s" if len(bugs) > 1 else "" bug_groups.append("%sissue%s %s" % (prefix, plural, ", ".join(bugs))) FormatIssues("", v8bugs) FormatIssues("Chromium ", crbugs) if len(bug_groups) > 0: return "(%s)" % ", ".join(bug_groups) else: return "" def SortingKey(version): """Key for sorting version number strings: '3.11' > '3.2.1.1'""" version_keys = map(int, version.split(".")) # Fill up to full version numbers to normalize comparison. while len(version_keys) < 4: # pragma: no cover version_keys.append(0) # Fill digits. return ".".join(map("{0:04d}".format, version_keys)) # Some commands don't like the pipe, e.g. calling vi from within the script or # from subscripts like git cl upload. def Command(cmd, args="", prefix="", pipe=True, cwd=None): cwd = cwd or os.getcwd() # TODO(machenbach): Use timeout. cmd_line = "%s %s %s" % (prefix, cmd, args) print "Command: %s" % cmd_line print "in %s" % cwd sys.stdout.flush() try: if pipe: return subprocess.check_output(cmd_line, shell=True, cwd=cwd) else: return subprocess.check_call(cmd_line, shell=True, cwd=cwd) except subprocess.CalledProcessError: return None finally: sys.stdout.flush() sys.stderr.flush() # Wrapper for side effects. class SideEffectHandler(object): # pragma: no cover def Call(self, fun, *args, **kwargs): return fun(*args, **kwargs) def Command(self, cmd, args="", prefix="", pipe=True, cwd=None): return Command(cmd, args, prefix, pipe, cwd=cwd) def ReadLine(self): return sys.stdin.readline().strip() def ReadURL(self, url, params=None): # pylint: disable=E1121 url_fh = urllib2.urlopen(url, params, 60) try: return url_fh.read() finally: url_fh.close() def ReadClusterFuzzAPI(self, api_key, **params): params["api_key"] = api_key.strip() params = urllib.urlencode(params) headers = {"Content-type": "application/x-www-form-urlencoded"} conn = httplib.HTTPSConnection("backend-dot-cluster-fuzz.appspot.com") conn.request("POST", "/_api/", params, headers) response = conn.getresponse() data = response.read() try: return json.loads(data) except: print data print "ERROR: Could not read response. Is your key valid?" raise def Sleep(self, seconds): time.sleep(seconds) def GetDate(self): return datetime.date.today().strftime("%Y-%m-%d") def GetUTCStamp(self): return time.mktime(datetime.datetime.utcnow().timetuple()) DEFAULT_SIDE_EFFECT_HANDLER = SideEffectHandler() class NoRetryException(Exception): pass class VCInterface(object): def InjectStep(self, step): self.step=step def Pull(self): raise NotImplementedError() def Fetch(self): raise NotImplementedError() def GetTags(self): raise NotImplementedError() def GetBranches(self): raise NotImplementedError() def MasterBranch(self): raise NotImplementedError() def CandidateBranch(self): raise NotImplementedError() def RemoteMasterBranch(self): raise NotImplementedError() def RemoteCandidateBranch(self): raise NotImplementedError() def RemoteBranch(self, name): raise NotImplementedError() def CLLand(self): raise NotImplementedError() def Tag(self, tag, remote, message): """Sets a tag for the current commit. Assumptions: The commit already landed and the commit message is unique. """ raise NotImplementedError() class GitInterface(VCInterface): def Pull(self): self.step.GitPull() def Fetch(self): self.step.Git("fetch") def GetTags(self): return self.step.Git("tag").strip().splitlines() def GetBranches(self): # Get relevant remote branches, e.g. "branch-heads/3.25". branches = filter( lambda s: re.match(r"^branch\-heads/\d+\.\d+$", s), self.step.GitRemotes()) # Remove 'branch-heads/' prefix. return map(lambda s: s[13:], branches) def MasterBranch(self): return "master" def CandidateBranch(self): return "candidates" def RemoteMasterBranch(self): return "origin/master" def RemoteCandidateBranch(self): return "origin/candidates" def RemoteBranch(self, name): # Assume that if someone "fully qualified" the ref, they know what they # want. if name.startswith('refs/'): return name if name in ["candidates", "master"]: return "refs/remotes/origin/%s" % name try: # Check if branch is in heads. if self.step.Git("show-ref refs/remotes/origin/%s" % name).strip(): return "refs/remotes/origin/%s" % name except GitFailedException: pass try: # Check if branch is in branch-heads. if self.step.Git("show-ref refs/remotes/branch-heads/%s" % name).strip(): return "refs/remotes/branch-heads/%s" % name except GitFailedException: pass self.Die("Can't find remote of %s" % name) def Tag(self, tag, remote, message): # Wait for the commit to appear. Assumes unique commit message titles (this # is the case for all automated merge and push commits - also no title is # the prefix of another title). commit = None for wait_interval in [3, 7, 15, 35, 45, 60]: self.step.Git("fetch") commit = self.step.GitLog(n=1, format="%H", grep=message, branch=remote) if commit: break print("The commit has not replicated to git. Waiting for %s seconds." % wait_interval) self.step._side_effect_handler.Sleep(wait_interval) else: self.step.Die("Couldn't determine commit for setting the tag. Maybe the " "git updater is lagging behind?") self.step.Git("tag %s %s" % (tag, commit)) self.step.Git("push origin %s" % tag) def CLLand(self): self.step.GitCLLand() class Step(GitRecipesMixin): def __init__(self, text, number, config, state, options, handler): self._text = text self._number = number self._config = config self._state = state self._options = options self._side_effect_handler = handler self.vc = GitInterface() self.vc.InjectStep(self) # The testing configuration might set a different default cwd. self.default_cwd = (self._config.get("DEFAULT_CWD") or os.path.join(self._options.work_dir, "v8")) assert self._number >= 0 assert self._config is not None assert self._state is not None assert self._side_effect_handler is not None def __getitem__(self, key): # Convenience method to allow direct [] access on step classes for # manipulating the backed state dict. return self._state.get(key) def __setitem__(self, key, value): # Convenience method to allow direct [] access on step classes for # manipulating the backed state dict. self._state[key] = value def Config(self, key): return self._config[key] def Run(self): # Restore state. state_file = "%s-state.json" % self._config["PERSISTFILE_BASENAME"] if not self._state and os.path.exists(state_file): self._state.update(json.loads(FileToText(state_file))) print ">>> Step %d: %s" % (self._number, self._text) try: return self.RunStep() finally: # Persist state. TextToFile(json.dumps(self._state), state_file) def RunStep(self): # pragma: no cover raise NotImplementedError def Retry(self, cb, retry_on=None, wait_plan=None): """ Retry a function. Params: cb: The function to retry. retry_on: A callback that takes the result of the function and returns True if the function should be retried. A function throwing an exception is always retried. wait_plan: A list of waiting delays between retries in seconds. The maximum number of retries is len(wait_plan). """ retry_on = retry_on or (lambda x: False) wait_plan = list(wait_plan or []) wait_plan.reverse() while True: got_exception = False try: result = cb() except NoRetryException as e: raise e except Exception as e: got_exception = e if got_exception or retry_on(result): if not wait_plan: # pragma: no cover raise Exception("Retried too often. Giving up. Reason: %s" % str(got_exception)) wait_time = wait_plan.pop() print "Waiting for %f seconds." % wait_time self._side_effect_handler.Sleep(wait_time) print "Retrying..." else: return result def ReadLine(self, default=None): # Don't prompt in forced mode. if self._options.force_readline_defaults and default is not None: print "%s (forced)" % default return default else: return self._side_effect_handler.ReadLine() def Command(self, name, args, cwd=None): cmd = lambda: self._side_effect_handler.Command( name, args, "", True, cwd=cwd or self.default_cwd) return self.Retry(cmd, None, [5]) def Git(self, args="", prefix="", pipe=True, retry_on=None, cwd=None): cmd = lambda: self._side_effect_handler.Command( "git", args, prefix, pipe, cwd=cwd or self.default_cwd) result = self.Retry(cmd, retry_on, [5, 30]) if result is None: raise GitFailedException("'git %s' failed." % args) return result def Editor(self, args): if self._options.requires_editor: return self._side_effect_handler.Command( os.environ["EDITOR"], args, pipe=False, cwd=self.default_cwd) def ReadURL(self, url, params=None, retry_on=None, wait_plan=None): wait_plan = wait_plan or [3, 60, 600] cmd = lambda: self._side_effect_handler.ReadURL(url, params) return self.Retry(cmd, retry_on, wait_plan) def GetDate(self): return self._side_effect_handler.GetDate() def Die(self, msg=""): if msg != "": print "Error: %s" % msg print "Exiting" raise Exception(msg) def DieNoManualMode(self, msg=""): if not self._options.manual: # pragma: no cover msg = msg or "Only available in manual mode." self.Die(msg) def Confirm(self, msg): print "%s [Y/n] " % msg, answer = self.ReadLine(default="Y") return answer == "" or answer == "Y" or answer == "y" def DeleteBranch(self, name, cwd=None): for line in self.GitBranch(cwd=cwd).splitlines(): if re.match(r"\*?\s*%s$" % re.escape(name), line): msg = "Branch %s exists, do you want to delete it?" % name if self.Confirm(msg): self.GitDeleteBranch(name, cwd=cwd) print "Branch %s deleted." % name else: msg = "Can't continue. Please delete branch %s and try again." % name self.Die(msg) def InitialEnvironmentChecks(self, cwd): # Cancel if this is not a git checkout. if not os.path.exists(os.path.join(cwd, ".git")): # pragma: no cover self.Die("This is not a git checkout, this script won't work for you.") # Cancel if EDITOR is unset or not executable. if (self._options.requires_editor and (not os.environ.get("EDITOR") or self.Command( "which", os.environ["EDITOR"]) is None)): # pragma: no cover self.Die("Please set your EDITOR environment variable, you'll need it.") def CommonPrepare(self): # Check for a clean workdir. if not self.GitIsWorkdirClean(): # pragma: no cover self.Die("Workspace is not clean. Please commit or undo your changes.") # Checkout master in case the script was left on a work branch. self.GitCheckout('origin/master') # Fetch unfetched revisions. self.vc.Fetch() def PrepareBranch(self): # Delete the branch that will be created later if it exists already. self.DeleteBranch(self._config["BRANCHNAME"]) def CommonCleanup(self): self.GitCheckout('origin/master') self.GitDeleteBranch(self._config["BRANCHNAME"]) # Clean up all temporary files. for f in glob.iglob("%s*" % self._config["PERSISTFILE_BASENAME"]): if os.path.isfile(f): os.remove(f) if os.path.isdir(f): shutil.rmtree(f) def ReadAndPersistVersion(self, prefix=""): def ReadAndPersist(var_name, def_name): match = re.match(r"^#define %s\s+(\d*)" % def_name, line) if match: value = match.group(1) self["%s%s" % (prefix, var_name)] = value for line in LinesInFile(os.path.join(self.default_cwd, VERSION_FILE)): for (var_name, def_name) in [("major", "V8_MAJOR_VERSION"), ("minor", "V8_MINOR_VERSION"), ("build", "V8_BUILD_NUMBER"), ("patch", "V8_PATCH_LEVEL")]: ReadAndPersist(var_name, def_name) def WaitForLGTM(self): print ("Please wait for an LGTM, then type \"LGTM\" to commit " "your change. (If you need to iterate on the patch or double check " "that it's sane, do so in another shell, but remember to not " "change the headline of the uploaded CL.") answer = "" while answer != "LGTM": print "> ", answer = self.ReadLine(None if self._options.wait_for_lgtm else "LGTM") if answer != "LGTM": print "That was not 'LGTM'." def WaitForResolvingConflicts(self, patch_file): print("Applying the patch \"%s\" failed. Either type \"ABORT\", " "or resolve the conflicts, stage *all* touched files with " "'git add', and type \"RESOLVED\"") self.DieNoManualMode() answer = "" while answer != "RESOLVED": if answer == "ABORT": self.Die("Applying the patch failed.") if answer != "": print "That was not 'RESOLVED' or 'ABORT'." print "> ", answer = self.ReadLine() # Takes a file containing the patch to apply as first argument. def ApplyPatch(self, patch_file, revert=False): try: self.GitApplyPatch(patch_file, revert) except GitFailedException: self.WaitForResolvingConflicts(patch_file) def GetVersionTag(self, revision): tag = self.Git("describe --tags %s" % revision).strip() if VERSION_RE.match(tag): return tag else: return None def GetRecentReleases(self, max_age): # Make sure tags are fetched. self.Git("fetch origin +refs/tags/*:refs/tags/*") # Current timestamp. time_now = int(self._side_effect_handler.GetUTCStamp()) # List every tag from a given period. revisions = self.Git("rev-list --max-age=%d --tags" % int(time_now - max_age)).strip() # Filter out revisions who's tag is off by one or more commits. return filter(lambda r: self.GetVersionTag(r), revisions.splitlines()) def GetLatestVersion(self): # Use cached version if available. if self["latest_version"]: return self["latest_version"] # Make sure tags are fetched. self.Git("fetch origin +refs/tags/*:refs/tags/*") version = sorted(filter(VERSION_RE.match, self.vc.GetTags()), key=SortingKey, reverse=True)[0] self["latest_version"] = version return version def GetLatestRelease(self): """The latest release is the git hash of the latest tagged version. This revision should be rolled into chromium. """ latest_version = self.GetLatestVersion() # The latest release. latest_hash = self.GitLog(n=1, format="%H", branch=latest_version) assert latest_hash return latest_hash def GetLatestReleaseBase(self, version=None): """The latest release base is the latest revision that is covered in the last change log file. It doesn't include cherry-picked patches. """ latest_version = version or self.GetLatestVersion() # Strip patch level if it exists. latest_version = ".".join(latest_version.split(".")[:3]) # The latest release base. latest_hash = self.GitLog(n=1, format="%H", branch=latest_version) assert latest_hash title = self.GitLog(n=1, format="%s", git_hash=latest_hash) match = PUSH_MSG_GIT_RE.match(title) if match: # Legacy: In the old process there's one level of indirection. The # version is on the candidates branch and points to the real release # base on master through the commit message. return match.group("git_rev") match = PUSH_MSG_NEW_RE.match(title) if match: # This is a new-style v8 version branched from master. The commit # "latest_hash" is the version-file change. Its parent is the release # base on master. return self.GitLog(n=1, format="%H", git_hash="%s^" % latest_hash) self.Die("Unknown latest release: %s" % latest_hash) def ArrayToVersion(self, prefix): return ".".join([self[prefix + "major"], self[prefix + "minor"], self[prefix + "build"], self[prefix + "patch"]]) def StoreVersion(self, version, prefix): version_parts = version.split(".") if len(version_parts) == 3: version_parts.append("0") major, minor, build, patch = version_parts self[prefix + "major"] = major self[prefix + "minor"] = minor self[prefix + "build"] = build self[prefix + "patch"] = patch def SetVersion(self, version_file, prefix): output = "" for line in FileToText(version_file).splitlines(): if line.startswith("#define V8_MAJOR_VERSION"): line = re.sub("\d+$", self[prefix + "major"], line) elif line.startswith("#define V8_MINOR_VERSION"): line = re.sub("\d+$", self[prefix + "minor"], line) elif line.startswith("#define V8_BUILD_NUMBER"): line = re.sub("\d+$", self[prefix + "build"], line) elif line.startswith("#define V8_PATCH_LEVEL"): line = re.sub("\d+$", self[prefix + "patch"], line) elif (self[prefix + "candidate"] and line.startswith("#define V8_IS_CANDIDATE_VERSION")): line = re.sub("\d+$", self[prefix + "candidate"], line) output += "%s\n" % line TextToFile(output, version_file) class BootstrapStep(Step): MESSAGE = "Bootstapping v8 checkout." def RunStep(self): if os.path.realpath(self.default_cwd) == os.path.realpath(V8_BASE): self.Die("Can't use v8 checkout with calling script as work checkout.") # Directory containing the working v8 checkout. if not os.path.exists(self._options.work_dir): os.makedirs(self._options.work_dir) if not os.path.exists(self.default_cwd): self.Command("fetch", "v8", cwd=self._options.work_dir) class UploadStep(Step): MESSAGE = "Upload for code review." def RunStep(self): if self._options.reviewer: print "Using account %s for review." % self._options.reviewer reviewer = self._options.reviewer else: print "Please enter the email address of a V8 reviewer for your patch: ", self.DieNoManualMode("A reviewer must be specified in forced mode.") reviewer = self.ReadLine() self.GitUpload(reviewer, self._options.author, self._options.force_upload, bypass_hooks=self._options.bypass_upload_hooks, cc=self._options.cc) class DetermineV8Sheriff(Step): MESSAGE = "Determine the V8 sheriff for code review." def RunStep(self): self["sheriff"] = None if not self._options.sheriff: # pragma: no cover return # The sheriff determined by the rotation on the waterfall has a # @google.com account. url = "https://chromium-build.appspot.com/p/chromium/sheriff_v8.js" match = re.match(r"document\.write\('(\w+)'\)", self.ReadURL(url)) # If "channel is sheriff", we can't match an account. if match: g_name = match.group(1) # Optimistically assume that google and chromium account name are the # same. self["sheriff"] = g_name + "@chromium.org" self._options.reviewer = ("%s,%s" % (self["sheriff"], self._options.reviewer)) print "Found active sheriff: %s" % self["sheriff"] else: print "No active sheriff found." def MakeStep(step_class=Step, number=0, state=None, config=None, options=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER): # Allow to pass in empty dictionaries. state = state if state is not None else {} config = config if config is not None else {} try: message = step_class.MESSAGE except AttributeError: message = step_class.__name__ return step_class(message, number=number, config=config, state=state, options=options, handler=side_effect_handler) class ScriptsBase(object): def __init__(self, config=None, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER, state=None): self._config = config or self._Config() self._side_effect_handler = side_effect_handler self._state = state if state is not None else {} def _Description(self): return None def _PrepareOptions(self, parser): pass def _ProcessOptions(self, options): return True def _Steps(self): # pragma: no cover raise Exception("Not implemented.") def _Config(self): return {} def MakeOptions(self, args=None): parser = argparse.ArgumentParser(description=self._Description()) parser.add_argument("-a", "--author", default="", help="The author email used for rietveld.") parser.add_argument("--dry-run", default=False, action="store_true", help="Perform only read-only actions.") parser.add_argument("-r", "--reviewer", default="", help="The account name to be used for reviews.") parser.add_argument("--sheriff", default=False, action="store_true", help=("Determine current sheriff to review CLs. On " "success, this will overwrite the reviewer " "option.")) parser.add_argument("-s", "--step", help="Specify the step where to start work. Default: 0.", default=0, type=int) parser.add_argument("--work-dir", help=("Location where to bootstrap a working v8 " "checkout.")) self._PrepareOptions(parser) if args is None: # pragma: no cover options = parser.parse_args() else: options = parser.parse_args(args) # Process common options. if options.step < 0: # pragma: no cover print "Bad step number %d" % options.step parser.print_help() return None # Defaults for options, common to all scripts. options.manual = getattr(options, "manual", True) options.force = getattr(options, "force", False) options.bypass_upload_hooks = False # Derived options. options.requires_editor = not options.force options.wait_for_lgtm = not options.force options.force_readline_defaults = not options.manual options.force_upload = not options.manual # Process script specific options. if not self._ProcessOptions(options): parser.print_help() return None if not options.work_dir: options.work_dir = "/tmp/v8-release-scripts-work-dir" return options def RunSteps(self, step_classes, args=None): options = self.MakeOptions(args) if not options: return 1 state_file = "%s-state.json" % self._config["PERSISTFILE_BASENAME"] if options.step == 0 and os.path.exists(state_file): os.remove(state_file) steps = [] for (number, step_class) in enumerate([BootstrapStep] + step_classes): steps.append(MakeStep(step_class, number, self._state, self._config, options, self._side_effect_handler)) for step in steps[options.step:]: if step.Run(): return 0 return 0 def Run(self, args=None): return self.RunSteps(self._Steps(), args) node-v4.2.6/deps/v8/tools/release/create_release.py000755 000766 000024 00000023271 12650222326 022343 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import os import sys import tempfile import urllib2 from common_includes import * class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): fetchspecs = [ "+refs/heads/*:refs/heads/*", "+refs/pending/*:refs/pending/*", "+refs/pending-tags/*:refs/pending-tags/*", ] self.Git("fetch origin %s" % " ".join(fetchspecs)) self.GitCheckout("origin/master") self.DeleteBranch("work-branch") class PrepareBranchRevision(Step): MESSAGE = "Check from which revision to branch off." def RunStep(self): self["push_hash"] = (self._options.revision or self.GitLog(n=1, format="%H", branch="origin/master")) assert self["push_hash"] print "Release revision %s" % self["push_hash"] class IncrementVersion(Step): MESSAGE = "Increment version number." def RunStep(self): latest_version = self.GetLatestVersion() # The version file on master can be used to bump up major/minor at # branch time. self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteMasterBranch()) self.ReadAndPersistVersion("master_") master_version = self.ArrayToVersion("master_") # Use the highest version from master or from tags to determine the new # version. authoritative_version = sorted( [master_version, latest_version], key=SortingKey)[1] self.StoreVersion(authoritative_version, "authoritative_") # Variables prefixed with 'new_' contain the new version numbers for the # ongoing candidates push. self["new_major"] = self["authoritative_major"] self["new_minor"] = self["authoritative_minor"] self["new_build"] = str(int(self["authoritative_build"]) + 1) # Make sure patch level is 0 in a new push. self["new_patch"] = "0" # The new version is not a candidate. self["new_candidate"] = "0" self["version"] = "%s.%s.%s" % (self["new_major"], self["new_minor"], self["new_build"]) print ("Incremented version to %s" % self["version"]) class DetectLastRelease(Step): MESSAGE = "Detect commit ID of last release base." def RunStep(self): self["last_push_master"] = self.GetLatestReleaseBase() class PrepareChangeLog(Step): MESSAGE = "Prepare raw ChangeLog entry." def Reload(self, body): """Attempts to reload the commit message from rietveld in order to allow late changes to the LOG flag. Note: This is brittle to future changes of the web page name or structure. """ match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", body, flags=re.M) if match: cl_url = ("https://codereview.chromium.org/%s/description" % match.group(1)) try: # Fetch from Rietveld but only retry once with one second delay since # there might be many revisions. body = self.ReadURL(cl_url, wait_plan=[1]) except urllib2.URLError: # pragma: no cover pass return body def RunStep(self): self["date"] = self.GetDate() output = "%s: Version %s\n\n" % (self["date"], self["version"]) TextToFile(output, self.Config("CHANGELOG_ENTRY_FILE")) commits = self.GitLog(format="%H", git_hash="%s..%s" % (self["last_push_master"], self["push_hash"])) # Cache raw commit messages. commit_messages = [ [ self.GitLog(n=1, format="%s", git_hash=commit), self.Reload(self.GitLog(n=1, format="%B", git_hash=commit)), self.GitLog(n=1, format="%an", git_hash=commit), ] for commit in commits.splitlines() ] # Auto-format commit messages. body = MakeChangeLogBody(commit_messages, auto_format=True) AppendToFile(body, self.Config("CHANGELOG_ENTRY_FILE")) msg = (" Performance and stability improvements on all platforms." "\n#\n# The change log above is auto-generated. Please review if " "all relevant\n# commit messages from the list below are included." "\n# All lines starting with # will be stripped.\n#\n") AppendToFile(msg, self.Config("CHANGELOG_ENTRY_FILE")) # Include unformatted commit messages as a reference in a comment. comment_body = MakeComment(MakeChangeLogBody(commit_messages)) AppendToFile(comment_body, self.Config("CHANGELOG_ENTRY_FILE")) class EditChangeLog(Step): MESSAGE = "Edit ChangeLog entry." def RunStep(self): print ("Please press to have your EDITOR open the ChangeLog " "entry, then edit its contents to your liking. When you're done, " "save the file and exit your EDITOR. ") self.ReadLine(default="") self.Editor(self.Config("CHANGELOG_ENTRY_FILE")) # Strip comments and reformat with correct indentation. changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")).rstrip() changelog_entry = StripComments(changelog_entry) changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) changelog_entry = changelog_entry.lstrip() if changelog_entry == "": # pragma: no cover self.Die("Empty ChangeLog entry.") # Safe new change log for adding it later to the candidates patch. TextToFile(changelog_entry, self.Config("CHANGELOG_ENTRY_FILE")) class MakeBranch(Step): MESSAGE = "Create the branch." def RunStep(self): self.Git("reset --hard origin/master") self.Git("checkout -b work-branch %s" % self["push_hash"]) self.GitCheckoutFile(CHANGELOG_FILE, self["latest_version"]) self.GitCheckoutFile(VERSION_FILE, self["latest_version"]) class AddChangeLog(Step): MESSAGE = "Add ChangeLog changes to release branch." def RunStep(self): changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")) old_change_log = FileToText(os.path.join(self.default_cwd, CHANGELOG_FILE)) new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log) TextToFile(new_change_log, os.path.join(self.default_cwd, CHANGELOG_FILE)) class SetVersion(Step): MESSAGE = "Set correct version for candidates." def RunStep(self): self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_") class CommitBranch(Step): MESSAGE = "Commit version and changelog to new branch." def RunStep(self): # Convert the ChangeLog entry to commit message format. text = FileToText(self.Config("CHANGELOG_ENTRY_FILE")) # Remove date and trailing white space. text = re.sub(r"^%s: " % self["date"], "", text.rstrip()) # Remove indentation and merge paragraphs into single long lines, keeping # empty lines between them. def SplitMapJoin(split_text, fun, join_text): return lambda text: join_text.join(map(fun, text.split(split_text))) text = SplitMapJoin( "\n\n", SplitMapJoin("\n", str.strip, " "), "\n\n")(text) if not text: # pragma: no cover self.Die("Commit message editing failed.") self["commit_title"] = text.splitlines()[0] TextToFile(text, self.Config("COMMITMSG_FILE")) self.GitCommit(file_name = self.Config("COMMITMSG_FILE")) os.remove(self.Config("COMMITMSG_FILE")) os.remove(self.Config("CHANGELOG_ENTRY_FILE")) class PushBranch(Step): MESSAGE = "Push changes." def RunStep(self): pushspecs = [ "refs/heads/work-branch:refs/pending/heads/%s" % self["version"], "%s:refs/pending-tags/heads/%s" % (self["push_hash"], self["version"]), "%s:refs/heads/%s" % (self["push_hash"], self["version"]), ] cmd = "push origin %s" % " ".join(pushspecs) if self._options.dry_run: print "Dry run. Command:\ngit %s" % cmd else: self.Git(cmd) class TagRevision(Step): MESSAGE = "Tag the new revision." def RunStep(self): if self._options.dry_run: print ("Dry run. Tagging \"%s\" with %s" % (self["commit_title"], self["version"])) else: self.vc.Tag(self["version"], "origin/%s" % self["version"], self["commit_title"]) class CleanUp(Step): MESSAGE = "Done!" def RunStep(self): print("Congratulations, you have successfully created version %s." % self["version"]) self.GitCheckout("origin/master") self.DeleteBranch("work-branch") self.Git("gc") class CreateRelease(ScriptsBase): def _PrepareOptions(self, parser): group = parser.add_mutually_exclusive_group() group.add_argument("-f", "--force", help="Don't prompt the user.", default=True, action="store_true") group.add_argument("-m", "--manual", help="Prompt the user at every important step.", default=False, action="store_true") parser.add_argument("-R", "--revision", help="The git commit ID to push (defaults to HEAD).") def _ProcessOptions(self, options): # pragma: no cover if not options.author or not options.reviewer: print "Reviewer (-r) and author (-a) are required." return False return True def _Config(self): return { "PERSISTFILE_BASENAME": "/tmp/create-releases-tempfile", "CHANGELOG_ENTRY_FILE": "/tmp/v8-create-releases-tempfile-changelog-entry", "COMMITMSG_FILE": "/tmp/v8-create-releases-tempfile-commitmsg", } def _Steps(self): return [ Preparation, PrepareBranchRevision, IncrementVersion, DetectLastRelease, PrepareChangeLog, EditChangeLog, MakeBranch, AddChangeLog, SetVersion, CommitBranch, PushBranch, TagRevision, CleanUp, ] if __name__ == "__main__": # pragma: no cover sys.exit(CreateRelease().Run()) node-v4.2.6/deps/v8/tools/release/git_recipes.py000644 000766 000024 00000022410 12650222326 021664 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import re SHA1_RE = re.compile('^[a-fA-F0-9]{40}$') ROLL_DEPS_GIT_SVN_ID_RE = re.compile('^git-svn-id: .*@([0-9]+) .*$') # Regular expression that matches a single commit footer line. COMMIT_FOOTER_ENTRY_RE = re.compile(r'([^:]+):\s+(.+)') # Footer metadata key for commit position. COMMIT_POSITION_FOOTER_KEY = 'Cr-Commit-Position' # Regular expression to parse a commit position COMMIT_POSITION_RE = re.compile(r'(.+)@\{#(\d+)\}') # Key for the 'git-svn' ID metadata commit footer entry. GIT_SVN_ID_FOOTER_KEY = 'git-svn-id' # e.g., git-svn-id: https://v8.googlecode.com/svn/trunk@23117 # ce2b1a6d-e550-0410-aec6-3dcde31c8c00 GIT_SVN_ID_RE = re.compile(r'[^@]+@(\d+)\s+(?:[a-zA-Z0-9\-]+)') # Copied from bot_update.py. def GetCommitMessageFooterMap(message): """Returns: (dict) A dictionary of commit message footer entries. """ footers = {} # Extract the lines in the footer block. lines = [] for line in message.strip().splitlines(): line = line.strip() if len(line) == 0: del(lines[:]) continue lines.append(line) # Parse the footer for line in lines: m = COMMIT_FOOTER_ENTRY_RE.match(line) if not m: # If any single line isn't valid, the entire footer is invalid. footers.clear() return footers footers[m.group(1)] = m.group(2).strip() return footers class GitFailedException(Exception): pass def Strip(f): def new_f(*args, **kwargs): result = f(*args, **kwargs) if result is None: return result else: return result.strip() return new_f def MakeArgs(l): """['-a', '', 'abc', ''] -> '-a abc'""" return " ".join(filter(None, l)) def Quoted(s): return "\"%s\"" % s class GitRecipesMixin(object): def GitIsWorkdirClean(self, **kwargs): return self.Git("status -s -uno", **kwargs).strip() == "" @Strip def GitBranch(self, **kwargs): return self.Git("branch", **kwargs) def GitCreateBranch(self, name, remote="", **kwargs): assert name remote_args = ["--upstream", remote] if remote else [] self.Git(MakeArgs(["new-branch", name] + remote_args), **kwargs) def GitDeleteBranch(self, name, **kwargs): assert name self.Git(MakeArgs(["branch -D", name]), **kwargs) def GitReset(self, name, **kwargs): assert name self.Git(MakeArgs(["reset --hard", name]), **kwargs) def GitStash(self, **kwargs): self.Git(MakeArgs(["stash"]), **kwargs) def GitRemotes(self, **kwargs): return map(str.strip, self.Git(MakeArgs(["branch -r"]), **kwargs).splitlines()) def GitCheckout(self, name, **kwargs): assert name self.Git(MakeArgs(["checkout -f", name]), **kwargs) def GitCheckoutFile(self, name, branch_or_hash, **kwargs): assert name assert branch_or_hash self.Git(MakeArgs(["checkout -f", branch_or_hash, "--", name]), **kwargs) def GitCheckoutFileSafe(self, name, branch_or_hash, **kwargs): try: self.GitCheckoutFile(name, branch_or_hash, **kwargs) except GitFailedException: # pragma: no cover # The file doesn't exist in that revision. return False return True def GitChangedFiles(self, git_hash, **kwargs): assert git_hash try: files = self.Git(MakeArgs(["diff --name-only", git_hash, "%s^" % git_hash]), **kwargs) return map(str.strip, files.splitlines()) except GitFailedException: # pragma: no cover # Git fails using "^" at branch roots. return [] @Strip def GitCurrentBranch(self, **kwargs): for line in self.Git("status -s -b -uno", **kwargs).strip().splitlines(): match = re.match(r"^## (.+)", line) if match: return match.group(1) raise Exception("Couldn't find curent branch.") # pragma: no cover @Strip def GitLog(self, n=0, format="", grep="", git_hash="", parent_hash="", branch="", path=None, reverse=False, **kwargs): assert not (git_hash and parent_hash) args = ["log"] if n > 0: args.append("-%d" % n) if format: args.append("--format=%s" % format) if grep: args.append("--grep=\"%s\"" % grep.replace("\"", "\\\"")) if reverse: args.append("--reverse") if git_hash: args.append(git_hash) if parent_hash: args.append("%s^" % parent_hash) args.append(branch) if path: args.extend(["--", path]) return self.Git(MakeArgs(args), **kwargs) def GitShowFile(self, refspec, path, **kwargs): assert refspec assert path return self.Git(MakeArgs(["show", "%s:%s" % (refspec, path)]), **kwargs) def GitGetPatch(self, git_hash, **kwargs): assert git_hash return self.Git(MakeArgs(["log", "-1", "-p", git_hash]), **kwargs) # TODO(machenbach): Unused? Remove. def GitAdd(self, name, **kwargs): assert name self.Git(MakeArgs(["add", Quoted(name)]), **kwargs) def GitApplyPatch(self, patch_file, reverse=False, **kwargs): assert patch_file args = ["apply --index --reject"] if reverse: args.append("--reverse") args.append(Quoted(patch_file)) self.Git(MakeArgs(args), **kwargs) def GitUpload(self, reviewer="", author="", force=False, cq=False, bypass_hooks=False, cc="", **kwargs): args = ["cl upload --send-mail"] if author: args += ["--email", Quoted(author)] if reviewer: args += ["-r", Quoted(reviewer)] if force: args.append("-f") if cq: args.append("--use-commit-queue") if bypass_hooks: args.append("--bypass-hooks") if cc: args += ["--cc", Quoted(cc)] # TODO(machenbach): Check output in forced mode. Verify that all required # base files were uploaded, if not retry. self.Git(MakeArgs(args), pipe=False, **kwargs) def GitCommit(self, message="", file_name="", author=None, **kwargs): assert message or file_name args = ["commit"] if file_name: args += ["-aF", Quoted(file_name)] if message: args += ["-am", Quoted(message)] if author: args += ["--author", "\"%s <%s>\"" % (author, author)] self.Git(MakeArgs(args), **kwargs) def GitPresubmit(self, **kwargs): self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"", **kwargs) def GitCLLand(self, **kwargs): self.Git( "cl land -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs) def GitDiff(self, loc1, loc2, **kwargs): return self.Git(MakeArgs(["diff", loc1, loc2]), **kwargs) def GitPull(self, **kwargs): self.Git("pull", **kwargs) def GitFetchOrigin(self, *refspecs, **kwargs): self.Git(MakeArgs(["fetch", "origin"] + list(refspecs)), **kwargs) @Strip # Copied from bot_update.py and modified for svn-like numbers only. def GetCommitPositionNumber(self, git_hash, **kwargs): """Dumps the 'git' log for a specific revision and parses out the commit position number. If a commit position metadata key is found, its number will be returned. Otherwise, we will search for a 'git-svn' metadata entry. If one is found, its SVN revision value is returned. """ git_log = self.GitLog(format='%B', n=1, git_hash=git_hash, **kwargs) footer_map = GetCommitMessageFooterMap(git_log) # Search for commit position metadata value = footer_map.get(COMMIT_POSITION_FOOTER_KEY) if value: match = COMMIT_POSITION_RE.match(value) if match: return match.group(2) # Extract the svn revision from 'git-svn' metadata value = footer_map.get(GIT_SVN_ID_FOOTER_KEY) if value: match = GIT_SVN_ID_RE.match(value) if match: return match.group(1) raise GitFailedException("Couldn't determine commit position for %s" % git_hash) def GitGetHashOfTag(self, tag_name, **kwargs): return self.Git("rev-list -1 " + tag_name).strip().encode("ascii", "ignore") node-v4.2.6/deps/v8/tools/release/merge_to_branch.py000755 000766 000024 00000026701 12650222326 022517 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from collections import OrderedDict import sys from common_includes import * def IsSvnNumber(rev): return rev.isdigit() and len(rev) < 8 class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): if os.path.exists(self.Config("ALREADY_MERGING_SENTINEL_FILE")): if self._options.force: os.remove(self.Config("ALREADY_MERGING_SENTINEL_FILE")) elif self._options.step == 0: # pragma: no cover self.Die("A merge is already in progress") open(self.Config("ALREADY_MERGING_SENTINEL_FILE"), "a").close() self.InitialEnvironmentChecks(self.default_cwd) if self._options.revert_master: # FIXME(machenbach): Make revert master obsolete? self["merge_to_branch"] = "master" elif self._options.branch: self["merge_to_branch"] = self._options.branch else: # pragma: no cover self.Die("Please specify a branch to merge to") self.CommonPrepare() self.PrepareBranch() class CreateBranch(Step): MESSAGE = "Create a fresh branch for the patch." def RunStep(self): self.GitCreateBranch(self.Config("BRANCHNAME"), self.vc.RemoteBranch(self["merge_to_branch"])) class SearchArchitecturePorts(Step): MESSAGE = "Search for corresponding architecture ports." def RunStep(self): self["full_revision_list"] = list(OrderedDict.fromkeys( self._options.revisions)) port_revision_list = [] for revision in self["full_revision_list"]: # Search for commits which matches the "Port XXX" pattern. git_hashes = self.GitLog(reverse=True, format="%H", grep="Port %s" % revision, branch=self.vc.RemoteMasterBranch()) for git_hash in git_hashes.splitlines(): revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash) # Is this revision included in the original revision list? if git_hash in self["full_revision_list"]: print("Found port of %s -> %s (already included): %s" % (revision, git_hash, revision_title)) else: print("Found port of %s -> %s: %s" % (revision, git_hash, revision_title)) port_revision_list.append(git_hash) # Do we find any port? if len(port_revision_list) > 0: if self.Confirm("Automatically add corresponding ports (%s)?" % ", ".join(port_revision_list)): #: 'y': Add ports to revision list. self["full_revision_list"].extend(port_revision_list) class CreateCommitMessage(Step): MESSAGE = "Create commit message." def RunStep(self): # Stringify: [123, 234] -> "r123, r234" self["revision_list"] = ", ".join(map(lambda s: "r%s" % s, self["full_revision_list"])) if not self["revision_list"]: # pragma: no cover self.Die("Revision list is empty.") if self._options.revert and not self._options.revert_master: action_text = "Rollback of %s" else: action_text = "Merged %s" # The commit message title is added below after the version is specified. msg_pieces = [ "\n".join(action_text % s for s in self["full_revision_list"]), ] msg_pieces.append("\n\n") for commit_hash in self["full_revision_list"]: patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash) msg_pieces.append("%s\n\n" % patch_merge_desc) bugs = [] for commit_hash in self["full_revision_list"]: msg = self.GitLog(n=1, git_hash=commit_hash) for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, re.M): bugs.extend(s.strip() for s in bug.split(",")) bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs))) if bug_aggregate: msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate) self["new_commit_msg"] = "".join(msg_pieces) class ApplyPatches(Step): MESSAGE = "Apply patches for selected revisions." def RunStep(self): for commit_hash in self["full_revision_list"]: print("Applying patch for %s to %s..." % (commit_hash, self["merge_to_branch"])) patch = self.GitGetPatch(commit_hash) TextToFile(patch, self.Config("TEMPORARY_PATCH_FILE")) self.ApplyPatch(self.Config("TEMPORARY_PATCH_FILE"), self._options.revert) if self._options.patch: self.ApplyPatch(self._options.patch, self._options.revert) class PrepareVersion(Step): MESSAGE = "Prepare version file." def RunStep(self): if self._options.revert_master: return # This is used to calculate the patch level increment. self.ReadAndPersistVersion() class IncrementVersion(Step): MESSAGE = "Increment version number." def RunStep(self): if self._options.revert_master: return new_patch = str(int(self["patch"]) + 1) if self.Confirm("Automatically increment V8_PATCH_LEVEL? (Saying 'n' will " "fire up your EDITOR on %s so you can make arbitrary " "changes. When you're done, save the file and exit your " "EDITOR.)" % VERSION_FILE): text = FileToText(os.path.join(self.default_cwd, VERSION_FILE)) text = MSub(r"(?<=#define V8_PATCH_LEVEL)(?P\s+)\d*$", r"\g%s" % new_patch, text) TextToFile(text, os.path.join(self.default_cwd, VERSION_FILE)) else: self.Editor(os.path.join(self.default_cwd, VERSION_FILE)) self.ReadAndPersistVersion("new_") self["version"] = "%s.%s.%s.%s" % (self["new_major"], self["new_minor"], self["new_build"], self["new_patch"]) class CommitLocal(Step): MESSAGE = "Commit to local branch." def RunStep(self): # Add a commit message title. if self._options.revert and self._options.revert_master: # TODO(machenbach): Find a better convention if multiple patches are # reverted in one CL. self["commit_title"] = "Revert on master" else: self["commit_title"] = "Version %s (cherry-pick)" % self["version"] self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"], self["new_commit_msg"]) TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE")) self.GitCommit(file_name=self.Config("COMMITMSG_FILE")) class CommitRepository(Step): MESSAGE = "Commit to the repository." def RunStep(self): self.GitCheckout(self.Config("BRANCHNAME")) self.WaitForLGTM() self.GitPresubmit() self.vc.CLLand() class TagRevision(Step): MESSAGE = "Create the tag." def RunStep(self): if self._options.revert_master: return print "Creating tag %s" % self["version"] self.vc.Tag(self["version"], self.vc.RemoteBranch(self["merge_to_branch"]), self["commit_title"]) class CleanUp(Step): MESSAGE = "Cleanup." def RunStep(self): self.CommonCleanup() if not self._options.revert_master: print "*** SUMMARY ***" print "version: %s" % self["version"] print "branch: %s" % self["merge_to_branch"] if self["revision_list"]: print "patches: %s" % self["revision_list"] class MergeToBranch(ScriptsBase): def _Description(self): return ("Performs the necessary steps to merge revisions from " "master to other branches, including candidates.") def _PrepareOptions(self, parser): group = parser.add_mutually_exclusive_group(required=True) group.add_argument("--branch", help="The branch to merge to.") group.add_argument("-R", "--revert-master", help="Revert specified patches from master.", default=False, action="store_true") parser.add_argument("revisions", nargs="*", help="The revisions to merge.") parser.add_argument("-f", "--force", help="Delete sentinel file.", default=False, action="store_true") parser.add_argument("-m", "--message", help="A commit message for the patch.") parser.add_argument("--revert", help="Revert specified patches.", default=False, action="store_true") parser.add_argument("-p", "--patch", help="A patch file to apply as part of the merge.") def _ProcessOptions(self, options): # TODO(machenbach): Add a test that covers revert from master if len(options.revisions) < 1: if not options.patch: print "Either a patch file or revision numbers must be specified" return False if not options.message: print "You must specify a merge comment if no patches are specified" return False options.bypass_upload_hooks = True # CC ulan to make sure that fixes are merged to Google3. options.cc = "ulan@chromium.org" # Make sure to use git hashes in the new workflows. for revision in options.revisions: if (IsSvnNumber(revision) or (revision[0:1] == "r" and IsSvnNumber(revision[1:]))): print "Please provide full git hashes of the patches to merge." print "Got: %s" % revision return False return True def _Config(self): return { "BRANCHNAME": "prepare-merge", "PERSISTFILE_BASENAME": "/tmp/v8-merge-to-branch-tempfile", "ALREADY_MERGING_SENTINEL_FILE": "/tmp/v8-merge-to-branch-tempfile-already-merging", "TEMPORARY_PATCH_FILE": "/tmp/v8-prepare-merge-tempfile-temporary-patch", "COMMITMSG_FILE": "/tmp/v8-prepare-merge-tempfile-commitmsg", } def _Steps(self): return [ Preparation, CreateBranch, SearchArchitecturePorts, CreateCommitMessage, ApplyPatches, PrepareVersion, IncrementVersion, CommitLocal, UploadStep, CommitRepository, TagRevision, CleanUp, ] if __name__ == "__main__": # pragma: no cover sys.exit(MergeToBranch().Run()) node-v4.2.6/deps/v8/tools/release/mergeinfo.py000755 000766 000024 00000002661 12650222326 021353 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import os import sys from subprocess import call def print_analysis(gitWorkingDir, hashToSearch): print '1.) Info' git_execute(gitWorkingDir, ['status']) print '2.) Searching for "' + hashToSearch + '"' print '=====================ORIGINAL COMMIT START=====================' git_execute(gitWorkingDir, ['show', hashToSearch]) print '=====================ORIGINAL COMMIT END=====================' print '#####################FOUND MERGES & REVERTS START#####################' git_execute(gitWorkingDir, ["log",'--all', '--grep='+hashToSearch]) print '#####################FOUND MERGES & REVERTS END#####################' print 'Finished successfully' def git_execute(workingDir, commands): return call(["git", '-C', workingDir] + commands) if __name__ == "__main__": # pragma: no cover parser = argparse.ArgumentParser('Tool to check where a git commit was merged and reverted.') parser.add_argument("-g", "--git-dir", required=False, default='.', help="The path to your git working directory.") parser.add_argument('hash', nargs=1, help="Hash of the commit to be searched.") args = sys.argv[1:] options = parser.parse_args(args) sys.exit(print_analysis(options.git_dir, options.hash[0])) node-v4.2.6/deps/v8/tools/release/push_to_candidates.py000755 000766 000024 00000034516 12650222326 023244 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import os import sys import tempfile import urllib2 from common_includes import * PUSH_MSG_GIT_SUFFIX = " (based on %s)" class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): self.InitialEnvironmentChecks(self.default_cwd) self.CommonPrepare() if(self["current_branch"] == self.Config("CANDIDATESBRANCH") or self["current_branch"] == self.Config("BRANCHNAME")): print "Warning: Script started on branch %s" % self["current_branch"] self.PrepareBranch() self.DeleteBranch(self.Config("CANDIDATESBRANCH")) class FreshBranch(Step): MESSAGE = "Create a fresh branch." def RunStep(self): self.GitCreateBranch(self.Config("BRANCHNAME"), self.vc.RemoteMasterBranch()) class PreparePushRevision(Step): MESSAGE = "Check which revision to push." def RunStep(self): if self._options.revision: self["push_hash"] = self._options.revision else: self["push_hash"] = self.GitLog(n=1, format="%H", git_hash="HEAD") if not self["push_hash"]: # pragma: no cover self.Die("Could not determine the git hash for the push.") class IncrementVersion(Step): MESSAGE = "Increment version number." def RunStep(self): latest_version = self.GetLatestVersion() # The version file on master can be used to bump up major/minor at # branch time. self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteMasterBranch()) self.ReadAndPersistVersion("master_") master_version = self.ArrayToVersion("master_") # Use the highest version from master or from tags to determine the new # version. authoritative_version = sorted( [master_version, latest_version], key=SortingKey)[1] self.StoreVersion(authoritative_version, "authoritative_") # Variables prefixed with 'new_' contain the new version numbers for the # ongoing candidates push. self["new_major"] = self["authoritative_major"] self["new_minor"] = self["authoritative_minor"] self["new_build"] = str(int(self["authoritative_build"]) + 1) # Make sure patch level is 0 in a new push. self["new_patch"] = "0" self["version"] = "%s.%s.%s" % (self["new_major"], self["new_minor"], self["new_build"]) print ("Incremented version to %s" % self["version"]) class DetectLastRelease(Step): MESSAGE = "Detect commit ID of last release base." def RunStep(self): if self._options.last_master: self["last_push_master"] = self._options.last_master else: self["last_push_master"] = self.GetLatestReleaseBase() class PrepareChangeLog(Step): MESSAGE = "Prepare raw ChangeLog entry." def Reload(self, body): """Attempts to reload the commit message from rietveld in order to allow late changes to the LOG flag. Note: This is brittle to future changes of the web page name or structure. """ match = re.search(r"^Review URL: https://codereview\.chromium\.org/(\d+)$", body, flags=re.M) if match: cl_url = ("https://codereview.chromium.org/%s/description" % match.group(1)) try: # Fetch from Rietveld but only retry once with one second delay since # there might be many revisions. body = self.ReadURL(cl_url, wait_plan=[1]) except urllib2.URLError: # pragma: no cover pass return body def RunStep(self): self["date"] = self.GetDate() output = "%s: Version %s\n\n" % (self["date"], self["version"]) TextToFile(output, self.Config("CHANGELOG_ENTRY_FILE")) commits = self.GitLog(format="%H", git_hash="%s..%s" % (self["last_push_master"], self["push_hash"])) # Cache raw commit messages. commit_messages = [ [ self.GitLog(n=1, format="%s", git_hash=commit), self.Reload(self.GitLog(n=1, format="%B", git_hash=commit)), self.GitLog(n=1, format="%an", git_hash=commit), ] for commit in commits.splitlines() ] # Auto-format commit messages. body = MakeChangeLogBody(commit_messages, auto_format=True) AppendToFile(body, self.Config("CHANGELOG_ENTRY_FILE")) msg = (" Performance and stability improvements on all platforms." "\n#\n# The change log above is auto-generated. Please review if " "all relevant\n# commit messages from the list below are included." "\n# All lines starting with # will be stripped.\n#\n") AppendToFile(msg, self.Config("CHANGELOG_ENTRY_FILE")) # Include unformatted commit messages as a reference in a comment. comment_body = MakeComment(MakeChangeLogBody(commit_messages)) AppendToFile(comment_body, self.Config("CHANGELOG_ENTRY_FILE")) class EditChangeLog(Step): MESSAGE = "Edit ChangeLog entry." def RunStep(self): print ("Please press to have your EDITOR open the ChangeLog " "entry, then edit its contents to your liking. When you're done, " "save the file and exit your EDITOR. ") self.ReadLine(default="") self.Editor(self.Config("CHANGELOG_ENTRY_FILE")) # Strip comments and reformat with correct indentation. changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")).rstrip() changelog_entry = StripComments(changelog_entry) changelog_entry = "\n".join(map(Fill80, changelog_entry.splitlines())) changelog_entry = changelog_entry.lstrip() if changelog_entry == "": # pragma: no cover self.Die("Empty ChangeLog entry.") # Safe new change log for adding it later to the candidates patch. TextToFile(changelog_entry, self.Config("CHANGELOG_ENTRY_FILE")) class StragglerCommits(Step): MESSAGE = ("Fetch straggler commits that sneaked in since this script was " "started.") def RunStep(self): self.vc.Fetch() self.GitCheckout(self.vc.RemoteMasterBranch()) class SquashCommits(Step): MESSAGE = "Squash commits into one." def RunStep(self): # Instead of relying on "git rebase -i", we'll just create a diff, because # that's easier to automate. TextToFile(self.GitDiff(self.vc.RemoteCandidateBranch(), self["push_hash"]), self.Config("PATCH_FILE")) # Convert the ChangeLog entry to commit message format. text = FileToText(self.Config("CHANGELOG_ENTRY_FILE")) # Remove date and trailing white space. text = re.sub(r"^%s: " % self["date"], "", text.rstrip()) # Show the used master hash in the commit message. suffix = PUSH_MSG_GIT_SUFFIX % self["push_hash"] text = MSub(r"^(Version \d+\.\d+\.\d+)$", "\\1%s" % suffix, text) # Remove indentation and merge paragraphs into single long lines, keeping # empty lines between them. def SplitMapJoin(split_text, fun, join_text): return lambda text: join_text.join(map(fun, text.split(split_text))) strip = lambda line: line.strip() text = SplitMapJoin("\n\n", SplitMapJoin("\n", strip, " "), "\n\n")(text) if not text: # pragma: no cover self.Die("Commit message editing failed.") self["commit_title"] = text.splitlines()[0] TextToFile(text, self.Config("COMMITMSG_FILE")) class NewBranch(Step): MESSAGE = "Create a new branch from candidates." def RunStep(self): self.GitCreateBranch(self.Config("CANDIDATESBRANCH"), self.vc.RemoteCandidateBranch()) class ApplyChanges(Step): MESSAGE = "Apply squashed changes." def RunStep(self): self.ApplyPatch(self.Config("PATCH_FILE")) os.remove(self.Config("PATCH_FILE")) # The change log has been modified by the patch. Reset it to the version # on candidates and apply the exact changes determined by this # PrepareChangeLog step above. self.GitCheckoutFile(CHANGELOG_FILE, self.vc.RemoteCandidateBranch()) # The version file has been modified by the patch. Reset it to the version # on candidates. self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteCandidateBranch()) class CommitSquash(Step): MESSAGE = "Commit to local candidates branch." def RunStep(self): # Make a first commit with a slightly different title to not confuse # the tagging. msg = FileToText(self.Config("COMMITMSG_FILE")).splitlines() msg[0] = msg[0].replace("(based on", "(squashed - based on") self.GitCommit(message = "\n".join(msg)) class PrepareVersionBranch(Step): MESSAGE = "Prepare new branch to commit version and changelog file." def RunStep(self): self.GitCheckout("master") self.Git("fetch") self.GitDeleteBranch(self.Config("CANDIDATESBRANCH")) self.GitCreateBranch(self.Config("CANDIDATESBRANCH"), self.vc.RemoteCandidateBranch()) class AddChangeLog(Step): MESSAGE = "Add ChangeLog changes to candidates branch." def RunStep(self): changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE")) old_change_log = FileToText(os.path.join(self.default_cwd, CHANGELOG_FILE)) new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log) TextToFile(new_change_log, os.path.join(self.default_cwd, CHANGELOG_FILE)) os.remove(self.Config("CHANGELOG_ENTRY_FILE")) class SetVersion(Step): MESSAGE = "Set correct version for candidates." def RunStep(self): self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_") class CommitCandidate(Step): MESSAGE = "Commit version and changelog to local candidates branch." def RunStep(self): self.GitCommit(file_name = self.Config("COMMITMSG_FILE")) os.remove(self.Config("COMMITMSG_FILE")) class SanityCheck(Step): MESSAGE = "Sanity check." def RunStep(self): # TODO(machenbach): Run presubmit script here as it is now missing in the # prepare push process. if not self.Confirm("Please check if your local checkout is sane: Inspect " "%s, compile, run tests. Do you want to commit this new candidates " "revision to the repository?" % VERSION_FILE): self.Die("Execution canceled.") # pragma: no cover class Land(Step): MESSAGE = "Land the patch." def RunStep(self): self.vc.CLLand() class TagRevision(Step): MESSAGE = "Tag the new revision." def RunStep(self): self.vc.Tag( self["version"], self.vc.RemoteCandidateBranch(), self["commit_title"]) class CleanUp(Step): MESSAGE = "Done!" def RunStep(self): print("Congratulations, you have successfully created the candidates " "revision %s." % self["version"]) self.CommonCleanup() if self.Config("CANDIDATESBRANCH") != self["current_branch"]: self.GitDeleteBranch(self.Config("CANDIDATESBRANCH")) class PushToCandidates(ScriptsBase): def _PrepareOptions(self, parser): group = parser.add_mutually_exclusive_group() group.add_argument("-f", "--force", help="Don't prompt the user.", default=False, action="store_true") group.add_argument("-m", "--manual", help="Prompt the user at every important step.", default=False, action="store_true") parser.add_argument("-b", "--last-master", help=("The git commit ID of the last master " "revision that was pushed to candidates. This is" " used for the auto-generated ChangeLog entry.")) parser.add_argument("-l", "--last-push", help="The git commit ID of the last candidates push.") parser.add_argument("-R", "--revision", help="The git commit ID to push (defaults to HEAD).") def _ProcessOptions(self, options): # pragma: no cover if not options.manual and not options.reviewer: print "A reviewer (-r) is required in (semi-)automatic mode." return False if not options.manual and not options.author: print "Specify your chromium.org email with -a in (semi-)automatic mode." return False options.tbr_commit = not options.manual return True def _Config(self): return { "BRANCHNAME": "prepare-push", "CANDIDATESBRANCH": "candidates-push", "PERSISTFILE_BASENAME": "/tmp/v8-push-to-candidates-tempfile", "CHANGELOG_ENTRY_FILE": "/tmp/v8-push-to-candidates-tempfile-changelog-entry", "PATCH_FILE": "/tmp/v8-push-to-candidates-tempfile-patch-file", "COMMITMSG_FILE": "/tmp/v8-push-to-candidates-tempfile-commitmsg", } def _Steps(self): return [ Preparation, FreshBranch, PreparePushRevision, IncrementVersion, DetectLastRelease, PrepareChangeLog, EditChangeLog, StragglerCommits, SquashCommits, NewBranch, ApplyChanges, CommitSquash, SanityCheck, Land, PrepareVersionBranch, AddChangeLog, SetVersion, CommitCandidate, Land, TagRevision, CleanUp, ] if __name__ == "__main__": # pragma: no cover sys.exit(PushToCandidates().Run()) node-v4.2.6/deps/v8/tools/release/releases.py000755 000766 000024 00000046057 12650222326 021212 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # This script retrieves the history of all V8 branches and # their corresponding Chromium revisions. # Requires a chromium checkout with branch heads: # gclient sync --with_branch_heads # gclient fetch import argparse import csv import itertools import json import os import re import sys from common_includes import * CONFIG = { "BRANCHNAME": "retrieve-v8-releases", "PERSISTFILE_BASENAME": "/tmp/v8-releases-tempfile", } # Expression for retrieving the bleeding edge revision from a commit message. PUSH_MSG_SVN_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$") PUSH_MSG_GIT_RE = re.compile(r".* \(based on ([a-fA-F0-9]+)\)$") # Expression for retrieving the merged patches from a merge commit message # (old and new format). MERGE_MESSAGE_RE = re.compile(r"^.*[M|m]erged (.+)(\)| into).*$", re.M) CHERRY_PICK_TITLE_GIT_RE = re.compile(r"^.* \(cherry\-pick\)\.?$") # New git message for cherry-picked CLs. One message per line. MERGE_MESSAGE_GIT_RE = re.compile(r"^Merged ([a-fA-F0-9]+)\.?$") # Expression for retrieving reverted patches from a commit message (old and # new format). ROLLBACK_MESSAGE_RE = re.compile(r"^.*[R|r]ollback of (.+)(\)| in).*$", re.M) # New git message for reverted CLs. One message per line. ROLLBACK_MESSAGE_GIT_RE = re.compile(r"^Rollback of ([a-fA-F0-9]+)\.?$") # Expression for retrieving the code review link. REVIEW_LINK_RE = re.compile(r"^Review URL: (.+)$", re.M) # Expression with three versions (historical) for extracting the v8 revision # from the chromium DEPS file. DEPS_RE = re.compile(r"""^\s*(?:["']v8_revision["']: ["']""" """|\(Var\("googlecode_url"\) % "v8"\) \+ "\/trunk@""" """|"http\:\/\/v8\.googlecode\.com\/svn\/trunk@)""" """([^"']+)["'].*$""", re.M) # Expression to pick tag and revision for bleeding edge tags. To be used with # output of 'svn log'. BLEEDING_EDGE_TAGS_RE = re.compile( r"A \/tags\/([^\s]+) \(from \/branches\/bleeding_edge\:(\d+)\)") OMAHA_PROXY_URL = "http://omahaproxy.appspot.com/" def SortBranches(branches): """Sort branches with version number names.""" return sorted(branches, key=SortingKey, reverse=True) def FilterDuplicatesAndReverse(cr_releases): """Returns the chromium releases in reverse order filtered by v8 revision duplicates. cr_releases is a list of [cr_rev, v8_hsh] reverse-sorted by cr_rev. """ last = "" result = [] for release in reversed(cr_releases): if last == release[1]: continue last = release[1] result.append(release) return result def BuildRevisionRanges(cr_releases): """Returns a mapping of v8 revision -> chromium ranges. The ranges are comma-separated, each range has the form R1:R2. The newest entry is the only one of the form R1, as there is no end range. cr_releases is a list of [cr_rev, v8_hsh] reverse-sorted by cr_rev. cr_rev either refers to a chromium commit position or a chromium branch number. """ range_lists = {} cr_releases = FilterDuplicatesAndReverse(cr_releases) # Visit pairs of cr releases from oldest to newest. for cr_from, cr_to in itertools.izip( cr_releases, itertools.islice(cr_releases, 1, None)): # Assume the chromium revisions are all different. assert cr_from[0] != cr_to[0] ran = "%s:%d" % (cr_from[0], int(cr_to[0]) - 1) # Collect the ranges in lists per revision. range_lists.setdefault(cr_from[1], []).append(ran) # Add the newest revision. if cr_releases: range_lists.setdefault(cr_releases[-1][1], []).append(cr_releases[-1][0]) # Stringify and comma-separate the range lists. return dict((hsh, ", ".join(ran)) for hsh, ran in range_lists.iteritems()) def MatchSafe(match): if match: return match.group(1) else: return "" class Preparation(Step): MESSAGE = "Preparation." def RunStep(self): self.CommonPrepare() self.PrepareBranch() class RetrieveV8Releases(Step): MESSAGE = "Retrieve all V8 releases." def ExceedsMax(self, releases): return (self._options.max_releases > 0 and len(releases) > self._options.max_releases) def GetMasterHashFromPush(self, title): return MatchSafe(PUSH_MSG_GIT_RE.match(title)) def GetMergedPatches(self, body): patches = MatchSafe(MERGE_MESSAGE_RE.search(body)) if not patches: patches = MatchSafe(ROLLBACK_MESSAGE_RE.search(body)) if patches: # Indicate reverted patches with a "-". patches = "-%s" % patches return patches def GetMergedPatchesGit(self, body): patches = [] for line in body.splitlines(): patch = MatchSafe(MERGE_MESSAGE_GIT_RE.match(line)) if patch: patches.append(patch) patch = MatchSafe(ROLLBACK_MESSAGE_GIT_RE.match(line)) if patch: patches.append("-%s" % patch) return ", ".join(patches) def GetReleaseDict( self, git_hash, master_position, master_hash, branch, version, patches, cl_body): revision = self.GetCommitPositionNumber(git_hash) return { # The cr commit position number on the branch. "revision": revision, # The git revision on the branch. "revision_git": git_hash, # The cr commit position number on master. "master_position": master_position, # The same for git. "master_hash": master_hash, # The branch name. "branch": branch, # The version for displaying in the form 3.26.3 or 3.26.3.12. "version": version, # The date of the commit. "date": self.GitLog(n=1, format="%ci", git_hash=git_hash), # Merged patches if available in the form 'r1234, r2345'. "patches_merged": patches, # Default for easier output formatting. "chromium_revision": "", # Default for easier output formatting. "chromium_branch": "", # Link to the CL on code review. Candiates pushes are not uploaded, # so this field will be populated below with the recent roll CL link. "review_link": MatchSafe(REVIEW_LINK_RE.search(cl_body)), # Link to the commit message on google code. "revision_link": ("https://code.google.com/p/v8/source/detail?r=%s" % revision), } def GetRelease(self, git_hash, branch): self.ReadAndPersistVersion() base_version = [self["major"], self["minor"], self["build"]] version = ".".join(base_version) body = self.GitLog(n=1, format="%B", git_hash=git_hash) patches = "" if self["patch"] != "0": version += ".%s" % self["patch"] if CHERRY_PICK_TITLE_GIT_RE.match(body.splitlines()[0]): patches = self.GetMergedPatchesGit(body) else: patches = self.GetMergedPatches(body) if SortingKey("4.2.69") <= SortingKey(version): master_hash = self.GetLatestReleaseBase(version=version) else: # Legacy: Before version 4.2.69, the master revision was determined # by commit message. title = self.GitLog(n=1, format="%s", git_hash=git_hash) master_hash = self.GetMasterHashFromPush(title) master_position = "" if master_hash: master_position = self.GetCommitPositionNumber(master_hash) return self.GetReleaseDict( git_hash, master_position, master_hash, branch, version, patches, body), self["patch"] def GetReleasesFromBranch(self, branch): self.GitReset(self.vc.RemoteBranch(branch)) if branch == self.vc.MasterBranch(): return self.GetReleasesFromMaster() releases = [] try: for git_hash in self.GitLog(format="%H").splitlines(): if VERSION_FILE not in self.GitChangedFiles(git_hash): continue if self.ExceedsMax(releases): break # pragma: no cover if not self.GitCheckoutFileSafe(VERSION_FILE, git_hash): break # pragma: no cover release, patch_level = self.GetRelease(git_hash, branch) releases.append(release) # Follow branches only until their creation point. # TODO(machenbach): This omits patches if the version file wasn't # manipulated correctly. Find a better way to detect the point where # the parent of the branch head leads to the trunk branch. if branch != self.vc.CandidateBranch() and patch_level == "0": break # Allow Ctrl-C interrupt. except (KeyboardInterrupt, SystemExit): # pragma: no cover pass # Clean up checked-out version file. self.GitCheckoutFileSafe(VERSION_FILE, "HEAD") return releases def GetReleaseFromRevision(self, revision): releases = [] try: if (VERSION_FILE not in self.GitChangedFiles(revision) or not self.GitCheckoutFileSafe(VERSION_FILE, revision)): print "Skipping revision %s" % revision return [] # pragma: no cover branches = map( str.strip, self.Git("branch -r --contains %s" % revision).strip().splitlines(), ) branch = "" for b in branches: if b.startswith("origin/"): branch = b.split("origin/")[1] break if b.startswith("branch-heads/"): branch = b.split("branch-heads/")[1] break else: print "Could not determine branch for %s" % revision release, _ = self.GetRelease(revision, branch) releases.append(release) # Allow Ctrl-C interrupt. except (KeyboardInterrupt, SystemExit): # pragma: no cover pass # Clean up checked-out version file. self.GitCheckoutFileSafe(VERSION_FILE, "HEAD") return releases def RunStep(self): self.GitCreateBranch(self._config["BRANCHNAME"]) releases = [] if self._options.branch == 'recent': # List every release from the last 7 days. revisions = self.GetRecentReleases(max_age=7 * DAY_IN_SECONDS) for revision in revisions: releases += self.GetReleaseFromRevision(revision) elif self._options.branch == 'all': # pragma: no cover # Retrieve the full release history. for branch in self.vc.GetBranches(): releases += self.GetReleasesFromBranch(branch) releases += self.GetReleasesFromBranch(self.vc.CandidateBranch()) releases += self.GetReleasesFromBranch(self.vc.MasterBranch()) else: # pragma: no cover # Retrieve history for a specified branch. assert self._options.branch in (self.vc.GetBranches() + [self.vc.CandidateBranch(), self.vc.MasterBranch()]) releases += self.GetReleasesFromBranch(self._options.branch) self["releases"] = sorted(releases, key=lambda r: SortingKey(r["version"]), reverse=True) class UpdateChromiumCheckout(Step): MESSAGE = "Update the chromium checkout." def RunStep(self): cwd = self._options.chromium self.GitFetchOrigin("+refs/heads/*:refs/remotes/origin/*", "+refs/branch-heads/*:refs/remotes/branch-heads/*", cwd=cwd) # Update v8 checkout in chromium. self.GitFetchOrigin(cwd=os.path.join(cwd, "v8")) def ConvertToCommitNumber(step, revision): # Simple check for git hashes. if revision.isdigit() and len(revision) < 8: return revision return step.GetCommitPositionNumber( revision, cwd=os.path.join(step._options.chromium, "v8")) class RetrieveChromiumV8Releases(Step): MESSAGE = "Retrieve V8 releases from Chromium DEPS." def RunStep(self): cwd = self._options.chromium # All v8 revisions we are interested in. releases_dict = dict((r["revision_git"], r) for r in self["releases"]) cr_releases = [] count_past_last_v8 = 0 try: for git_hash in self.GitLog( format="%H", grep="V8", branch="origin/master", path="DEPS", cwd=cwd).splitlines(): deps = self.GitShowFile(git_hash, "DEPS", cwd=cwd) match = DEPS_RE.search(deps) if match: cr_rev = self.GetCommitPositionNumber(git_hash, cwd=cwd) if cr_rev: v8_hsh = match.group(1) cr_releases.append([cr_rev, v8_hsh]) if count_past_last_v8: count_past_last_v8 += 1 # pragma: no cover if count_past_last_v8 > 20: break # pragma: no cover # Stop as soon as we find a v8 revision that we didn't fetch in the # v8-revision-retrieval part above (i.e. a revision that's too old). # Just iterate a few more times in case there were reverts. if v8_hsh not in releases_dict: count_past_last_v8 += 1 # pragma: no cover # Allow Ctrl-C interrupt. except (KeyboardInterrupt, SystemExit): # pragma: no cover pass # Add the chromium ranges to the v8 candidates and master releases. all_ranges = BuildRevisionRanges(cr_releases) for hsh, ranges in all_ranges.iteritems(): releases_dict.get(hsh, {})["chromium_revision"] = ranges # TODO(machenbach): Unify common code with method above. class RetrieveChromiumBranches(Step): MESSAGE = "Retrieve Chromium branch information." def RunStep(self): cwd = self._options.chromium # All v8 revisions we are interested in. releases_dict = dict((r["revision_git"], r) for r in self["releases"]) # Filter out irrelevant branches. branches = filter(lambda r: re.match(r"branch-heads/\d+", r), self.GitRemotes(cwd=cwd)) # Transform into pure branch numbers. branches = map(lambda r: int(re.match(r"branch-heads/(\d+)", r).group(1)), branches) branches = sorted(branches, reverse=True) cr_branches = [] count_past_last_v8 = 0 try: for branch in branches: deps = self.GitShowFile( "refs/branch-heads/%d" % branch, "DEPS", cwd=cwd) match = DEPS_RE.search(deps) if match: v8_hsh = match.group(1) cr_branches.append([str(branch), v8_hsh]) if count_past_last_v8: count_past_last_v8 += 1 # pragma: no cover if count_past_last_v8 > 20: break # pragma: no cover # Stop as soon as we find a v8 revision that we didn't fetch in the # v8-revision-retrieval part above (i.e. a revision that's too old). # Just iterate a few more times in case there were reverts. if v8_hsh not in releases_dict: count_past_last_v8 += 1 # pragma: no cover # Allow Ctrl-C interrupt. except (KeyboardInterrupt, SystemExit): # pragma: no cover pass # Add the chromium branches to the v8 candidate releases. all_ranges = BuildRevisionRanges(cr_branches) for revision, ranges in all_ranges.iteritems(): releases_dict.get(revision, {})["chromium_branch"] = ranges class RetrieveInformationOnChromeReleases(Step): MESSAGE = 'Retrieves relevant information on the latest Chrome releases' def Run(self): params = None result_raw = self.ReadURL( OMAHA_PROXY_URL + "all.json", params, wait_plan=[5, 20] ) recent_releases = json.loads(result_raw) canaries = [] for current_os in recent_releases: for current_version in current_os["versions"]: if current_version["channel"] != "canary": continue current_candidate = self._CreateCandidate(current_version) canaries.append(current_candidate) chrome_releases = {"canaries": canaries} self["chrome_releases"] = chrome_releases def _GetGitHashForV8Version(self, v8_version): if v8_version == "N/A": return "" if v8_version.split(".")[3]== "0": return self.GitGetHashOfTag(v8_version[:-2]) return self.GitGetHashOfTag(v8_version) def _CreateCandidate(self, current_version): params = None url_to_call = (OMAHA_PROXY_URL + "v8.json?version=" + current_version["previous_version"]) result_raw = self.ReadURL( url_to_call, params, wait_plan=[5, 20] ) previous_v8_version = json.loads(result_raw)["v8_version"] v8_previous_version_hash = self._GetGitHashForV8Version(previous_v8_version) current_v8_version = current_version["v8_version"] v8_version_hash = self._GetGitHashForV8Version(current_v8_version) current_candidate = { "chrome_version": current_version["version"], "os": current_version["os"], "release_date": current_version["current_reldate"], "v8_version": current_v8_version, "v8_version_hash": v8_version_hash, "v8_previous_version": previous_v8_version, "v8_previous_version_hash": v8_previous_version_hash, } return current_candidate class CleanUp(Step): MESSAGE = "Clean up." def RunStep(self): self.CommonCleanup() class WriteOutput(Step): MESSAGE = "Print output." def Run(self): output = { "releases": self["releases"], "chrome_releases": self["chrome_releases"], } if self._options.csv: with open(self._options.csv, "w") as f: writer = csv.DictWriter(f, ["version", "branch", "revision", "chromium_revision", "patches_merged"], restval="", extrasaction="ignore") for release in self["releases"]: writer.writerow(release) if self._options.json: with open(self._options.json, "w") as f: f.write(json.dumps(output)) if not self._options.csv and not self._options.json: print output # pragma: no cover class Releases(ScriptsBase): def _PrepareOptions(self, parser): parser.add_argument("-b", "--branch", default="recent", help=("The branch to analyze. If 'all' is specified, " "analyze all branches. If 'recent' (default) " "is specified, track beta, stable and " "candidates.")) parser.add_argument("-c", "--chromium", help=("The path to your Chromium src/ " "directory to automate the V8 roll.")) parser.add_argument("--csv", help="Path to a CSV file for export.") parser.add_argument("-m", "--max-releases", type=int, default=0, help="The maximum number of releases to track.") parser.add_argument("--json", help="Path to a JSON file for export.") def _ProcessOptions(self, options): # pragma: no cover options.force_readline_defaults = True return True def _Config(self): return { "BRANCHNAME": "retrieve-v8-releases", "PERSISTFILE_BASENAME": "/tmp/v8-releases-tempfile", } def _Steps(self): return [ Preparation, RetrieveV8Releases, UpdateChromiumCheckout, RetrieveChromiumV8Releases, RetrieveChromiumBranches, RetrieveInformationOnChromeReleases, CleanUp, WriteOutput, ] if __name__ == "__main__": # pragma: no cover sys.exit(Releases().Run()) node-v4.2.6/deps/v8/tools/release/script_test.py000755 000766 000024 00000004366 12650222326 021747 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2014 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Wraps test execution with a coverage analysis. To get the best speed, the # native python coverage version >= 3.7.1 should be installed. import coverage import os import unittest import sys def Main(argv): script_path = os.path.dirname(os.path.abspath(__file__)) cov = coverage.coverage(include=([os.path.join(script_path, '*.py')])) cov.start() import test_scripts alltests = map(unittest.TestLoader().loadTestsFromTestCase, [ test_scripts.ToplevelTest, test_scripts.ScriptTest, test_scripts.SystemTest, ]) unittest.TextTestRunner(verbosity=2).run(unittest.TestSuite(alltests)) cov.stop() print cov.report() if __name__ == '__main__': sys.exit(Main(sys.argv)) node-v4.2.6/deps/v8/tools/release/search_related_commits.py000755 000766 000024 00000014536 12650222326 024104 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import argparse import operator import os import re from sets import Set from subprocess import Popen, PIPE import sys def search_all_related_commits( git_working_dir, start_hash, until, separator, verbose=False): all_commits_raw = _find_commits_inbetween( start_hash, until, git_working_dir, verbose) if verbose: print "All commits between and : " + all_commits_raw # Adding start hash too all_commits = [start_hash] all_commits.extend(all_commits_raw.splitlines()) all_related_commits = {} already_treated_commits = Set([]) for commit in all_commits: if commit in already_treated_commits: continue related_commits = _search_related_commits( git_working_dir, commit, until, separator, verbose) if len(related_commits) > 0: all_related_commits[commit] = related_commits already_treated_commits.update(related_commits) already_treated_commits.update(commit) return all_related_commits def _search_related_commits( git_working_dir, start_hash, until, separator, verbose=False): if separator: commits_between = _find_commits_inbetween( start_hash, separator, git_working_dir, verbose) if commits_between == "": return [] # Extract commit position original_message = _git_execute( git_working_dir, ["show", "-s", "--format=%B", start_hash], verbose) title = original_message.splitlines()[0] matches = re.search("(\{#)([0-9]*)(\})", original_message) if not matches: return [] commit_position = matches.group(2) if verbose: print "1.) Commit position to look for: " + commit_position search_range = start_hash + ".." + until def git_args(grep_pattern): return [ "log", "--reverse", "--grep=" + grep_pattern, "--format=%H", search_range, ] found_by_hash = _git_execute( git_working_dir, git_args(start_hash), verbose).strip() if verbose: print "2.) Found by hash: " + found_by_hash found_by_commit_pos = _git_execute( git_working_dir, git_args(commit_position), verbose).strip() if verbose: print "3.) Found by commit position: " + found_by_commit_pos # Replace brackets or else they are wrongly interpreted by --grep title = title.replace("[", "\\[") title = title.replace("]", "\\]") found_by_title = _git_execute( git_working_dir, git_args(title), verbose).strip() if verbose: print "4.) Found by title: " + found_by_title hits = ( _convert_to_array(found_by_hash) + _convert_to_array(found_by_commit_pos) + _convert_to_array(found_by_title)) hits = _remove_duplicates(hits) if separator: for current_hit in hits: commits_between = _find_commits_inbetween( separator, current_hit, git_working_dir, verbose) if commits_between != "": return hits return [] return hits def _find_commits_inbetween(start_hash, end_hash, git_working_dir, verbose): commits_between = _git_execute( git_working_dir, ["rev-list", "--reverse", start_hash + ".." + end_hash], verbose) return commits_between.strip() def _convert_to_array(string_of_hashes): return string_of_hashes.splitlines() def _remove_duplicates(array): no_duplicates = [] for current in array: if not current in no_duplicates: no_duplicates.append(current) return no_duplicates def _git_execute(working_dir, args, verbose=False): command = ["git", "-C", working_dir] + args if verbose: print "Git working dir: " + working_dir print "Executing git command:" + str(command) p = Popen(args=command, stdin=PIPE, stdout=PIPE, stderr=PIPE) output, err = p.communicate() rc = p.returncode if rc != 0: raise Exception(err) if verbose: print "Git return value: " + output return output def _pretty_print_entry(hash, git_dir, pre_text, verbose): text_to_print = _git_execute( git_dir, ["show", "--quiet", "--date=iso", hash, "--format=%ad # %H # %s"], verbose) return pre_text + text_to_print.strip() def main(options): all_related_commits = search_all_related_commits( options.git_dir, options.of[0], options.until[0], options.separator, options.verbose) sort_key = lambda x: ( _git_execute( options.git_dir, ["show", "--quiet", "--date=iso", x, "--format=%ad"], options.verbose)).strip() high_level_commits = sorted(all_related_commits.keys(), key=sort_key) for current_key in high_level_commits: if options.prettyprint: yield _pretty_print_entry( current_key, options.git_dir, "+", options.verbose) else: yield "+" + current_key found_commits = all_related_commits[current_key] for current_commit in found_commits: if options.prettyprint: yield _pretty_print_entry( current_commit, options.git_dir, "| ", options.verbose) else: yield "| " + current_commit if __name__ == "__main__": # pragma: no cover parser = argparse.ArgumentParser( "This tool analyzes the commit range between and . " "It finds commits which belong together e.g. Implement/Revert pairs and " "Implement/Port/Revert triples. All supplied hashes need to be " "from the same branch e.g. master.") parser.add_argument("-g", "--git-dir", required=False, default=".", help="The path to your git working directory.") parser.add_argument("--verbose", action="store_true", help="Enables a very verbose output") parser.add_argument("of", nargs=1, help="Hash of the commit to be searched.") parser.add_argument("until", nargs=1, help="Commit when searching should stop") parser.add_argument("--separator", required=False, help="The script will only list related commits " "which are separated by hash <--separator>.") parser.add_argument("--prettyprint", action="store_true", help="Pretty prints the output") args = sys.argv[1:] options = parser.parse_args(args) for current_line in main(options): print current_line node-v4.2.6/deps/v8/tools/release/test_scripts.py000644 000766 000024 00000164715 12650222326 022134 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import shutil import tempfile import traceback import unittest import auto_push from auto_push import LastReleaseBailout import auto_roll import common_includes from common_includes import * import create_release from create_release import CreateRelease import merge_to_branch from merge_to_branch import * import push_to_candidates from push_to_candidates import * import chromium_roll from chromium_roll import ChromiumRoll import releases from releases import Releases from auto_tag import AutoTag TEST_CONFIG = { "DEFAULT_CWD": None, "BRANCHNAME": "test-prepare-push", "CANDIDATESBRANCH": "test-candidates-push", "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-candidates-tempfile", "CHANGELOG_ENTRY_FILE": "/tmp/test-v8-push-to-candidates-tempfile-changelog-entry", "PATCH_FILE": "/tmp/test-v8-push-to-candidates-tempfile-patch", "COMMITMSG_FILE": "/tmp/test-v8-push-to-candidates-tempfile-commitmsg", "CHROMIUM": "/tmp/test-v8-push-to-candidates-tempfile-chromium", "SETTINGS_LOCATION": None, "ALREADY_MERGING_SENTINEL_FILE": "/tmp/test-merge-to-branch-tempfile-already-merging", "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch", } AUTO_PUSH_ARGS = [ "-a", "author@chromium.org", "-r", "reviewer@chromium.org", ] class ToplevelTest(unittest.TestCase): def testSortBranches(self): S = releases.SortBranches self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2]) self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2]) self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2]) def testFilterDuplicatesAndReverse(self): F = releases.FilterDuplicatesAndReverse self.assertEquals([], F([])) self.assertEquals([["100", "10"]], F([["100", "10"]])) self.assertEquals([["99", "9"], ["100", "10"]], F([["100", "10"], ["99", "9"]])) self.assertEquals([["98", "9"], ["100", "10"]], F([["100", "10"], ["99", "9"], ["98", "9"]])) self.assertEquals([["98", "9"], ["99", "10"]], F([["100", "10"], ["99", "10"], ["98", "9"]])) def testBuildRevisionRanges(self): B = releases.BuildRevisionRanges self.assertEquals({}, B([])) self.assertEquals({"10": "100"}, B([["100", "10"]])) self.assertEquals({"10": "100", "9": "99:99"}, B([["100", "10"], ["99", "9"]])) self.assertEquals({"10": "100", "9": "97:99"}, B([["100", "10"], ["98", "9"], ["97", "9"]])) self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"}, B([["100", "10"], ["99", "9"], ["91", "3"]])) self.assertEquals({"13": "101", "12": "100:100", "9": "94:97", "3": "91:93, 98:99"}, B([["101", "13"], ["100", "12"], ["98", "3"], ["94", "9"], ["91", "3"]])) def testMakeComment(self): self.assertEquals("# Line 1\n# Line 2\n#", MakeComment(" Line 1\n Line 2\n")) self.assertEquals("#Line 1\n#Line 2", MakeComment("Line 1\n Line 2")) def testStripComments(self): self.assertEquals(" Line 1\n Line 3\n", StripComments(" Line 1\n# Line 2\n Line 3\n#\n")) self.assertEquals("\nLine 2 ### Test\n #", StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #")) def testMakeChangeLogBodySimple(self): commits = [ ["Title text 1", "Title text 1\n\nBUG=\n", "author1@chromium.org"], ["Title text 2.", "Title text 2\n\nBUG=1234\n", "author2@chromium.org"], ] self.assertEquals(" Title text 1.\n" " (author1@chromium.org)\n\n" " Title text 2 (Chromium issue 1234).\n" " (author2@chromium.org)\n\n", MakeChangeLogBody(commits)) def testMakeChangeLogBodyEmpty(self): self.assertEquals("", MakeChangeLogBody([])) def testMakeChangeLogBodyAutoFormat(self): commits = [ ["Title text 1!", "Title text 1\nLOG=y\nBUG=\n", "author1@chromium.org"], ["Title text 2", "Title text 2\n\nBUG=1234\n", "author2@chromium.org"], ["Title text 3", "Title text 3\n\nBUG=1234\nLOG = Yes\n", "author3@chromium.org"], ["Title text 3", "Title text 4\n\nBUG=1234\nLOG=\n", "author4@chromium.org"], ] self.assertEquals(" Title text 1.\n\n" " Title text 3 (Chromium issue 1234).\n\n", MakeChangeLogBody(commits, True)) def testRegressWrongLogEntryOnTrue(self): body = """ Check elimination: Learn from if(CompareMap(x)) on true branch. BUG= R=verwaest@chromium.org Committed: https://code.google.com/p/v8/source/detail?r=18210 """ self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True)) def testMakeChangeLogBugReferenceEmpty(self): self.assertEquals("", MakeChangeLogBugReference("")) self.assertEquals("", MakeChangeLogBugReference("LOG=")) self.assertEquals("", MakeChangeLogBugReference(" BUG =")) self.assertEquals("", MakeChangeLogBugReference("BUG=none\t")) def testMakeChangeLogBugReferenceSimple(self): self.assertEquals("(issue 987654)", MakeChangeLogBugReference("BUG = v8:987654")) self.assertEquals("(Chromium issue 987654)", MakeChangeLogBugReference("BUG=987654 ")) def testMakeChangeLogBugReferenceFromBody(self): self.assertEquals("(Chromium issue 1234567)", MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n" " BUG=\tchromium:1234567\t\n" "R=somebody\n")) def testMakeChangeLogBugReferenceMultiple(self): # All issues should be sorted and grouped. Multiple references to the same # issue should be filtered. self.assertEquals("(issues 123, 234, Chromium issue 345)", MakeChangeLogBugReference("Title\n\n" "BUG=v8:234\n" " BUG\t= 345, \tv8:234,\n" "BUG=v8:123\n" "R=somebody\n")) self.assertEquals("(Chromium issues 123, 234)", MakeChangeLogBugReference("Title\n\n" "BUG=234,,chromium:123 \n" "R=somebody\n")) self.assertEquals("(Chromium issues 123, 234)", MakeChangeLogBugReference("Title\n\n" "BUG=chromium:234, , 123\n" "R=somebody\n")) self.assertEquals("(issues 345, 456)", MakeChangeLogBugReference("Title\n\n" "\t\tBUG=v8:345,v8:456\n" "R=somebody\n")) self.assertEquals("(issue 123, Chromium issues 345, 456)", MakeChangeLogBugReference("Title\n\n" "BUG=chromium:456\n" "BUG = none\n" "R=somebody\n" "BUG=456,v8:123, 345")) # TODO(machenbach): These test don't make much sense when the formatting is # done later. def testMakeChangeLogBugReferenceLong(self): # -----------------00--------10--------20--------30-------- self.assertEquals("(issues 234, 1234567890, 1234567" "8901234567890, Chromium issues 12345678," " 123456789)", MakeChangeLogBugReference("BUG=v8:234\n" "BUG=v8:1234567890\n" "BUG=v8:12345678901234567890\n" "BUG=123456789\n" "BUG=12345678\n")) # -----------------00--------10--------20--------30-------- self.assertEquals("(issues 234, 1234567890, 1234567" "8901234567890, Chromium issues" " 123456789, 1234567890)", MakeChangeLogBugReference("BUG=v8:234\n" "BUG=v8:12345678901234567890\n" "BUG=v8:1234567890\n" "BUG=123456789\n" "BUG=1234567890\n")) # -----------------00--------10--------20--------30-------- self.assertEquals("(Chromium issues 234, 1234567890" ", 12345678901234567, " "1234567890123456789)", MakeChangeLogBugReference("BUG=234\n" "BUG=12345678901234567\n" "BUG=1234567890123456789\n" "BUG=1234567890\n")) def Cmd(*args, **kwargs): """Convenience function returning a shell command test expectation.""" return { "name": "command", "args": args, "ret": args[-1], "cb": kwargs.get("cb"), "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]), } def RL(text, cb=None): """Convenience function returning a readline test expectation.""" return { "name": "readline", "args": [], "ret": text, "cb": cb, "cwd": None, } def URL(*args, **kwargs): """Convenience function returning a readurl test expectation.""" return { "name": "readurl", "args": args[:-1], "ret": args[-1], "cb": kwargs.get("cb"), "cwd": None, } class SimpleMock(object): def __init__(self): self._recipe = [] self._index = -1 def Expect(self, recipe): self._recipe = recipe def Call(self, name, *args, **kwargs): # pragma: no cover self._index += 1 try: expected_call = self._recipe[self._index] except IndexError: raise NoRetryException("Calling %s %s" % (name, " ".join(args))) if not isinstance(expected_call, dict): raise NoRetryException("Found wrong expectation type for %s %s" % (name, " ".join(args))) if expected_call["name"] != name: raise NoRetryException("Expected action: %s %s - Actual: %s" % (expected_call["name"], expected_call["args"], name)) # Check if the given working directory matches the expected one. if expected_call["cwd"] != kwargs.get("cwd"): raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" % (expected_call["cwd"], expected_call["name"], expected_call["args"], kwargs.get("cwd"))) # The number of arguments in the expectation must match the actual # arguments. if len(args) > len(expected_call['args']): raise NoRetryException("When calling %s with arguments, the " "expectations must consist of at least as many arguments." % name) # Compare expected and actual arguments. for (expected_arg, actual_arg) in zip(expected_call['args'], args): if expected_arg != actual_arg: raise NoRetryException("Expected: %s - Actual: %s" % (expected_arg, actual_arg)) # The expected call contains an optional callback for checking the context # at the time of the call. if expected_call['cb']: try: expected_call['cb']() except: tb = traceback.format_exc() raise NoRetryException("Caught exception from callback: %s" % tb) # If the return value is an exception, raise it instead of returning. if isinstance(expected_call['ret'], Exception): raise expected_call['ret'] return expected_call['ret'] def AssertFinished(self): # pragma: no cover if self._index < len(self._recipe) -1: raise NoRetryException("Called mock too seldom: %d vs. %d" % (self._index, len(self._recipe))) class ScriptTest(unittest.TestCase): def MakeEmptyTempFile(self): handle, name = tempfile.mkstemp() os.close(handle) self._tmp_files.append(name) return name def MakeEmptyTempDirectory(self): name = tempfile.mkdtemp() self._tmp_files.append(name) return name def WriteFakeVersionFile(self, major=3, minor=22, build=4, patch=0): version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE) if not os.path.exists(os.path.dirname(version_file)): os.makedirs(os.path.dirname(version_file)) with open(version_file, "w") as f: f.write(" // Some line...\n") f.write("\n") f.write("#define V8_MAJOR_VERSION %s\n" % major) f.write("#define V8_MINOR_VERSION %s\n" % minor) f.write("#define V8_BUILD_NUMBER %s\n" % build) f.write("#define V8_PATCH_LEVEL %s\n" % patch) f.write(" // Some line...\n") f.write("#define V8_IS_CANDIDATE_VERSION 0\n") def MakeStep(self): """Convenience wrapper.""" options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([]) return MakeStep(step_class=Step, state=self._state, config=TEST_CONFIG, side_effect_handler=self, options=options) def RunStep(self, script=PushToCandidates, step_class=Step, args=None): """Convenience wrapper.""" args = args if args is not None else ["-m"] return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args) def Call(self, fun, *args, **kwargs): print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs)) def Command(self, cmd, args="", prefix="", pipe=True, cwd=None): print "%s %s" % (cmd, args) print "in %s" % cwd return self._mock.Call("command", cmd + " " + args, cwd=cwd) def ReadLine(self): return self._mock.Call("readline") def ReadURL(self, url, params): if params is not None: return self._mock.Call("readurl", url, params) else: return self._mock.Call("readurl", url) def Sleep(self, seconds): pass def GetDate(self): return "1999-07-31" def GetUTCStamp(self): return "1000000" def Expect(self, *args): """Convenience wrapper.""" self._mock.Expect(*args) def setUp(self): self._mock = SimpleMock() self._tmp_files = [] self._state = {} TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory() def tearDown(self): if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]): shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"]) # Clean up temps. Doesn't work automatically. for name in self._tmp_files: if os.path.isfile(name): os.remove(name) if os.path.isdir(name): shutil.rmtree(name) self._mock.AssertFinished() def testGitMock(self): self.Expect([Cmd("git --version", "git version 1.2.3"), Cmd("git dummy", "")]) self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version")) self.assertEquals("", self.MakeStep().Git("dummy")) def testCommonPrepareDefault(self): self.Expect([ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), RL("Y"), Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), ]) self.MakeStep().CommonPrepare() self.MakeStep().PrepareBranch() def testCommonPrepareNoConfirm(self): self.Expect([ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), RL("n"), ]) self.MakeStep().CommonPrepare() self.assertRaises(Exception, self.MakeStep().PrepareBranch) def testCommonPrepareDeleteBranchFailure(self): self.Expect([ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), RL("Y"), Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None), ]) self.MakeStep().CommonPrepare() self.assertRaises(Exception, self.MakeStep().PrepareBranch) def testInitialEnvironmentChecks(self): TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) os.environ["EDITOR"] = "vi" self.Expect([ Cmd("which vi", "/usr/bin/vi"), ]) self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"]) def testTagTimeout(self): self.Expect([ Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), ]) args = ["--branch", "candidates", "ab12345"] self._state["version"] = "tag_name" self._state["commit_title"] = "Title" self.assertRaises(Exception, lambda: self.RunStep(MergeToBranch, TagRevision, args)) def testReadAndPersistVersion(self): self.WriteFakeVersionFile(build=5) step = self.MakeStep() step.ReadAndPersistVersion() self.assertEquals("3", step["major"]) self.assertEquals("22", step["minor"]) self.assertEquals("5", step["build"]) self.assertEquals("0", step["patch"]) def testRegex(self): self.assertEqual("(issue 321)", re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321")) self.assertEqual("(Chromium issue 321)", re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321")) cl = " too little\n\ttab\ttab\n too much\n trailing " cl = MSub(r"\t", r" ", cl) cl = MSub(r"^ {1,7}([^ ])", r" \1", cl) cl = MSub(r"^ {9,80}([^ ])", r" \1", cl) cl = MSub(r" +$", r"", cl) self.assertEqual(" too little\n" " tab tab\n" " too much\n" " trailing", cl) self.assertEqual("//\n#define V8_BUILD_NUMBER 3\n", MSub(r"(?<=#define V8_BUILD_NUMBER)(?P\s+)\d*$", r"\g3", "//\n#define V8_BUILD_NUMBER 321\n")) def testPreparePushRevision(self): # Tests the default push hash used when the --revision option is not set. self.Expect([ Cmd("git log -1 --format=%H HEAD", "push_hash") ]) self.RunStep(PushToCandidates, PreparePushRevision) self.assertEquals("push_hash", self._state["push_hash"]) def testPrepareChangeLog(self): self.WriteFakeVersionFile() TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() self.Expect([ Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"), Cmd("git log -1 --format=%s rev1", "Title text 1"), Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"), Cmd("git log -1 --format=%an rev1", "author1@chromium.org"), Cmd("git log -1 --format=%s rev2", "Title text 2."), Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"), Cmd("git log -1 --format=%an rev2", "author2@chromium.org"), Cmd("git log -1 --format=%s rev3", "Title text 3"), Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"), Cmd("git log -1 --format=%an rev3", "author3@chromium.org"), Cmd("git log -1 --format=%s rev4", "Title text 4"), Cmd("git log -1 --format=%B rev4", ("Title\n\nBUG=456\nLOG=Y\n\n" "Review URL: https://codereview.chromium.org/9876543210\n")), URL("https://codereview.chromium.org/9876543210/description", "Title\n\nBUG=456\nLOG=N\n\n"), Cmd("git log -1 --format=%an rev4", "author4@chromium.org"), ]) self._state["last_push_master"] = "1234" self._state["push_hash"] = "push_hash" self._state["version"] = "3.22.5" self.RunStep(PushToCandidates, PrepareChangeLog) actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]) expected_cl = """1999-07-31: Version 3.22.5 Title text 1. Title text 3 (Chromium issue 321). Performance and stability improvements on all platforms. # # The change log above is auto-generated. Please review if all relevant # commit messages from the list below are included. # All lines starting with # will be stripped. # # Title text 1. # (author1@chromium.org) # # Title text 2 (Chromium issue 123). # (author2@chromium.org) # # Title text 3 (Chromium issue 321). # (author3@chromium.org) # # Title text 4 (Chromium issue 456). # (author4@chromium.org) # #""" self.assertEquals(expected_cl, actual_cl) def testEditChangeLog(self): TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"]) os.environ["EDITOR"] = "vi" self.Expect([ RL(""), # Open editor. Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""), ]) self.RunStep(PushToCandidates, EditChangeLog) self.assertEquals("New\n Lines", FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])) TAGS = """ 4425.0 0.0.0.0 3.9.6 3.22.4 test_tag """ # Version as tag: 3.22.4.0. Version on master: 3.22.6. # Make sure that the latest version is 3.22.6.0. def testIncrementVersion(self): self.Expect([ Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git tag", self.TAGS), Cmd("git checkout -f origin/master -- include/v8-version.h", "", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)), ]) self.RunStep(PushToCandidates, IncrementVersion) self.assertEquals("3", self._state["new_major"]) self.assertEquals("22", self._state["new_minor"]) self.assertEquals("7", self._state["new_build"]) self.assertEquals("0", self._state["new_patch"]) def _TestSquashCommits(self, change_log, expected_msg): TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f: f.write(change_log) self.Expect([ Cmd("git diff origin/candidates hash1", "patch content"), ]) self._state["push_hash"] = "hash1" self._state["date"] = "1999-11-11" self.RunStep(PushToCandidates, SquashCommits) self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg) patch = FileToText(TEST_CONFIG["PATCH_FILE"]) self.assertTrue(re.search(r"patch content", patch)) def testSquashCommitsUnformatted(self): change_log = """1999-11-11: Version 3.22.5 Log text 1. Chromium issue 12345 Performance and stability improvements on all platforms.\n""" commit_msg = """Version 3.22.5 (based on hash1) Log text 1. Chromium issue 12345 Performance and stability improvements on all platforms.""" self._TestSquashCommits(change_log, commit_msg) def testSquashCommitsFormatted(self): change_log = """1999-11-11: Version 3.22.5 Long commit message that fills more than 80 characters (Chromium issue 12345). Performance and stability improvements on all platforms.\n""" commit_msg = """Version 3.22.5 (based on hash1) Long commit message that fills more than 80 characters (Chromium issue 12345). Performance and stability improvements on all platforms.""" self._TestSquashCommits(change_log, commit_msg) def testSquashCommitsQuotationMarks(self): change_log = """Line with "quotation marks".\n""" commit_msg = """Line with "quotation marks".""" self._TestSquashCommits(change_log, commit_msg) def testBootstrapper(self): work_dir = self.MakeEmptyTempDirectory() class FakeScript(ScriptsBase): def _Steps(self): return [] # Use the test configuration without the fake testing default work dir. fake_config = dict(TEST_CONFIG) del(fake_config["DEFAULT_CWD"]) self.Expect([ Cmd("fetch v8", "", cwd=work_dir), ]) FakeScript(fake_config, self).Run(["--work-dir", work_dir]) def _PushToCandidates(self, force=False, manual=False): TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) # The version file on master has build level 5, while the version # file from candidates has build level 4. self.WriteFakeVersionFile(build=5) TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() master_change_log = "2014-03-17: Sentinel\n" TextToFile(master_change_log, os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) os.environ["EDITOR"] = "vi" commit_msg_squashed = """Version 3.22.5 (squashed - based on push_hash) Log text 1 (issue 321). Performance and stability improvements on all platforms.""" commit_msg = """Version 3.22.5 (based on push_hash) Log text 1 (issue 321). Performance and stability improvements on all platforms.""" def ResetChangeLog(): """On 'git co -b new_branch origin/candidates', and 'git checkout -- ChangeLog', the ChangLog will be reset to its content on candidates.""" candidates_change_log = """1999-04-05: Version 3.22.4 Performance and stability improvements on all platforms.\n""" TextToFile(candidates_change_log, os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) def ResetToCandidates(): ResetChangeLog() self.WriteFakeVersionFile() def CheckVersionCommit(): commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) self.assertEquals(commit_msg, commit) version = FileToText( os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version)) self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version)) self.assertTrue( re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) # Check that the change log on the candidates branch got correctly # modified. change_log = FileToText( os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) self.assertEquals( """1999-07-31: Version 3.22.5 Log text 1 (issue 321). Performance and stability improvements on all platforms. 1999-04-05: Version 3.22.4 Performance and stability improvements on all platforms.\n""", change_log) force_flag = " -f" if not manual else "" expectations = [] if not force: expectations.append(Cmd("which vi", "/usr/bin/vi")) expectations += [ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* branch2\n"), Cmd("git branch", " branch1\n* branch2\n"), Cmd(("git new-branch %s --upstream origin/master" % TEST_CONFIG["BRANCHNAME"]), ""), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git tag", self.TAGS), Cmd("git checkout -f origin/master -- include/v8-version.h", "", cb=self.WriteFakeVersionFile), Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), Cmd("git log -1 --format=%s release_hash", "Version 3.22.4 (based on abc3)\n"), Cmd("git log --format=%H abc3..push_hash", "rev1\n"), Cmd("git log -1 --format=%s rev1", "Log text 1.\n"), Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"), Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"), ] if manual: expectations.append(RL("")) # Open editor. if not force: expectations.append( Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "")) expectations += [ Cmd("git fetch", ""), Cmd("git checkout -f origin/master", ""), Cmd("git diff origin/candidates push_hash", "patch content\n"), Cmd(("git new-branch %s --upstream origin/candidates" % TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates), Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""), Cmd("git checkout -f origin/candidates -- ChangeLog", "", cb=ResetChangeLog), Cmd("git checkout -f origin/candidates -- include/v8-version.h", "", cb=self.WriteFakeVersionFile), Cmd("git commit -am \"%s\"" % commit_msg_squashed, ""), ] if manual: expectations.append(RL("Y")) # Sanity check. expectations += [ Cmd("git cl land -f --bypass-hooks", ""), Cmd("git checkout -f master", ""), Cmd("git fetch", ""), Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""), Cmd(("git new-branch %s --upstream origin/candidates" % TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates), Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "", cb=CheckVersionCommit), Cmd("git cl land -f --bypass-hooks", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=" "\"Version 3.22.5 (based on push_hash)\"" " origin/candidates", "hsh_to_tag"), Cmd("git tag 3.22.5 hsh_to_tag", ""), Cmd("git push origin 3.22.5", ""), Cmd("git checkout -f origin/master", ""), Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""), ] self.Expect(expectations) args = ["-a", "author@chromium.org", "--revision", "push_hash"] if force: args.append("-f") if manual: args.append("-m") else: args += ["-r", "reviewer@chromium.org"] PushToCandidates(TEST_CONFIG, self).Run(args) cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) # Note: The version file is on build number 5 again in the end of this test # since the git command that merges to master is mocked out. def testPushToCandidatesManual(self): self._PushToCandidates(manual=True) def testPushToCandidatesSemiAutomatic(self): self._PushToCandidates() def testPushToCandidatesForced(self): self._PushToCandidates(force=True) def testCreateRelease(self): TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) # The version file on master has build level 5. self.WriteFakeVersionFile(build=5) master_change_log = "2014-03-17: Sentinel\n" TextToFile(master_change_log, os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) commit_msg = """Version 3.22.5 Log text 1 (issue 321). Performance and stability improvements on all platforms.""" def ResetChangeLog(): last_change_log = """1999-04-05: Version 3.22.4 Performance and stability improvements on all platforms.\n""" TextToFile(last_change_log, os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) def CheckVersionCommit(): commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) self.assertEquals(commit_msg, commit) version = FileToText( os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version)) self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version)) self.assertTrue( re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) # Check that the change log on the candidates branch got correctly # modified. change_log = FileToText( os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) self.assertEquals( """1999-07-31: Version 3.22.5 Log text 1 (issue 321). Performance and stability improvements on all platforms. 1999-04-05: Version 3.22.4 Performance and stability improvements on all platforms.\n""", change_log) expectations = [ Cmd("git fetch origin " "+refs/heads/*:refs/heads/* " "+refs/pending/*:refs/pending/* " "+refs/pending-tags/*:refs/pending-tags/*", ""), Cmd("git checkout -f origin/master", ""), Cmd("git branch", ""), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git tag", self.TAGS), Cmd("git checkout -f origin/master -- include/v8-version.h", "", cb=self.WriteFakeVersionFile), Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"), Cmd("git log -1 --format=%H release_hash^", "abc3\n"), Cmd("git log --format=%H abc3..push_hash", "rev1\n"), Cmd("git log -1 --format=%s rev1", "Log text 1.\n"), Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"), Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"), Cmd("git reset --hard origin/master", ""), Cmd("git checkout -b work-branch push_hash", ""), Cmd("git checkout -f 3.22.4 -- ChangeLog", "", cb=ResetChangeLog), Cmd("git checkout -f 3.22.4 -- include/v8-version.h", "", cb=self.WriteFakeVersionFile), Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "", cb=CheckVersionCommit), Cmd("git push origin " "refs/heads/work-branch:refs/pending/heads/3.22.5 " "push_hash:refs/pending-tags/heads/3.22.5 " "push_hash:refs/heads/3.22.5", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=" "\"Version 3.22.5\" origin/3.22.5", "hsh_to_tag"), Cmd("git tag 3.22.5 hsh_to_tag", ""), Cmd("git push origin 3.22.5", ""), Cmd("git checkout -f origin/master", ""), Cmd("git branch", "* master\n work-branch\n"), Cmd("git branch -D work-branch", ""), Cmd("git gc", ""), ] self.Expect(expectations) args = ["-a", "author@chromium.org", "-r", "reviewer@chromium.org", "--revision", "push_hash"] CreateRelease(TEST_CONFIG, self).Run(args) cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) # Note: The version file is on build number 5 again in the end of this test # since the git command that merges to master is mocked out. C_V8_22624_LOG = """V8 CL. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123 """ C_V8_123455_LOG = """V8 CL. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123 """ C_V8_123456_LOG = """V8 CL. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123 """ ROLL_COMMIT_MSG = """Update V8 to version 3.22.4 (based on abc). Summary of changes available at: https://chromium.googlesource.com/v8/v8/+log/last_rol..roll_hsh Please follow these instructions for assigning/CC'ing issues: https://code.google.com/p/v8-wiki/wiki/TriagingIssues TBR=g_name@chromium.org,reviewer@chromium.org""" def testChromiumRoll(self): # Setup fake directory structures. TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git")) chrome_dir = TEST_CONFIG["CHROMIUM"] os.makedirs(os.path.join(chrome_dir, "v8")) # Write fake deps file. TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line", os.path.join(chrome_dir, "DEPS")) def WriteDeps(): TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line", os.path.join(chrome_dir, "DEPS")) expectations = [ Cmd("git fetch origin", ""), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git log -1 --format=%s roll_hsh", "Version 3.22.4 (based on abc)\n"), Cmd("git describe --tags roll_hsh", "3.22.4"), Cmd("git describe --tags last_roll_hsh", "3.22.2.1"), URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js", "document.write('g_name')"), Cmd("git status -s -uno", "", cwd=chrome_dir), Cmd("git checkout -f master", "", cwd=chrome_dir), Cmd("git branch", "", cwd=chrome_dir), Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir), Cmd("git pull", "", cwd=chrome_dir), Cmd("git fetch origin", ""), Cmd("git new-branch work-branch", "", cwd=chrome_dir), Cmd("roll-dep-svn v8 roll_hsh", "rolled", cb=WriteDeps, cwd=chrome_dir), Cmd(("git commit -am \"%s\" " "--author \"author@chromium.org \"" % self.ROLL_COMMIT_MSG), "", cwd=chrome_dir), Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f", "", cwd=chrome_dir), Cmd("git checkout -f master", "", cwd=chrome_dir), Cmd("git branch -D work-branch", "", cwd=chrome_dir), ] self.Expect(expectations) args = ["-a", "author@chromium.org", "-c", chrome_dir, "--sheriff", "-r", "reviewer@chromium.org", "--last-roll", "last_roll_hsh", "roll_hsh"] ChromiumRoll(TEST_CONFIG, self).Run(args) deps = FileToText(os.path.join(chrome_dir, "DEPS")) self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps)) def testCheckLastPushRecently(self): self.Expect([ Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git tag", self.TAGS), Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), Cmd("git log -1 --format=%s release_hash", "Version 3.22.4 (based on abc3)\n"), Cmd("git log --format=%H abc3..abc123", "\n"), ]) self._state["candidate"] = "abc123" self.assertEquals(0, self.RunStep( auto_push.AutoPush, LastReleaseBailout, AUTO_PUSH_ARGS)) def testAutoPush(self): self.Expect([ Cmd("git fetch", ""), Cmd("git fetch origin +refs/heads/roll:refs/heads/roll", ""), Cmd("git show-ref -s refs/heads/roll", "abc123\n"), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git tag", self.TAGS), Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), Cmd("git log -1 --format=%s release_hash", "Version 3.22.4 (based on abc3)\n"), Cmd("git log --format=%H abc3..abc123", "some_stuff\n"), ]) auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"]) state = json.loads(FileToText("%s-state.json" % TEST_CONFIG["PERSISTFILE_BASENAME"])) self.assertEquals("abc123", state["candidate"]) def testAutoRollExistingRoll(self): self.Expect([ URL("https://codereview.chromium.org/search", "owner=author%40chromium.org&limit=30&closed=3&format=json", ("{\"results\": [{\"subject\": \"different\"}," "{\"subject\": \"Update V8 to Version...\"}]}")), ]) result = auto_roll.AutoRoll(TEST_CONFIG, self).Run( AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]]) self.assertEquals(0, result) # Snippet from the original DEPS file. FAKE_DEPS = """ vars = { "v8_revision": "abcd123455", } deps = { "src/v8": (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" + Var("v8_revision"), } """ def testAutoRollUpToDate(self): TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS")) self.Expect([ URL("https://codereview.chromium.org/search", "owner=author%40chromium.org&limit=30&closed=3&format=json", ("{\"results\": [{\"subject\": \"different\"}]}")), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git rev-list --max-age=740800 --tags", "bad_tag\nhash_234\nhash_123"), Cmd("git describe --tags bad_tag", ""), Cmd("git describe --tags hash_234", "3.22.4"), Cmd("git describe --tags hash_123", "3.22.3"), Cmd("git describe --tags abcd123455", "3.22.4"), Cmd("git describe --tags hash_234", "3.22.4"), Cmd("git describe --tags hash_123", "3.22.3"), ]) result = auto_roll.AutoRoll(TEST_CONFIG, self).Run( AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]]) self.assertEquals(0, result) def testAutoRoll(self): TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS")) self.Expect([ URL("https://codereview.chromium.org/search", "owner=author%40chromium.org&limit=30&closed=3&format=json", ("{\"results\": [{\"subject\": \"different\"}]}")), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git rev-list --max-age=740800 --tags", "bad_tag\nhash_234\nhash_123"), Cmd("git describe --tags bad_tag", ""), Cmd("git describe --tags hash_234", "3.22.4"), Cmd("git describe --tags hash_123", "3.22.3"), Cmd("git describe --tags abcd123455", "3.22.3.1"), Cmd("git describe --tags hash_234", "3.22.4"), ]) result = auto_roll.AutoRoll(TEST_CONFIG, self).Run( AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"], "--roll"]) self.assertEquals(0, result) def testMergeToBranch(self): TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile() TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) self.WriteFakeVersionFile(build=5) os.environ["EDITOR"] = "vi" extra_patch = self.MakeEmptyTempFile() def VerifyPatch(patch): return lambda: self.assertEquals(patch, FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"])) msg = """Version 3.22.5.1 (cherry-pick) Merged ab12345 Merged ab23456 Merged ab34567 Merged ab45678 Merged ab56789 Title4 Title2 Title3 Title1 Revert "Something" BUG=123,234,345,456,567,v8:123 LOG=N """ def VerifyLand(): commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) self.assertEquals(msg, commit) version = FileToText( os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+1", version)) self.assertTrue( re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) self.Expect([ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* branch2\n"), Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" % TEST_CONFIG["BRANCHNAME"], ""), Cmd(("git log --format=%H --grep=\"Port ab12345\" " "--reverse origin/master"), "ab45678\nab23456"), Cmd("git log -1 --format=%s ab45678", "Title1"), Cmd("git log -1 --format=%s ab23456", "Title2"), Cmd(("git log --format=%H --grep=\"Port ab23456\" " "--reverse origin/master"), ""), Cmd(("git log --format=%H --grep=\"Port ab34567\" " "--reverse origin/master"), "ab56789"), Cmd("git log -1 --format=%s ab56789", "Title3"), RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)? # Simulate git being down which stops the script. Cmd("git log -1 --format=%s ab12345", None), # Restart script in the failing step. Cmd("git log -1 --format=%s ab12345", "Title4"), Cmd("git log -1 --format=%s ab23456", "Title2"), Cmd("git log -1 --format=%s ab34567", "Title3"), Cmd("git log -1 --format=%s ab45678", "Title1"), Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""), Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"), Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"), Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"), Cmd("git log -1 ab45678", "Title1\nBUG="), Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"), Cmd("git log -1 -p ab12345", "patch4"), Cmd(("git apply --index --reject \"%s\"" % TEST_CONFIG["TEMPORARY_PATCH_FILE"]), "", cb=VerifyPatch("patch4")), Cmd("git log -1 -p ab23456", "patch2"), Cmd(("git apply --index --reject \"%s\"" % TEST_CONFIG["TEMPORARY_PATCH_FILE"]), "", cb=VerifyPatch("patch2")), Cmd("git log -1 -p ab34567", "patch3"), Cmd(("git apply --index --reject \"%s\"" % TEST_CONFIG["TEMPORARY_PATCH_FILE"]), "", cb=VerifyPatch("patch3")), Cmd("git log -1 -p ab45678", "patch1"), Cmd(("git apply --index --reject \"%s\"" % TEST_CONFIG["TEMPORARY_PATCH_FILE"]), "", cb=VerifyPatch("patch1")), Cmd("git log -1 -p ab56789", "patch5\n"), Cmd(("git apply --index --reject \"%s\"" % TEST_CONFIG["TEMPORARY_PATCH_FILE"]), "", cb=VerifyPatch("patch5\n")), Cmd("git apply --index --reject \"%s\"" % extra_patch, ""), RL("Y"), # Automatically increment patch level? Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""), RL("reviewer@chromium.org"), # V8 reviewer. Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" " "--bypass-hooks --cc \"ulan@chromium.org\"", ""), Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""), RL("LGTM"), # Enter LGTM for V8 CL. Cmd("git cl presubmit", "Presubmit successfull\n"), Cmd("git cl land -f --bypass-hooks", "Closing issue\n", cb=VerifyLand), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"" "Version 3.22.5.1 (cherry-pick)" "\" refs/remotes/origin/candidates", ""), Cmd("git fetch", ""), Cmd("git log -1 --format=%H --grep=\"" "Version 3.22.5.1 (cherry-pick)" "\" refs/remotes/origin/candidates", "hsh_to_tag"), Cmd("git tag 3.22.5.1 hsh_to_tag", ""), Cmd("git push origin 3.22.5.1", ""), Cmd("git checkout -f origin/master", ""), Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), ]) # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567. args = ["-f", "-p", extra_patch, "--branch", "candidates", "ab12345", "ab23456", "ab34567"] # The first run of the script stops because of git being down. self.assertRaises(GitFailedException, lambda: MergeToBranch(TEST_CONFIG, self).Run(args)) # Test that state recovery after restarting the script works. args += ["-s", "4"] MergeToBranch(TEST_CONFIG, self).Run(args) def testReleases(self): c_hash1_commit_log = """Update V8 to Version 4.2.71. Cr-Commit-Position: refs/heads/master@{#5678} """ c_hash2_commit_log = """Revert something. BUG=12345 Reason: > Some reason. > Cr-Commit-Position: refs/heads/master@{#12345} > git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4 Review URL: https://codereview.chromium.org/12345 Cr-Commit-Position: refs/heads/master@{#4567} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b """ c_hash3_commit_log = """Simple. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b """ c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick). Merged abc12. Review URL: fake.com Cr-Commit-Position: refs/heads/candidates@{#234} """ c_hash_123_commit_log = """Version 3.3.1.0 git-svn-id: googlecode@123 0039-1c4b """ c_hash_345_commit_log = """Version 3.4.0. Cr-Commit-Position: refs/heads/candidates@{#345} """ c_hash_456_commit_log = """Version 4.2.71. Cr-Commit-Position: refs/heads/4.2.71@{#1} """ c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n" json_output = self.MakeEmptyTempFile() csv_output = self.MakeEmptyTempFile() self.WriteFakeVersionFile() TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() chrome_dir = TEST_CONFIG["CHROMIUM"] chrome_v8_dir = os.path.join(chrome_dir, "v8") os.makedirs(chrome_v8_dir) def ResetVersion(major, minor, build, patch=0): return lambda: self.WriteFakeVersionFile(major=major, minor=minor, build=build, patch=patch) self.Expect([ Cmd("git status -s -uno", ""), Cmd("git checkout -f origin/master", ""), Cmd("git fetch", ""), Cmd("git branch", " branch1\n* branch2\n"), Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""), Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), Cmd("git rev-list --max-age=395200 --tags", "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"), Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"), Cmd("git describe --tags hash_234", "3.3.1.1"), Cmd("git describe --tags hash_123", "3.21.2"), Cmd("git describe --tags hash_345", "3.22.3"), Cmd("git describe --tags hash_456", "4.2.71"), Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE), Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 3, 1, 1)), Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"), Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), Cmd("git log -1 --format=%s hash_234", ""), Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), Cmd("git log -1 --format=%ci hash_234", "18:15"), Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 22, 5)), Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE), Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 21, 2)), Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"), Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), Cmd("git log -1 --format=%s hash_123", ""), Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), Cmd("git log -1 --format=%ci hash_123", "03:15"), Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 22, 5)), Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE), Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 22, 3)), Cmd("git branch -r --contains hash_345", " origin/candidates\n"), Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), Cmd("git log -1 --format=%s hash_345", ""), Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), Cmd("git log -1 --format=%ci hash_345", ""), Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 22, 5)), Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE), Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "", cb=ResetVersion(4, 2, 71)), Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"), Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), Cmd("git log -1 --format=%H 4.2.71", "hash_456"), Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"), Cmd("git log -1 --format=%H hash_456^", "master_456"), Cmd("git log -1 --format=%B master_456", "Cr-Commit-Position: refs/heads/master@{#456}"), Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), Cmd("git log -1 --format=%ci hash_456", "02:15"), Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", cb=ResetVersion(3, 22, 5)), Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* " "+refs/branch-heads/*:refs/remotes/branch-heads/*", "", cwd=chrome_dir), Cmd("git fetch origin", "", cwd=chrome_v8_dir), Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS", "c_hash1\nc_hash2\nc_hash3\n", cwd=chrome_dir), Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir), Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log, cwd=chrome_dir), Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir), Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log, cwd=chrome_dir), Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir), Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log, cwd=chrome_dir), Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir), Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345", cwd=chrome_dir), URL("http://omahaproxy.appspot.com/all.json", """[{ "os": "win", "versions": [{ "version": "2.2.2.2", "v8_version": "22.2.2.2", "current_reldate": "04/09/15", "os": "win", "channel": "canary", "previous_version": "1.1.1.0" }] }]"""), URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{ "chromium_version": "1.1.1.0", "v8_version": "11.1.1.0" }"""), Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"), Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"), Cmd("git checkout -f origin/master", ""), Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "") ]) args = ["-c", TEST_CONFIG["CHROMIUM"], "--json", json_output, "--csv", csv_output, "--max-releases", "1"] Releases(TEST_CONFIG, self).Run(args) # Check expected output. csv = ("4.2.71,4.2.71,1,5678,\r\n" "3.22.3,candidates,345,4567:5677,\r\n" "3.21.2,3.21,123,,\r\n" "3.3.1.1,3.3,234,,abc12\r\n") self.assertEquals(csv, FileToText(csv_output)) expected_json = {"chrome_releases":{ "canaries": [ { "chrome_version": "2.2.2.2", "os": "win", "release_date": "04/09/15", "v8_version": "22.2.2.2", "v8_version_hash": "v8_version_hash", "v8_previous_version": "11.1.1.0", "v8_previous_version_hash": "v8_previous_version_hash" }]}, "releases":[ { "revision": "1", "revision_git": "hash_456", "master_position": "456", "master_hash": "master_456", "patches_merged": "", "version": "4.2.71", "chromium_revision": "5678", "branch": "4.2.71", "review_link": "", "date": "02:15", "chromium_branch": "", # FIXME(machenbach): Fix revisions link for git. "revision_link": "https://code.google.com/p/v8/source/detail?r=1", }, { "revision": "345", "revision_git": "hash_345", "master_position": "", "master_hash": "", "patches_merged": "", "version": "3.22.3", "chromium_revision": "4567:5677", "branch": "candidates", "review_link": "", "date": "", "chromium_branch": "7", "revision_link": "https://code.google.com/p/v8/source/detail?r=345", }, { "revision": "123", "revision_git": "hash_123", "patches_merged": "", "master_position": "", "master_hash": "", "version": "3.21.2", "chromium_revision": "", "branch": "3.21", "review_link": "", "date": "03:15", "chromium_branch": "", "revision_link": "https://code.google.com/p/v8/source/detail?r=123", }, { "revision": "234", "revision_git": "hash_234", "patches_merged": "abc12", "master_position": "", "master_hash": "", "version": "3.3.1.1", "chromium_revision": "", "branch": "3.3", "review_link": "fake.com", "date": "18:15", "chromium_branch": "", "revision_link": "https://code.google.com/p/v8/source/detail?r=234", },], } self.assertEquals(expected_json, json.loads(FileToText(json_output))) class SystemTest(unittest.TestCase): def testReload(self): options = ScriptsBase( TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([]) step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={}, options=options, side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER) body = step.Reload( """------------------------------------------------------------------------ r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines Prepare push to trunk. Now working on version 3.23.11. R=danno@chromium.org Review URL: https://codereview.chromium.org/83173002 ------------------------------------------------------------------------""") self.assertEquals( """Prepare push to trunk. Now working on version 3.23.11. R=danno@chromium.org Committed: https://code.google.com/p/v8/source/detail?r=17997""", body) node-v4.2.6/deps/v8/tools/release/test_search_related_commits.py000755 000766 000024 00000020116 12650222326 025132 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. from collections import namedtuple from os import path import search_related_commits import shutil from subprocess import Popen, PIPE, check_call import unittest TEST_CONFIG = { "GIT_REPO": "/tmp/test-v8-search-related-commits", } class TestSearchRelatedCommits(unittest.TestCase): base_dir = TEST_CONFIG["GIT_REPO"] def _execute_git(self, git_args): fullCommand = ["git", "-C", self.base_dir] + git_args p = Popen(args=fullCommand, stdin=PIPE, stdout=PIPE, stderr=PIPE) output, err = p.communicate() rc = p.returncode if rc != 0: raise Exception(err) return output def setUp(self): if path.exists(self.base_dir): shutil.rmtree(self.base_dir) check_call(["git", "init", self.base_dir]) # Initial commit message = """[turbofan] Sanitize language mode for javascript operators. R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28059}""" self._make_empty_commit(message) message = """[crankshaft] Do some stuff R=hablich@chromium.org Review URL: https://codereview.chromium.org/1084243007 Cr-Commit-Position: refs/heads/master@{#28030}""" self._make_empty_commit(message) def tearDown(self): if path.exists(self.base_dir): shutil.rmtree(self.base_dir) def _assert_correct_standard_result( self, result, all_commits, hash_of_first_commit): self.assertEqual(len(result), 1, "Master commit not found") self.assertTrue( result.get(hash_of_first_commit), "Master commit is wrong") self.assertEqual( len(result[hash_of_first_commit]), 1, "Child commit not found") self.assertEqual( all_commits[2], result[hash_of_first_commit][0], "Child commit wrong") def _get_commits(self): commits = self._execute_git( ["log", "--format=%H", "--reverse"]).splitlines() return commits def _make_empty_commit(self, message): self._execute_git(["commit", "--allow-empty", "-m", message]) def testSearchByCommitPosition(self): message = """Revert of some stuff. > Cr-Commit-Position: refs/heads/master@{#28059} R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28088}""" self._make_empty_commit(message) commits = self._get_commits() hash_of_first_commit = commits[0] result = search_related_commits.search_all_related_commits( self.base_dir, hash_of_first_commit, "HEAD", None) self._assert_correct_standard_result(result, commits, hash_of_first_commit) def testSearchByTitle(self): message = """Revert of some stuff. > [turbofan] Sanitize language mode for javascript operators. > Cr-Commit-Position: refs/heads/master@{#289} R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28088}""" self._make_empty_commit(message) commits = self._get_commits() hash_of_first_commit = commits[0] result = search_related_commits.search_all_related_commits( self.base_dir, hash_of_first_commit, "HEAD", None) self._assert_correct_standard_result(result, commits, hash_of_first_commit) def testSearchByHash(self): commits = self._get_commits() hash_of_first_commit = commits[0] message = """Revert of some stuff. > [turbofan] Sanitize language mode for javascript operators. > Reverting """ + hash_of_first_commit + """ > R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28088}""" self._make_empty_commit(message) #Fetch again for an update commits = self._get_commits() hash_of_first_commit = commits[0] result = search_related_commits.search_all_related_commits( self.base_dir, hash_of_first_commit, "HEAD", None) self._assert_correct_standard_result(result, commits, hash_of_first_commit) def testConsiderSeparator(self): commits = self._get_commits() hash_of_first_commit = commits[0] # Related commits happen before separator so it is not a hit message = """Revert of some stuff: Not a hit > [turbofan] Sanitize language mode for javascript operators. > Reverting """ + hash_of_first_commit + """ > R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28088}""" self._make_empty_commit(message) # Related commits happen before and after separator so it is a hit commit_pos_of_master = "27088" message = """Implement awesome feature: Master commit Review URL: https://codereview.chromium.org/1084243235 Cr-Commit-Position: refs/heads/master@{#""" + commit_pos_of_master + "}" self._make_empty_commit(message) # Separator commit message = """Commit which is the origin of the branch Review URL: https://codereview.chromium.org/1084243456 Cr-Commit-Position: refs/heads/master@{#28173}""" self._make_empty_commit(message) # Filler commit message = "Some unrelated commit: Not a hit" self._make_empty_commit(message) # Related commit after separator: a hit message = "Patch r" + commit_pos_of_master +""" done Review URL: https://codereview.chromium.org/1084243235 Cr-Commit-Position: refs/heads/master@{#29567}""" self._make_empty_commit(message) #Fetch again for an update commits = self._get_commits() hash_of_first_commit = commits[0] hash_of_hit = commits[3] hash_of_separator = commits[4] hash_of_child_hit = commits[6] result = search_related_commits.search_all_related_commits( self.base_dir, hash_of_first_commit, "HEAD", hash_of_separator) self.assertTrue(result.get(hash_of_hit), "Hit not found") self.assertEqual(len(result), 1, "More than one hit found") self.assertEqual( len(result.get(hash_of_hit)), 1, "More than one child hit found") self.assertEqual( result.get(hash_of_hit)[0], hash_of_child_hit, "Wrong commit found") def testPrettyPrint(self): message = """Revert of some stuff. > [turbofan] Sanitize language mode for javascript operators. > Cr-Commit-Position: refs/heads/master@{#289} R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/1084243005 Cr-Commit-Position: refs/heads/master@{#28088}""" self._make_empty_commit(message) commits = self._get_commits() hash_of_first_commit = commits[0] OptionsStruct = namedtuple( "OptionsStruct", "git_dir of until all prettyprint separator verbose") options = OptionsStruct( git_dir= self.base_dir, of= [hash_of_first_commit], until= [commits[2]], all= True, prettyprint= True, separator = None, verbose=False) output = [] for current_line in search_related_commits.main(options): output.append(current_line) self.assertIs(len(output), 2, "Not exactly two entries written") self.assertTrue(output[0].startswith("+"), "Master entry not marked with +") self.assertTrue(output[1].startswith("| "), "Child entry not marked with |") def testNothingFound(self): commits = self._get_commits() self._execute_git(["commit", "--allow-empty", "-m", "A"]) self._execute_git(["commit", "--allow-empty", "-m", "B"]) self._execute_git(["commit", "--allow-empty", "-m", "C"]) self._execute_git(["commit", "--allow-empty", "-m", "D"]) hash_of_first_commit = commits[0] result = search_related_commits.search_all_related_commits( self.base_dir, hash_of_first_commit, "HEAD", None) self.assertEqual(len(result), 0, "Results found where none should be.") if __name__ == "__main__": #import sys;sys.argv = ['', 'Test.testName'] unittest.main() node-v4.2.6/deps/v8/tools/perf_tests/chromium_revision000644 000766 000024 00000000007 12650222326 023235 0ustar00iojsstaff000000 000000 210122 node-v4.2.6/deps/v8/tools/oom_dump/oom_dump.cc000644 000766 000024 00000022132 12650222326 021343 0ustar00iojsstaff000000 000000 // Copyright 2010 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include namespace { using google_breakpad::Minidump; using google_breakpad::MinidumpContext; using google_breakpad::MinidumpThread; using google_breakpad::MinidumpThreadList; using google_breakpad::MinidumpException; using google_breakpad::MinidumpMemoryRegion; const char* InstanceTypeToString(int type) { static char const* names[v8::internal::LAST_TYPE] = {0}; if (names[v8::internal::STRING_TYPE] == NULL) { using namespace v8::internal; #define SET(type) names[type] = #type; INSTANCE_TYPE_LIST(SET) #undef SET } return names[type]; } u_int32_t ReadPointedValue(MinidumpMemoryRegion* region, u_int64_t base, int offset) { u_int32_t ptr = 0; CHECK(region->GetMemoryAtAddress(base + 4 * offset, &ptr)); u_int32_t value = 0; CHECK(region->GetMemoryAtAddress(ptr, &value)); return value; } void ReadArray(MinidumpMemoryRegion* region, u_int64_t array_ptr, int size, int* output) { for (int i = 0; i < size; i++) { u_int32_t value; CHECK(region->GetMemoryAtAddress(array_ptr + 4 * i, &value)); output[i] = value; } } u_int32_t ReadArrayFrom(MinidumpMemoryRegion* region, u_int64_t base, int offset, int size, int* output) { u_int32_t ptr = 0; CHECK(region->GetMemoryAtAddress(base + 4 * offset, &ptr)); ReadArray(region, ptr, size, output); } double toM(int size) { return size / (1024. * 1024.); } class IndirectSorter { public: explicit IndirectSorter(int* a) : a_(a) { } bool operator() (int i0, int i1) { return a_[i0] > a_[i1]; } private: int* a_; }; void DumpHeapStats(const char *minidump_file) { Minidump minidump(minidump_file); CHECK(minidump.Read()); MinidumpException *exception = minidump.GetException(); CHECK(exception); MinidumpContext* crash_context = exception->GetContext(); CHECK(crash_context); u_int32_t exception_thread_id = 0; CHECK(exception->GetThreadID(&exception_thread_id)); MinidumpThreadList* thread_list = minidump.GetThreadList(); CHECK(thread_list); MinidumpThread* exception_thread = thread_list->GetThreadByID(exception_thread_id); CHECK(exception_thread); // Currently only 32-bit Windows minidumps are supported. CHECK_EQ(MD_CONTEXT_X86, crash_context->GetContextCPU()); const MDRawContextX86* contextX86 = crash_context->GetContextX86(); CHECK(contextX86); const u_int32_t esp = contextX86->esp; MinidumpMemoryRegion* memory_region = exception_thread->GetMemory(); CHECK(memory_region); const u_int64_t last = memory_region->GetBase() + memory_region->GetSize(); u_int64_t heap_stats_addr = 0; for (u_int64_t addr = esp; addr < last; addr += 4) { u_int32_t value = 0; CHECK(memory_region->GetMemoryAtAddress(addr, &value)); if (value >= esp && value < last) { u_int32_t value2 = 0; CHECK(memory_region->GetMemoryAtAddress(value, &value2)); if (value2 == v8::internal::HeapStats::kStartMarker) { heap_stats_addr = addr; break; } } } CHECK(heap_stats_addr); // Read heap stats. #define READ_FIELD(offset) \ ReadPointedValue(memory_region, heap_stats_addr, offset) CHECK(READ_FIELD(0) == v8::internal::HeapStats::kStartMarker); CHECK(READ_FIELD(24) == v8::internal::HeapStats::kEndMarker); const int new_space_size = READ_FIELD(1); const int new_space_capacity = READ_FIELD(2); const int old_space_size = READ_FIELD(3); const int old_space_capacity = READ_FIELD(4); const int code_space_size = READ_FIELD(5); const int code_space_capacity = READ_FIELD(6); const int map_space_size = READ_FIELD(7); const int map_space_capacity = READ_FIELD(8); const int cell_space_size = READ_FIELD(9); const int cell_space_capacity = READ_FIELD(10); const int lo_space_size = READ_FIELD(11); const int global_handle_count = READ_FIELD(12); const int weak_global_handle_count = READ_FIELD(13); const int pending_global_handle_count = READ_FIELD(14); const int near_death_global_handle_count = READ_FIELD(15); const int destroyed_global_handle_count = READ_FIELD(16); const int memory_allocator_size = READ_FIELD(17); const int memory_allocator_capacity = READ_FIELD(18); const int os_error = READ_FIELD(19); #undef READ_FIELD int objects_per_type[v8::internal::LAST_TYPE + 1] = {0}; ReadArrayFrom(memory_region, heap_stats_addr, 21, v8::internal::LAST_TYPE + 1, objects_per_type); int size_per_type[v8::internal::LAST_TYPE + 1] = {0}; ReadArrayFrom(memory_region, heap_stats_addr, 22, v8::internal::LAST_TYPE + 1, size_per_type); int js_global_objects = objects_per_type[v8::internal::JS_GLOBAL_OBJECT_TYPE]; int js_builtins_objects = objects_per_type[v8::internal::JS_BUILTINS_OBJECT_TYPE]; int js_global_proxies = objects_per_type[v8::internal::JS_GLOBAL_PROXY_TYPE]; int indices[v8::internal::LAST_TYPE + 1]; for (int i = 0; i <= v8::internal::LAST_TYPE; i++) { indices[i] = i; } std::stable_sort(indices, indices + sizeof(indices)/sizeof(indices[0]), IndirectSorter(size_per_type)); int total_size = 0; for (int i = 0; i <= v8::internal::LAST_TYPE; i++) { total_size += size_per_type[i]; } // Print heap stats. printf("exception thread ID: %" PRIu32 " (%#" PRIx32 ")\n", exception_thread_id, exception_thread_id); printf("heap stats address: %#" PRIx64 "\n", heap_stats_addr); #define PRINT_INT_STAT(stat) \ printf("\t%-25s\t% 10d\n", #stat ":", stat); #define PRINT_MB_STAT(stat) \ printf("\t%-25s\t% 10.3f MB\n", #stat ":", toM(stat)); PRINT_MB_STAT(new_space_size); PRINT_MB_STAT(new_space_capacity); PRINT_MB_STAT(old_space_size); PRINT_MB_STAT(old_space_capacity); PRINT_MB_STAT(code_space_size); PRINT_MB_STAT(code_space_capacity); PRINT_MB_STAT(map_space_size); PRINT_MB_STAT(map_space_capacity); PRINT_MB_STAT(cell_space_size); PRINT_MB_STAT(cell_space_capacity); PRINT_MB_STAT(lo_space_size); PRINT_INT_STAT(global_handle_count); PRINT_INT_STAT(weak_global_handle_count); PRINT_INT_STAT(pending_global_handle_count); PRINT_INT_STAT(near_death_global_handle_count); PRINT_INT_STAT(destroyed_global_handle_count); PRINT_MB_STAT(memory_allocator_size); PRINT_MB_STAT(memory_allocator_capacity); PRINT_INT_STAT(os_error); #undef PRINT_STAT printf("\n"); printf( "\tJS_GLOBAL_OBJECT_TYPE/JS_BUILTINS_OBJECT_TYPE/JS_GLOBAL_PROXY_TYPE: " "%d/%d/%d\n\n", js_global_objects, js_builtins_objects, js_global_proxies); int running_size = 0; for (int i = 0; i <= v8::internal::LAST_TYPE; i++) { int type = indices[i]; const char* name = InstanceTypeToString(type); if (name == NULL) { // Unknown instance type. Check that there is no objects of that type. CHECK_EQ(0, objects_per_type[type]); CHECK_EQ(0, size_per_type[type]); continue; } int size = size_per_type[type]; running_size += size; printf("\t%-37s% 9d% 11.3f MB% 10.3f%%% 10.3f%%\n", name, objects_per_type[type], toM(size), 100. * size / total_size, 100. * running_size / total_size); } printf("\t%-37s% 9d% 11.3f MB% 10.3f%%% 10.3f%%\n", "total", 0, toM(total_size), 100., 100.); } } // namespace int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "usage: %s \n", argv[0]); return 1; } DumpHeapStats(argv[1]); return 0; } node-v4.2.6/deps/v8/tools/oom_dump/README000644 000766 000024 00000002376 12650222326 020105 0ustar00iojsstaff000000 000000 oom_dump extracts useful information from Google Chrome OOM minidumps. To build one needs a google-breakpad checkout (http://code.google.com/p/google-breakpad/). First, one needs to build and install breakpad itself. For instructions check google-breakpad, but currently it's as easy as: ./configure make sudo make install (the catch: breakpad installs .so into /usr/local/lib, so you might need some additional tweaking to make it discoverable, for example, put a soft link into /usr/lib directory). Next step is to build v8. Note: you should build x64 version of v8, if you're on 64-bit platform, otherwise you would get a link error when building oom_dump. Also, if you are testing against an older version of chrome you should build the corresponding version of V8 to make sure that the type-id enum have the correct values. The last step is to build oom_dump itself. The following command should work: cd /tools/oom_dump scons BREAKPAD_DIR= (Additionally you can control v8 working copy dir, but the default should work.) If everything goes fine, oom_dump should print some useful information about the OOM crash. Note: currently only 32-bit Windows minidumps are supported. node-v4.2.6/deps/v8/tools/oom_dump/SConstruct000644 000766 000024 00000004227 12650222326 021254 0ustar00iojsstaff000000 000000 # Copyright 2010 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. vars = Variables('custom.py') vars.Add(PathVariable('BREAKPAD_DIR', 'Path to checkout of google-breakpad project', '~/google-breakpad', PathVariable.PathIsDir)) vars.Add(PathVariable('V8_DIR', 'Path to checkout of v8 project', '../..', PathVariable.PathIsDir)) env = Environment(variables = vars, CPPPATH = ['${BREAKPAD_DIR}/src', '${V8_DIR}/src'], LIBPATH = ['/usr/local/lib', '${V8_DIR}']) env.Program('oom_dump.cc', LIBS = ['breakpad', 'v8', 'pthread']) node-v4.2.6/deps/v8/tools/ninja/ninja_output.py000644 000766 000024 00000002557 12650222326 021577 0ustar00iojsstaff000000 000000 # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import os.path def GetNinjaOutputDirectory(v8_root, configuration=None): """Returns //(Release|Debug). The configuration chosen is the one most recently generated/built, but can be overriden via the parameter. Detects a custom output_dir specified by GYP_GENERATOR_FLAGS.""" output_dir = 'out' generator_flags = os.getenv('GYP_GENERATOR_FLAGS', '').split(' ') for flag in generator_flags: name_value = flag.split('=', 1) if len(name_value) == 2 and name_value[0] == 'output_dir': output_dir = name_value[1] root = os.path.join(v8_root, output_dir) if configuration: return os.path.join(root, configuration) debug_path = os.path.join(root, 'Debug') release_path = os.path.join(root, 'Release') def is_release_newer(test_path): try: debug_mtime = os.path.getmtime(os.path.join(debug_path, test_path)) except os.error: debug_mtime = 0 try: rel_mtime = os.path.getmtime(os.path.join(release_path, test_path)) except os.error: rel_mtime = 0 return rel_mtime >= debug_mtime if is_release_newer('.ninja_log') or is_release_newer('.ninja_deps'): return release_path return debug_path node-v4.2.6/deps/v8/tools/gyp/v8.gyp000644 000766 000024 00000220701 12650222326 017255 0ustar00iojsstaff000000 000000 # Copyright 2012 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { 'variables': { 'icu_use_data_file_flag%': 0, 'v8_code': 1, 'v8_random_seed%': 314159265, 'embed_script%': "", 'v8_extra_library_files%': [], 'mksnapshot_exec': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)', }, 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'], 'targets': [ { 'target_name': 'v8', 'dependencies_traverse': 1, 'dependencies': ['v8_maybe_snapshot'], 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], }, { 'toolsets': ['target'], }], ['component=="shared_library"', { 'type': '<(component)', 'sources': [ # Note: on non-Windows we still build this file so that gyp # has some sources to link into the component. '../../src/v8dll-main.cc', ], 'include_dirs': [ '../..', ], 'defines': [ 'V8_SHARED', 'BUILDING_V8_SHARED', ], 'direct_dependent_settings': { 'defines': [ 'V8_SHARED', 'USING_V8_SHARED', ], }, 'target_conditions': [ ['OS=="android" and _toolset=="target"', { 'libraries': [ '-llog', ], 'include_dirs': [ 'src/common/android/include', ], }], ], 'conditions': [ ['OS=="mac"', { 'xcode_settings': { 'OTHER_LDFLAGS': ['-dynamiclib', '-all_load'] }, }], ['soname_version!=""', { 'product_extension': 'so.<(soname_version)', }], ], }, { 'type': 'none', }], ], 'direct_dependent_settings': { 'include_dirs': [ '../../include', ], }, }, { # This rule delegates to either v8_snapshot, v8_nosnapshot, or # v8_external_snapshot, depending on the current variables. # The intention is to make the 'calling' rules a bit simpler. 'target_name': 'v8_maybe_snapshot', 'type': 'none', 'conditions': [ ['v8_use_snapshot!="true"', { # The dependency on v8_base should come from a transitive # dependency however the Android toolchain requires libv8_base.a # to appear before libv8_snapshot.a so it's listed explicitly. 'dependencies': ['v8_base', 'v8_nosnapshot'], }], ['v8_use_snapshot=="true" and v8_use_external_startup_data==0', { # The dependency on v8_base should come from a transitive # dependency however the Android toolchain requires libv8_base.a # to appear before libv8_snapshot.a so it's listed explicitly. 'dependencies': ['v8_base', 'v8_snapshot'], }], ['v8_use_snapshot=="true" and v8_use_external_startup_data==1 and want_separate_host_toolset==0', { 'dependencies': ['v8_base', 'v8_external_snapshot'], 'inputs': [ '<(PRODUCT_DIR)/snapshot_blob.bin', ], }], ['v8_use_snapshot=="true" and v8_use_external_startup_data==1 and want_separate_host_toolset==1', { 'dependencies': ['v8_base', 'v8_external_snapshot'], 'target_conditions': [ ['_toolset=="host"', { 'inputs': [ '<(PRODUCT_DIR)/snapshot_blob_host.bin', ], }, { 'inputs': [ '<(PRODUCT_DIR)/snapshot_blob.bin', ], }], ], }], ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], }, { 'toolsets': ['target'], }], ] }, { 'target_name': 'v8_snapshot', 'type': 'static_library', 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], 'dependencies': [ 'mksnapshot#host', 'js2c#host', ], }, { 'toolsets': ['target'], 'dependencies': [ 'mksnapshot', 'js2c', ], }], ['component=="shared_library"', { 'defines': [ 'V8_SHARED', 'BUILDING_V8_SHARED', ], 'direct_dependent_settings': { 'defines': [ 'V8_SHARED', 'USING_V8_SHARED', ], }, }], ], 'dependencies': [ 'v8_base', ], 'include_dirs+': [ '../..', ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc', '<(INTERMEDIATE_DIR)/snapshot.cc', ], 'actions': [ { 'action_name': 'run_mksnapshot', 'inputs': [ '<(mksnapshot_exec)', '<(embed_script)', ], 'outputs': [ '<(INTERMEDIATE_DIR)/snapshot.cc', ], 'variables': { 'mksnapshot_flags': [ '--log-snapshot-positions', '--logfile', '<(INTERMEDIATE_DIR)/snapshot.log', ], 'conditions': [ ['v8_random_seed!=0', { 'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'], }], ], }, 'action': [ '<(mksnapshot_exec)', '<@(mksnapshot_flags)', '<@(INTERMEDIATE_DIR)/snapshot.cc', '<(embed_script)', ], }, ], }, { 'target_name': 'v8_nosnapshot', 'type': 'static_library', 'dependencies': [ 'v8_base', ], 'include_dirs+': [ '../..', ], 'sources': [ '<(SHARED_INTERMEDIATE_DIR)/libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc', '<(SHARED_INTERMEDIATE_DIR)/extras-libraries.cc', '../../src/snapshot/snapshot-empty.cc', ], 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], 'dependencies': ['js2c#host'], }, { 'toolsets': ['target'], 'dependencies': ['js2c'], }], ['component=="shared_library"', { 'defines': [ 'BUILDING_V8_SHARED', 'V8_SHARED', ], }], ] }, { 'target_name': 'v8_external_snapshot', 'type': 'static_library', 'conditions': [ [ 'v8_use_external_startup_data==1', { 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], 'dependencies': [ 'mksnapshot#host', 'js2c#host', 'natives_blob', ]}, { 'toolsets': ['target'], 'dependencies': [ 'mksnapshot', 'js2c', 'natives_blob', ], }], ['component=="shared_library"', { 'defines': [ 'V8_SHARED', 'BUILDING_V8_SHARED', ], 'direct_dependent_settings': { 'defines': [ 'V8_SHARED', 'USING_V8_SHARED', ], }, }], ], 'dependencies': [ 'v8_base', ], 'include_dirs+': [ '../..', ], 'sources': [ '../../src/snapshot/natives-external.cc', '../../src/snapshot/snapshot-external.cc', ], 'actions': [ { 'action_name': 'run_mksnapshot (external)', 'inputs': [ '<(mksnapshot_exec)', ], 'variables': { 'mksnapshot_flags': [ '--log-snapshot-positions', '--logfile', '<(INTERMEDIATE_DIR)/snapshot.log', ], 'conditions': [ ['v8_random_seed!=0', { 'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'], }], ], }, 'conditions': [ ['want_separate_host_toolset==1', { 'target_conditions': [ ['_toolset=="host"', { 'outputs': [ '<(INTERMEDIATE_DIR)/snapshot.cc', '<(PRODUCT_DIR)/snapshot_blob_host.bin', ], 'action': [ '<(mksnapshot_exec)', '<@(mksnapshot_flags)', '<@(INTERMEDIATE_DIR)/snapshot.cc', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin', '<(embed_script)', ], }, { 'outputs': [ '<(INTERMEDIATE_DIR)/snapshot.cc', '<(PRODUCT_DIR)/snapshot_blob.bin', ], 'action': [ '<(mksnapshot_exec)', '<@(mksnapshot_flags)', '<@(INTERMEDIATE_DIR)/snapshot.cc', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin', '<(embed_script)', ], }], ], }, { 'outputs': [ '<(INTERMEDIATE_DIR)/snapshot.cc', '<(PRODUCT_DIR)/snapshot_blob.bin', ], 'action': [ '<(mksnapshot_exec)', '<@(mksnapshot_flags)', '<@(INTERMEDIATE_DIR)/snapshot.cc', '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin', '<(embed_script)', ], }], ], }, ], }], ], }, { 'target_name': 'v8_base', 'type': 'static_library', 'dependencies': [ 'v8_libbase', ], 'variables': { 'optimize': 'max', }, 'include_dirs+': [ '../..', ], 'defines': [ # TODO(jochen): Remove again after this is globally turned on. 'V8_IMMINENT_DEPRECATION_WARNINGS', ], 'sources': [ ### gcmole(all) ### '../../include/v8-debug.h', '../../include/v8-platform.h', '../../include/v8-profiler.h', '../../include/v8-testing.h', '../../include/v8-util.h', '../../include/v8-version.h', '../../include/v8.h', '../../include/v8config.h', '../../src/accessors.cc', '../../src/accessors.h', '../../src/allocation.cc', '../../src/allocation.h', '../../src/allocation-site-scopes.cc', '../../src/allocation-site-scopes.h', '../../src/allocation-tracker.cc', '../../src/allocation-tracker.h', '../../src/api.cc', '../../src/api.h', '../../src/api-natives.cc', '../../src/api-natives.h', '../../src/arguments.cc', '../../src/arguments.h', '../../src/assembler.cc', '../../src/assembler.h', '../../src/assert-scope.h', '../../src/assert-scope.cc', '../../src/ast-value-factory.cc', '../../src/ast-value-factory.h', '../../src/ast-literal-reindexer.cc', '../../src/ast-literal-reindexer.h', '../../src/ast-numbering.cc', '../../src/ast-numbering.h', '../../src/ast.cc', '../../src/ast.h', '../../src/background-parsing-task.cc', '../../src/background-parsing-task.h', '../../src/bailout-reason.cc', '../../src/bailout-reason.h', '../../src/basic-block-profiler.cc', '../../src/basic-block-profiler.h', '../../src/bignum-dtoa.cc', '../../src/bignum-dtoa.h', '../../src/bignum.cc', '../../src/bignum.h', '../../src/bit-vector.cc', '../../src/bit-vector.h', '../../src/bootstrapper.cc', '../../src/bootstrapper.h', '../../src/builtins.cc', '../../src/builtins.h', '../../src/bytecodes-irregexp.h', '../../src/cached-powers.cc', '../../src/cached-powers.h', '../../src/char-predicates.cc', '../../src/char-predicates-inl.h', '../../src/char-predicates.h', '../../src/checks.cc', '../../src/checks.h', '../../src/circular-queue-inl.h', '../../src/circular-queue.h', '../../src/code-factory.cc', '../../src/code-factory.h', '../../src/code-stubs.cc', '../../src/code-stubs.h', '../../src/code-stubs-hydrogen.cc', '../../src/code.h', '../../src/codegen.cc', '../../src/codegen.h', '../../src/compilation-cache.cc', '../../src/compilation-cache.h', '../../src/compilation-dependencies.cc', '../../src/compilation-dependencies.h', '../../src/compilation-statistics.cc', '../../src/compilation-statistics.h', '../../src/compiler/access-builder.cc', '../../src/compiler/access-builder.h', '../../src/compiler/all-nodes.cc', '../../src/compiler/all-nodes.h', '../../src/compiler/ast-graph-builder.cc', '../../src/compiler/ast-graph-builder.h', '../../src/compiler/ast-loop-assignment-analyzer.cc', '../../src/compiler/ast-loop-assignment-analyzer.h', '../../src/compiler/basic-block-instrumentor.cc', '../../src/compiler/basic-block-instrumentor.h', '../../src/compiler/change-lowering.cc', '../../src/compiler/change-lowering.h', '../../src/compiler/coalesced-live-ranges.cc', '../../src/compiler/coalesced-live-ranges.h', '../../src/compiler/code-generator-impl.h', '../../src/compiler/code-generator.cc', '../../src/compiler/code-generator.h', '../../src/compiler/common-node-cache.cc', '../../src/compiler/common-node-cache.h', '../../src/compiler/common-operator-reducer.cc', '../../src/compiler/common-operator-reducer.h', '../../src/compiler/common-operator.cc', '../../src/compiler/common-operator.h', '../../src/compiler/control-builders.cc', '../../src/compiler/control-builders.h', '../../src/compiler/control-equivalence.cc', '../../src/compiler/control-equivalence.h', '../../src/compiler/control-flow-optimizer.cc', '../../src/compiler/control-flow-optimizer.h', '../../src/compiler/dead-code-elimination.cc', '../../src/compiler/dead-code-elimination.h', '../../src/compiler/diamond.h', '../../src/compiler/frame.h', '../../src/compiler/frame-elider.cc', '../../src/compiler/frame-elider.h', "../../src/compiler/frame-states.cc", "../../src/compiler/frame-states.h", '../../src/compiler/gap-resolver.cc', '../../src/compiler/gap-resolver.h', '../../src/compiler/graph-builder.h', '../../src/compiler/graph-reducer.cc', '../../src/compiler/graph-reducer.h', '../../src/compiler/graph-replay.cc', '../../src/compiler/graph-replay.h', '../../src/compiler/graph-trimmer.cc', '../../src/compiler/graph-trimmer.h', '../../src/compiler/graph-visualizer.cc', '../../src/compiler/graph-visualizer.h', '../../src/compiler/graph.cc', '../../src/compiler/graph.h', '../../src/compiler/greedy-allocator.cc', '../../src/compiler/greedy-allocator.h', '../../src/compiler/instruction-codes.h', '../../src/compiler/instruction-selector-impl.h', '../../src/compiler/instruction-selector.cc', '../../src/compiler/instruction-selector.h', '../../src/compiler/instruction.cc', '../../src/compiler/instruction.h', '../../src/compiler/js-builtin-reducer.cc', '../../src/compiler/js-builtin-reducer.h', '../../src/compiler/js-context-specialization.cc', '../../src/compiler/js-context-specialization.h', '../../src/compiler/js-frame-specialization.cc', '../../src/compiler/js-frame-specialization.h', '../../src/compiler/js-generic-lowering.cc', '../../src/compiler/js-generic-lowering.h', '../../src/compiler/js-graph.cc', '../../src/compiler/js-graph.h', '../../src/compiler/js-inlining.cc', '../../src/compiler/js-inlining.h', '../../src/compiler/js-intrinsic-lowering.cc', '../../src/compiler/js-intrinsic-lowering.h', '../../src/compiler/js-operator.cc', '../../src/compiler/js-operator.h', '../../src/compiler/js-type-feedback.cc', '../../src/compiler/js-type-feedback.h', '../../src/compiler/js-typed-lowering.cc', '../../src/compiler/js-typed-lowering.h', '../../src/compiler/jump-threading.cc', '../../src/compiler/jump-threading.h', '../../src/compiler/linkage-impl.h', '../../src/compiler/linkage.cc', '../../src/compiler/linkage.h', '../../src/compiler/liveness-analyzer.cc', '../../src/compiler/liveness-analyzer.h', '../../src/compiler/load-elimination.cc', '../../src/compiler/load-elimination.h', '../../src/compiler/loop-analysis.cc', '../../src/compiler/loop-analysis.h', '../../src/compiler/loop-peeling.cc', '../../src/compiler/loop-peeling.h', '../../src/compiler/machine-operator-reducer.cc', '../../src/compiler/machine-operator-reducer.h', '../../src/compiler/machine-operator.cc', '../../src/compiler/machine-operator.h', '../../src/compiler/machine-type.cc', '../../src/compiler/machine-type.h', '../../src/compiler/move-optimizer.cc', '../../src/compiler/move-optimizer.h', '../../src/compiler/node-aux-data.h', '../../src/compiler/node-cache.cc', '../../src/compiler/node-cache.h', '../../src/compiler/node-marker.cc', '../../src/compiler/node-marker.h', '../../src/compiler/node-matchers.cc', '../../src/compiler/node-matchers.h', '../../src/compiler/node-properties.cc', '../../src/compiler/node-properties.h', '../../src/compiler/node.cc', '../../src/compiler/node.h', '../../src/compiler/opcodes.cc', '../../src/compiler/opcodes.h', '../../src/compiler/operator-properties.cc', '../../src/compiler/operator-properties.h', '../../src/compiler/operator.cc', '../../src/compiler/operator.h', '../../src/compiler/osr.cc', '../../src/compiler/osr.h', '../../src/compiler/pipeline.cc', '../../src/compiler/pipeline.h', '../../src/compiler/pipeline-statistics.cc', '../../src/compiler/pipeline-statistics.h', '../../src/compiler/raw-machine-assembler.cc', '../../src/compiler/raw-machine-assembler.h', '../../src/compiler/register-allocator.cc', '../../src/compiler/register-allocator.h', '../../src/compiler/register-allocator-verifier.cc', '../../src/compiler/register-allocator-verifier.h', '../../src/compiler/register-configuration.cc', '../../src/compiler/register-configuration.h', '../../src/compiler/representation-change.h', '../../src/compiler/schedule.cc', '../../src/compiler/schedule.h', '../../src/compiler/scheduler.cc', '../../src/compiler/scheduler.h', '../../src/compiler/select-lowering.cc', '../../src/compiler/select-lowering.h', '../../src/compiler/simplified-lowering.cc', '../../src/compiler/simplified-lowering.h', '../../src/compiler/simplified-operator-reducer.cc', '../../src/compiler/simplified-operator-reducer.h', '../../src/compiler/simplified-operator.cc', '../../src/compiler/simplified-operator.h', '../../src/compiler/source-position.cc', '../../src/compiler/source-position.h', '../../src/compiler/state-values-utils.cc', '../../src/compiler/state-values-utils.h', '../../src/compiler/tail-call-optimization.cc', '../../src/compiler/tail-call-optimization.h', '../../src/compiler/typer.cc', '../../src/compiler/typer.h', '../../src/compiler/value-numbering-reducer.cc', '../../src/compiler/value-numbering-reducer.h', '../../src/compiler/verifier.cc', '../../src/compiler/verifier.h', '../../src/compiler/zone-pool.cc', '../../src/compiler/zone-pool.h', '../../src/compiler.cc', '../../src/compiler.h', '../../src/contexts.cc', '../../src/contexts.h', '../../src/conversions-inl.h', '../../src/conversions.cc', '../../src/conversions.h', '../../src/counters.cc', '../../src/counters.h', '../../src/cpu-profiler-inl.h', '../../src/cpu-profiler.cc', '../../src/cpu-profiler.h', '../../src/date.cc', '../../src/date.h', '../../src/dateparser-inl.h', '../../src/dateparser.cc', '../../src/dateparser.h', '../../src/debug.cc', '../../src/debug.h', '../../src/deoptimizer.cc', '../../src/deoptimizer.h', '../../src/disasm.h', '../../src/disassembler.cc', '../../src/disassembler.h', '../../src/diy-fp.cc', '../../src/diy-fp.h', '../../src/double.h', '../../src/dtoa.cc', '../../src/dtoa.h', '../../src/effects.h', '../../src/elements-kind.cc', '../../src/elements-kind.h', '../../src/elements.cc', '../../src/elements.h', '../../src/execution.cc', '../../src/execution.h', '../../src/expression-classifier.h', '../../src/extensions/externalize-string-extension.cc', '../../src/extensions/externalize-string-extension.h', '../../src/extensions/free-buffer-extension.cc', '../../src/extensions/free-buffer-extension.h', '../../src/extensions/gc-extension.cc', '../../src/extensions/gc-extension.h', '../../src/extensions/statistics-extension.cc', '../../src/extensions/statistics-extension.h', '../../src/extensions/trigger-failure-extension.cc', '../../src/extensions/trigger-failure-extension.h', '../../src/factory.cc', '../../src/factory.h', '../../src/fast-dtoa.cc', '../../src/fast-dtoa.h', '../../src/field-index.h', '../../src/field-index-inl.h', '../../src/fixed-dtoa.cc', '../../src/fixed-dtoa.h', '../../src/flag-definitions.h', '../../src/flags.cc', '../../src/flags.h', '../../src/frames-inl.h', '../../src/frames.cc', '../../src/frames.h', '../../src/full-codegen.cc', '../../src/full-codegen.h', '../../src/func-name-inferrer.cc', '../../src/func-name-inferrer.h', '../../src/gdb-jit.cc', '../../src/gdb-jit.h', '../../src/global-handles.cc', '../../src/global-handles.h', '../../src/globals.h', '../../src/handles-inl.h', '../../src/handles.cc', '../../src/handles.h', '../../src/hashmap.h', '../../src/heap-profiler.cc', '../../src/heap-profiler.h', '../../src/heap-snapshot-generator-inl.h', '../../src/heap-snapshot-generator.cc', '../../src/heap-snapshot-generator.h', '../../src/heap/memory-reducer.cc', '../../src/heap/memory-reducer.h', '../../src/heap/gc-idle-time-handler.cc', '../../src/heap/gc-idle-time-handler.h', '../../src/heap/gc-tracer.cc', '../../src/heap/gc-tracer.h', '../../src/heap/heap-inl.h', '../../src/heap/heap.cc', '../../src/heap/heap.h', '../../src/heap/identity-map.cc', '../../src/heap/identity-map.h', '../../src/heap/incremental-marking-inl.h', '../../src/heap/incremental-marking.cc', '../../src/heap/incremental-marking.h', '../../src/heap/mark-compact-inl.h', '../../src/heap/mark-compact.cc', '../../src/heap/mark-compact.h', '../../src/heap/objects-visiting-inl.h', '../../src/heap/objects-visiting.cc', '../../src/heap/objects-visiting.h', '../../src/heap/spaces-inl.h', '../../src/heap/spaces.cc', '../../src/heap/spaces.h', '../../src/heap/store-buffer-inl.h', '../../src/heap/store-buffer.cc', '../../src/heap/store-buffer.h', '../../src/hydrogen-alias-analysis.h', '../../src/hydrogen-bce.cc', '../../src/hydrogen-bce.h', '../../src/hydrogen-bch.cc', '../../src/hydrogen-bch.h', '../../src/hydrogen-canonicalize.cc', '../../src/hydrogen-canonicalize.h', '../../src/hydrogen-check-elimination.cc', '../../src/hydrogen-check-elimination.h', '../../src/hydrogen-dce.cc', '../../src/hydrogen-dce.h', '../../src/hydrogen-dehoist.cc', '../../src/hydrogen-dehoist.h', '../../src/hydrogen-environment-liveness.cc', '../../src/hydrogen-environment-liveness.h', '../../src/hydrogen-escape-analysis.cc', '../../src/hydrogen-escape-analysis.h', '../../src/hydrogen-flow-engine.h', '../../src/hydrogen-instructions.cc', '../../src/hydrogen-instructions.h', '../../src/hydrogen.cc', '../../src/hydrogen.h', '../../src/hydrogen-gvn.cc', '../../src/hydrogen-gvn.h', '../../src/hydrogen-infer-representation.cc', '../../src/hydrogen-infer-representation.h', '../../src/hydrogen-infer-types.cc', '../../src/hydrogen-infer-types.h', '../../src/hydrogen-load-elimination.cc', '../../src/hydrogen-load-elimination.h', '../../src/hydrogen-mark-deoptimize.cc', '../../src/hydrogen-mark-deoptimize.h', '../../src/hydrogen-mark-unreachable.cc', '../../src/hydrogen-mark-unreachable.h', '../../src/hydrogen-osr.cc', '../../src/hydrogen-osr.h', '../../src/hydrogen-range-analysis.cc', '../../src/hydrogen-range-analysis.h', '../../src/hydrogen-redundant-phi.cc', '../../src/hydrogen-redundant-phi.h', '../../src/hydrogen-removable-simulates.cc', '../../src/hydrogen-removable-simulates.h', '../../src/hydrogen-representation-changes.cc', '../../src/hydrogen-representation-changes.h', '../../src/hydrogen-sce.cc', '../../src/hydrogen-sce.h', '../../src/hydrogen-store-elimination.cc', '../../src/hydrogen-store-elimination.h', '../../src/hydrogen-types.cc', '../../src/hydrogen-types.h', '../../src/hydrogen-uint32-analysis.cc', '../../src/hydrogen-uint32-analysis.h', '../../src/i18n.cc', '../../src/i18n.h', '../../src/icu_util.cc', '../../src/icu_util.h', '../../src/ic/access-compiler.cc', '../../src/ic/access-compiler.h', '../../src/ic/call-optimization.cc', '../../src/ic/call-optimization.h', '../../src/ic/handler-compiler.cc', '../../src/ic/handler-compiler.h', '../../src/ic/ic-inl.h', '../../src/ic/ic-state.cc', '../../src/ic/ic-state.h', '../../src/ic/ic.cc', '../../src/ic/ic.h', '../../src/ic/ic-compiler.cc', '../../src/ic/ic-compiler.h', '../../src/interface-descriptors.cc', '../../src/interface-descriptors.h', '../../src/interpreter-irregexp.cc', '../../src/interpreter-irregexp.h', '../../src/isolate.cc', '../../src/isolate.h', '../../src/json-parser.h', '../../src/json-stringifier.h', '../../src/jsregexp-inl.h', '../../src/jsregexp.cc', '../../src/jsregexp.h', '../../src/layout-descriptor-inl.h', '../../src/layout-descriptor.cc', '../../src/layout-descriptor.h', '../../src/list-inl.h', '../../src/list.h', '../../src/lithium-allocator-inl.h', '../../src/lithium-allocator.cc', '../../src/lithium-allocator.h', '../../src/lithium-codegen.cc', '../../src/lithium-codegen.h', '../../src/lithium.cc', '../../src/lithium.h', '../../src/lithium-inl.h', '../../src/liveedit.cc', '../../src/liveedit.h', '../../src/log-inl.h', '../../src/log-utils.cc', '../../src/log-utils.h', '../../src/log.cc', '../../src/log.h', '../../src/lookup-inl.h', '../../src/lookup.cc', '../../src/lookup.h', '../../src/macro-assembler.h', '../../src/messages.cc', '../../src/messages.h', '../../src/modules.cc', '../../src/modules.h', '../../src/msan.h', '../../src/objects-debug.cc', '../../src/objects-inl.h', '../../src/objects-printer.cc', '../../src/objects.cc', '../../src/objects.h', '../../src/optimizing-compile-dispatcher.cc', '../../src/optimizing-compile-dispatcher.h', '../../src/ostreams.cc', '../../src/ostreams.h', '../../src/pattern-rewriter.cc', '../../src/parser.cc', '../../src/parser.h', '../../src/pending-compilation-error-handler.cc', '../../src/pending-compilation-error-handler.h', '../../src/preparse-data-format.h', '../../src/preparse-data.cc', '../../src/preparse-data.h', '../../src/preparser.cc', '../../src/preparser.h', '../../src/prettyprinter.cc', '../../src/prettyprinter.h', '../../src/profile-generator-inl.h', '../../src/profile-generator.cc', '../../src/profile-generator.h', '../../src/property-details.h', '../../src/property.cc', '../../src/property.h', '../../src/prototype.h', '../../src/regexp-macro-assembler-irregexp-inl.h', '../../src/regexp-macro-assembler-irregexp.cc', '../../src/regexp-macro-assembler-irregexp.h', '../../src/regexp-macro-assembler-tracer.cc', '../../src/regexp-macro-assembler-tracer.h', '../../src/regexp-macro-assembler.cc', '../../src/regexp-macro-assembler.h', '../../src/regexp-stack.cc', '../../src/regexp-stack.h', '../../src/rewriter.cc', '../../src/rewriter.h', '../../src/runtime-profiler.cc', '../../src/runtime-profiler.h', '../../src/runtime/runtime-array.cc', '../../src/runtime/runtime-atomics.cc', '../../src/runtime/runtime-classes.cc', '../../src/runtime/runtime-collections.cc', '../../src/runtime/runtime-compiler.cc', '../../src/runtime/runtime-date.cc', '../../src/runtime/runtime-debug.cc', '../../src/runtime/runtime-forin.cc', '../../src/runtime/runtime-function.cc', '../../src/runtime/runtime-generator.cc', '../../src/runtime/runtime-i18n.cc', '../../src/runtime/runtime-internal.cc', '../../src/runtime/runtime-json.cc', '../../src/runtime/runtime-literals.cc', '../../src/runtime/runtime-liveedit.cc', '../../src/runtime/runtime-maths.cc', '../../src/runtime/runtime-numbers.cc', '../../src/runtime/runtime-object.cc', '../../src/runtime/runtime-observe.cc', '../../src/runtime/runtime-proxy.cc', '../../src/runtime/runtime-regexp.cc', '../../src/runtime/runtime-scopes.cc', '../../src/runtime/runtime-strings.cc', '../../src/runtime/runtime-symbol.cc', '../../src/runtime/runtime-test.cc', '../../src/runtime/runtime-typedarray.cc', '../../src/runtime/runtime-uri.cc', '../../src/runtime/runtime-utils.h', '../../src/runtime/runtime.cc', '../../src/runtime/runtime.h', '../../src/safepoint-table.cc', '../../src/safepoint-table.h', '../../src/sampler.cc', '../../src/sampler.h', '../../src/scanner-character-streams.cc', '../../src/scanner-character-streams.h', '../../src/scanner.cc', '../../src/scanner.h', '../../src/scopeinfo.cc', '../../src/scopeinfo.h', '../../src/scopes.cc', '../../src/scopes.h', '../../src/signature.h', '../../src/simulator.h', '../../src/small-pointer-list.h', '../../src/smart-pointers.h', '../../src/snapshot/natives.h', '../../src/snapshot/serialize.cc', '../../src/snapshot/serialize.h', '../../src/snapshot/snapshot.h', '../../src/snapshot/snapshot-common.cc', '../../src/snapshot/snapshot-source-sink.cc', '../../src/snapshot/snapshot-source-sink.h', '../../src/splay-tree.h', '../../src/splay-tree-inl.h', '../../src/startup-data-util.cc', '../../src/startup-data-util.h', '../../src/string-builder.cc', '../../src/string-builder.h', '../../src/string-search.cc', '../../src/string-search.h', '../../src/string-stream.cc', '../../src/string-stream.h', '../../src/strings-storage.cc', '../../src/strings-storage.h', '../../src/strtod.cc', '../../src/strtod.h', '../../src/ic/stub-cache.cc', '../../src/ic/stub-cache.h', '../../src/token.cc', '../../src/token.h', '../../src/transitions-inl.h', '../../src/transitions.cc', '../../src/transitions.h', '../../src/type-feedback-vector-inl.h', '../../src/type-feedback-vector.cc', '../../src/type-feedback-vector.h', '../../src/type-info.cc', '../../src/type-info.h', '../../src/types-inl.h', '../../src/types.cc', '../../src/types.h', '../../src/typing.cc', '../../src/typing.h', '../../src/unbound-queue-inl.h', '../../src/unbound-queue.h', '../../src/unicode-inl.h', '../../src/unicode.cc', '../../src/unicode.h', '../../src/unicode-decoder.cc', '../../src/unicode-decoder.h', '../../src/unique.h', '../../src/utils.cc', '../../src/utils.h', '../../src/v8.cc', '../../src/v8.h', '../../src/v8memory.h', '../../src/v8threads.cc', '../../src/v8threads.h', '../../src/variables.cc', '../../src/variables.h', '../../src/vector.h', '../../src/version.cc', '../../src/version.h', '../../src/vm-state-inl.h', '../../src/vm-state.h', '../../src/zone.cc', '../../src/zone.h', '../../src/zone-allocator.h', '../../src/zone-containers.h', '../../src/third_party/fdlibm/fdlibm.cc', '../../src/third_party/fdlibm/fdlibm.h', ], 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], }, { 'toolsets': ['target'], }], ['v8_target_arch=="arm"', { 'sources': [ ### gcmole(arch:arm) ### '../../src/arm/assembler-arm-inl.h', '../../src/arm/assembler-arm.cc', '../../src/arm/assembler-arm.h', '../../src/arm/builtins-arm.cc', '../../src/arm/code-stubs-arm.cc', '../../src/arm/code-stubs-arm.h', '../../src/arm/codegen-arm.cc', '../../src/arm/codegen-arm.h', '../../src/arm/constants-arm.h', '../../src/arm/constants-arm.cc', '../../src/arm/cpu-arm.cc', '../../src/arm/debug-arm.cc', '../../src/arm/deoptimizer-arm.cc', '../../src/arm/disasm-arm.cc', '../../src/arm/frames-arm.cc', '../../src/arm/frames-arm.h', '../../src/arm/full-codegen-arm.cc', '../../src/arm/interface-descriptors-arm.cc', '../../src/arm/interface-descriptors-arm.h', '../../src/arm/lithium-arm.cc', '../../src/arm/lithium-arm.h', '../../src/arm/lithium-codegen-arm.cc', '../../src/arm/lithium-codegen-arm.h', '../../src/arm/lithium-gap-resolver-arm.cc', '../../src/arm/lithium-gap-resolver-arm.h', '../../src/arm/macro-assembler-arm.cc', '../../src/arm/macro-assembler-arm.h', '../../src/arm/regexp-macro-assembler-arm.cc', '../../src/arm/regexp-macro-assembler-arm.h', '../../src/arm/simulator-arm.cc', '../../src/arm/simulator-arm.h', '../../src/compiler/arm/code-generator-arm.cc', '../../src/compiler/arm/instruction-codes-arm.h', '../../src/compiler/arm/instruction-selector-arm.cc', '../../src/compiler/arm/linkage-arm.cc', '../../src/ic/arm/access-compiler-arm.cc', '../../src/ic/arm/handler-compiler-arm.cc', '../../src/ic/arm/ic-arm.cc', '../../src/ic/arm/ic-compiler-arm.cc', '../../src/ic/arm/stub-cache-arm.cc', ], }], ['v8_target_arch=="arm64"', { 'sources': [ ### gcmole(arch:arm64) ### '../../src/arm64/assembler-arm64.cc', '../../src/arm64/assembler-arm64.h', '../../src/arm64/assembler-arm64-inl.h', '../../src/arm64/builtins-arm64.cc', '../../src/arm64/codegen-arm64.cc', '../../src/arm64/codegen-arm64.h', '../../src/arm64/code-stubs-arm64.cc', '../../src/arm64/code-stubs-arm64.h', '../../src/arm64/constants-arm64.h', '../../src/arm64/cpu-arm64.cc', '../../src/arm64/debug-arm64.cc', '../../src/arm64/decoder-arm64.cc', '../../src/arm64/decoder-arm64.h', '../../src/arm64/decoder-arm64-inl.h', '../../src/arm64/delayed-masm-arm64.cc', '../../src/arm64/delayed-masm-arm64.h', '../../src/arm64/delayed-masm-arm64-inl.h', '../../src/arm64/deoptimizer-arm64.cc', '../../src/arm64/disasm-arm64.cc', '../../src/arm64/disasm-arm64.h', '../../src/arm64/frames-arm64.cc', '../../src/arm64/frames-arm64.h', '../../src/arm64/full-codegen-arm64.cc', '../../src/arm64/instructions-arm64.cc', '../../src/arm64/instructions-arm64.h', '../../src/arm64/instrument-arm64.cc', '../../src/arm64/instrument-arm64.h', '../../src/arm64/interface-descriptors-arm64.cc', '../../src/arm64/interface-descriptors-arm64.h', '../../src/arm64/lithium-arm64.cc', '../../src/arm64/lithium-arm64.h', '../../src/arm64/lithium-codegen-arm64.cc', '../../src/arm64/lithium-codegen-arm64.h', '../../src/arm64/lithium-gap-resolver-arm64.cc', '../../src/arm64/lithium-gap-resolver-arm64.h', '../../src/arm64/macro-assembler-arm64.cc', '../../src/arm64/macro-assembler-arm64.h', '../../src/arm64/macro-assembler-arm64-inl.h', '../../src/arm64/regexp-macro-assembler-arm64.cc', '../../src/arm64/regexp-macro-assembler-arm64.h', '../../src/arm64/simulator-arm64.cc', '../../src/arm64/simulator-arm64.h', '../../src/arm64/utils-arm64.cc', '../../src/arm64/utils-arm64.h', '../../src/compiler/arm64/code-generator-arm64.cc', '../../src/compiler/arm64/instruction-codes-arm64.h', '../../src/compiler/arm64/instruction-selector-arm64.cc', '../../src/compiler/arm64/linkage-arm64.cc', '../../src/ic/arm64/access-compiler-arm64.cc', '../../src/ic/arm64/handler-compiler-arm64.cc', '../../src/ic/arm64/ic-arm64.cc', '../../src/ic/arm64/ic-compiler-arm64.cc', '../../src/ic/arm64/stub-cache-arm64.cc', ], }], ['v8_target_arch=="ia32"', { 'sources': [ ### gcmole(arch:ia32) ### '../../src/ia32/assembler-ia32-inl.h', '../../src/ia32/assembler-ia32.cc', '../../src/ia32/assembler-ia32.h', '../../src/ia32/builtins-ia32.cc', '../../src/ia32/code-stubs-ia32.cc', '../../src/ia32/code-stubs-ia32.h', '../../src/ia32/codegen-ia32.cc', '../../src/ia32/codegen-ia32.h', '../../src/ia32/cpu-ia32.cc', '../../src/ia32/debug-ia32.cc', '../../src/ia32/deoptimizer-ia32.cc', '../../src/ia32/disasm-ia32.cc', '../../src/ia32/frames-ia32.cc', '../../src/ia32/frames-ia32.h', '../../src/ia32/full-codegen-ia32.cc', '../../src/ia32/interface-descriptors-ia32.cc', '../../src/ia32/lithium-codegen-ia32.cc', '../../src/ia32/lithium-codegen-ia32.h', '../../src/ia32/lithium-gap-resolver-ia32.cc', '../../src/ia32/lithium-gap-resolver-ia32.h', '../../src/ia32/lithium-ia32.cc', '../../src/ia32/lithium-ia32.h', '../../src/ia32/macro-assembler-ia32.cc', '../../src/ia32/macro-assembler-ia32.h', '../../src/ia32/regexp-macro-assembler-ia32.cc', '../../src/ia32/regexp-macro-assembler-ia32.h', '../../src/compiler/ia32/code-generator-ia32.cc', '../../src/compiler/ia32/instruction-codes-ia32.h', '../../src/compiler/ia32/instruction-selector-ia32.cc', '../../src/compiler/ia32/linkage-ia32.cc', '../../src/ic/ia32/access-compiler-ia32.cc', '../../src/ic/ia32/handler-compiler-ia32.cc', '../../src/ic/ia32/ic-ia32.cc', '../../src/ic/ia32/ic-compiler-ia32.cc', '../../src/ic/ia32/stub-cache-ia32.cc', ], }], ['v8_target_arch=="x87"', { 'sources': [ ### gcmole(arch:x87) ### '../../src/x87/assembler-x87-inl.h', '../../src/x87/assembler-x87.cc', '../../src/x87/assembler-x87.h', '../../src/x87/builtins-x87.cc', '../../src/x87/code-stubs-x87.cc', '../../src/x87/code-stubs-x87.h', '../../src/x87/codegen-x87.cc', '../../src/x87/codegen-x87.h', '../../src/x87/cpu-x87.cc', '../../src/x87/debug-x87.cc', '../../src/x87/deoptimizer-x87.cc', '../../src/x87/disasm-x87.cc', '../../src/x87/frames-x87.cc', '../../src/x87/frames-x87.h', '../../src/x87/full-codegen-x87.cc', '../../src/x87/interface-descriptors-x87.cc', '../../src/x87/lithium-codegen-x87.cc', '../../src/x87/lithium-codegen-x87.h', '../../src/x87/lithium-gap-resolver-x87.cc', '../../src/x87/lithium-gap-resolver-x87.h', '../../src/x87/lithium-x87.cc', '../../src/x87/lithium-x87.h', '../../src/x87/macro-assembler-x87.cc', '../../src/x87/macro-assembler-x87.h', '../../src/x87/regexp-macro-assembler-x87.cc', '../../src/x87/regexp-macro-assembler-x87.h', '../../src/compiler/x87/code-generator-x87.cc', '../../src/compiler/x87/instruction-codes-x87.h', '../../src/compiler/x87/instruction-selector-x87.cc', '../../src/compiler/x87/linkage-x87.cc', '../../src/ic/x87/access-compiler-x87.cc', '../../src/ic/x87/handler-compiler-x87.cc', '../../src/ic/x87/ic-x87.cc', '../../src/ic/x87/ic-compiler-x87.cc', '../../src/ic/x87/stub-cache-x87.cc', ], }], ['v8_target_arch=="mips" or v8_target_arch=="mipsel"', { 'sources': [ ### gcmole(arch:mipsel) ### '../../src/mips/assembler-mips.cc', '../../src/mips/assembler-mips.h', '../../src/mips/assembler-mips-inl.h', '../../src/mips/builtins-mips.cc', '../../src/mips/codegen-mips.cc', '../../src/mips/codegen-mips.h', '../../src/mips/code-stubs-mips.cc', '../../src/mips/code-stubs-mips.h', '../../src/mips/constants-mips.cc', '../../src/mips/constants-mips.h', '../../src/mips/cpu-mips.cc', '../../src/mips/debug-mips.cc', '../../src/mips/deoptimizer-mips.cc', '../../src/mips/disasm-mips.cc', '../../src/mips/frames-mips.cc', '../../src/mips/frames-mips.h', '../../src/mips/full-codegen-mips.cc', '../../src/mips/interface-descriptors-mips.cc', '../../src/mips/lithium-codegen-mips.cc', '../../src/mips/lithium-codegen-mips.h', '../../src/mips/lithium-gap-resolver-mips.cc', '../../src/mips/lithium-gap-resolver-mips.h', '../../src/mips/lithium-mips.cc', '../../src/mips/lithium-mips.h', '../../src/mips/macro-assembler-mips.cc', '../../src/mips/macro-assembler-mips.h', '../../src/mips/regexp-macro-assembler-mips.cc', '../../src/mips/regexp-macro-assembler-mips.h', '../../src/mips/simulator-mips.cc', '../../src/mips/simulator-mips.h', '../../src/compiler/mips/code-generator-mips.cc', '../../src/compiler/mips/instruction-codes-mips.h', '../../src/compiler/mips/instruction-selector-mips.cc', '../../src/compiler/mips/linkage-mips.cc', '../../src/ic/mips/access-compiler-mips.cc', '../../src/ic/mips/handler-compiler-mips.cc', '../../src/ic/mips/ic-mips.cc', '../../src/ic/mips/ic-compiler-mips.cc', '../../src/ic/mips/stub-cache-mips.cc', ], }], ['v8_target_arch=="mips64el"', { 'sources': [ ### gcmole(arch:mips64el) ### '../../src/mips64/assembler-mips64.cc', '../../src/mips64/assembler-mips64.h', '../../src/mips64/assembler-mips64-inl.h', '../../src/mips64/builtins-mips64.cc', '../../src/mips64/codegen-mips64.cc', '../../src/mips64/codegen-mips64.h', '../../src/mips64/code-stubs-mips64.cc', '../../src/mips64/code-stubs-mips64.h', '../../src/mips64/constants-mips64.cc', '../../src/mips64/constants-mips64.h', '../../src/mips64/cpu-mips64.cc', '../../src/mips64/debug-mips64.cc', '../../src/mips64/deoptimizer-mips64.cc', '../../src/mips64/disasm-mips64.cc', '../../src/mips64/frames-mips64.cc', '../../src/mips64/frames-mips64.h', '../../src/mips64/full-codegen-mips64.cc', '../../src/mips64/interface-descriptors-mips64.cc', '../../src/mips64/lithium-codegen-mips64.cc', '../../src/mips64/lithium-codegen-mips64.h', '../../src/mips64/lithium-gap-resolver-mips64.cc', '../../src/mips64/lithium-gap-resolver-mips64.h', '../../src/mips64/lithium-mips64.cc', '../../src/mips64/lithium-mips64.h', '../../src/mips64/macro-assembler-mips64.cc', '../../src/mips64/macro-assembler-mips64.h', '../../src/mips64/regexp-macro-assembler-mips64.cc', '../../src/mips64/regexp-macro-assembler-mips64.h', '../../src/mips64/simulator-mips64.cc', '../../src/mips64/simulator-mips64.h', '../../src/compiler/mips64/code-generator-mips64.cc', '../../src/compiler/mips64/instruction-codes-mips64.h', '../../src/compiler/mips64/instruction-selector-mips64.cc', '../../src/compiler/mips64/linkage-mips64.cc', '../../src/ic/mips64/access-compiler-mips64.cc', '../../src/ic/mips64/handler-compiler-mips64.cc', '../../src/ic/mips64/ic-mips64.cc', '../../src/ic/mips64/ic-compiler-mips64.cc', '../../src/ic/mips64/stub-cache-mips64.cc', ], }], ['v8_target_arch=="x64" or v8_target_arch=="x32"', { 'sources': [ ### gcmole(arch:x64) ### '../../src/x64/assembler-x64-inl.h', '../../src/x64/assembler-x64.cc', '../../src/x64/assembler-x64.h', '../../src/x64/builtins-x64.cc', '../../src/x64/code-stubs-x64.cc', '../../src/x64/code-stubs-x64.h', '../../src/x64/codegen-x64.cc', '../../src/x64/codegen-x64.h', '../../src/x64/cpu-x64.cc', '../../src/x64/debug-x64.cc', '../../src/x64/deoptimizer-x64.cc', '../../src/x64/disasm-x64.cc', '../../src/x64/frames-x64.cc', '../../src/x64/frames-x64.h', '../../src/x64/full-codegen-x64.cc', '../../src/x64/interface-descriptors-x64.cc', '../../src/x64/lithium-codegen-x64.cc', '../../src/x64/lithium-codegen-x64.h', '../../src/x64/lithium-gap-resolver-x64.cc', '../../src/x64/lithium-gap-resolver-x64.h', '../../src/x64/lithium-x64.cc', '../../src/x64/lithium-x64.h', '../../src/x64/macro-assembler-x64.cc', '../../src/x64/macro-assembler-x64.h', '../../src/x64/regexp-macro-assembler-x64.cc', '../../src/x64/regexp-macro-assembler-x64.h', '../../src/ic/x64/access-compiler-x64.cc', '../../src/ic/x64/handler-compiler-x64.cc', '../../src/ic/x64/ic-x64.cc', '../../src/ic/x64/ic-compiler-x64.cc', '../../src/ic/x64/stub-cache-x64.cc', ], }], ['v8_target_arch=="x64"', { 'sources': [ '../../src/compiler/x64/code-generator-x64.cc', '../../src/compiler/x64/instruction-codes-x64.h', '../../src/compiler/x64/instruction-selector-x64.cc', '../../src/compiler/x64/linkage-x64.cc', ], }], ['v8_target_arch=="ppc" or v8_target_arch=="ppc64"', { 'sources': [ ### gcmole(arch:ppc) ### '../../src/ppc/assembler-ppc-inl.h', '../../src/ppc/assembler-ppc.cc', '../../src/ppc/assembler-ppc.h', '../../src/ppc/builtins-ppc.cc', '../../src/ppc/code-stubs-ppc.cc', '../../src/ppc/code-stubs-ppc.h', '../../src/ppc/codegen-ppc.cc', '../../src/ppc/codegen-ppc.h', '../../src/ppc/constants-ppc.h', '../../src/ppc/constants-ppc.cc', '../../src/ppc/cpu-ppc.cc', '../../src/ppc/debug-ppc.cc', '../../src/ppc/deoptimizer-ppc.cc', '../../src/ppc/disasm-ppc.cc', '../../src/ppc/frames-ppc.cc', '../../src/ppc/frames-ppc.h', '../../src/ppc/full-codegen-ppc.cc', '../../src/ppc/interface-descriptors-ppc.cc', '../../src/ppc/interface-descriptors-ppc.h', '../../src/ppc/lithium-ppc.cc', '../../src/ppc/lithium-ppc.h', '../../src/ppc/lithium-codegen-ppc.cc', '../../src/ppc/lithium-codegen-ppc.h', '../../src/ppc/lithium-gap-resolver-ppc.cc', '../../src/ppc/lithium-gap-resolver-ppc.h', '../../src/ppc/macro-assembler-ppc.cc', '../../src/ppc/macro-assembler-ppc.h', '../../src/ppc/regexp-macro-assembler-ppc.cc', '../../src/ppc/regexp-macro-assembler-ppc.h', '../../src/ppc/simulator-ppc.cc', '../../src/ppc/simulator-ppc.h', '../../src/compiler/ppc/code-generator-ppc.cc', '../../src/compiler/ppc/instruction-codes-ppc.h', '../../src/compiler/ppc/instruction-selector-ppc.cc', '../../src/compiler/ppc/linkage-ppc.cc', '../../src/ic/ppc/access-compiler-ppc.cc', '../../src/ic/ppc/handler-compiler-ppc.cc', '../../src/ic/ppc/ic-ppc.cc', '../../src/ic/ppc/ic-compiler-ppc.cc', '../../src/ic/ppc/stub-cache-ppc.cc', ], }], ['OS=="win"', { 'variables': { 'gyp_generators': '\n' % include_target) else: f.write('#include <%s>\n' % include_target) if include_after: for header in include_after.split(':'): f.write('#include %s\n' % header) if options.define: for define in options.define: key, value = define.split('=', 1) # This non-standard pop_macro extension is supported # by compilers we support (GCC, clang). f.write('#pragma pop_macro("%s")\n' % key) def DoMain(argv): return '\n'.join(GeneratorMain(argv)) if __name__ == '__main__': DoMain(sys.argv[1:]) node-v4.2.6/deps/v8/tools/gcmole/bootstrap.sh000755 000766 000024 00000010470 12650222326 021222 0ustar00iojsstaff000000 000000 #!/usr/bin/env bash # Copyright 2013 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This script will build libgcmole.so. Building a recent clang needs a # recent GCC, so if you explicitly want to use GCC 4.8, use: # # CC=gcc-4.8 CPP=cpp-4.8 CXX=g++-4.8 CXXFLAGS=-static-libstdc++ CXXCPP=cpp-4.8 ./bootstrap.sh CLANG_RELEASE=3.5 THIS_DIR="$(dirname "${0}")" LLVM_DIR="${THIS_DIR}/../../third_party/llvm" CLANG_DIR="${LLVM_DIR}/tools/clang" LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project} # Die if any command dies. set -e OS="$(uname -s)" # Xcode and clang don't get along when predictive compilation is enabled. # http://crbug.com/96315 if [[ "${OS}" = "Darwin" ]] && xcodebuild -version | grep -q 'Xcode 3.2' ; then XCONF=com.apple.Xcode if [[ "${GYP_GENERATORS}" != "make" ]] && \ [ "$(defaults read "${XCONF}" EnablePredictiveCompilation)" != "0" ]; then echo echo " HEARKEN!" echo "You're using Xcode3 and you have 'Predictive Compilation' enabled." echo "This does not work well with clang (http://crbug.com/96315)." echo "Disable it in Preferences->Building (lower right), or run" echo " defaults write ${XCONF} EnablePredictiveCompilation -boolean NO" echo "while Xcode is not running." echo fi SUB_VERSION=$(xcodebuild -version | sed -Ene 's/Xcode 3\.2\.([0-9]+)/\1/p') if [[ "${SUB_VERSION}" < 6 ]]; then echo echo " YOUR LD IS BUGGY!" echo "Please upgrade Xcode to at least 3.2.6." echo fi fi echo Getting LLVM r"${CLANG_RELEASE}" in "${LLVM_DIR}" if ! svn co --force \ "${LLVM_REPO_URL}/llvm/branches/release_${CLANG_RELEASE/./}" \ "${LLVM_DIR}"; then echo Checkout failed, retrying rm -rf "${LLVM_DIR}" svn co --force \ "${LLVM_REPO_URL}/llvm/branches/release_${CLANG_RELEASE/./}" \ "${LLVM_DIR}" fi echo Getting clang r"${CLANG_RELEASE}" in "${CLANG_DIR}" svn co --force \ "${LLVM_REPO_URL}/cfe/branches/release_${CLANG_RELEASE/./}" \ "${CLANG_DIR}" # Echo all commands set -x NUM_JOBS=3 if [[ "${OS}" = "Linux" ]]; then NUM_JOBS="$(grep -c "^processor" /proc/cpuinfo)" elif [ "${OS}" = "Darwin" ]; then NUM_JOBS="$(sysctl -n hw.ncpu)" fi # Build clang. cd "${LLVM_DIR}" if [[ ! -f ./config.status ]]; then ../llvm/configure \ --enable-optimized \ --disable-threads \ --disable-pthreads \ --without-llvmgcc \ --without-llvmgxx fi MACOSX_DEPLOYMENT_TARGET=10.5 make -j"${NUM_JOBS}" STRIP_FLAGS= if [ "${OS}" = "Darwin" ]; then # See http://crbug.com/256342 STRIP_FLAGS=-x fi strip ${STRIP_FLAGS} Release+Asserts/bin/clang cd - # Build libgcmole.so make -C "${THIS_DIR}" clean make -C "${THIS_DIR}" LLVM_SRC_ROOT="${LLVM_DIR}" libgcmole.so set +x echo echo You can now run gcmole using this command: echo echo CLANG_BIN=\"third_party/llvm/Release+Asserts/bin\" lua tools/gcmole/gcmole.lua echo node-v4.2.6/deps/v8/tools/gcmole/gccause.lua000644 000766 000024 00000004411 12650222326 020761 0ustar00iojsstaff000000 000000 -- Copyright 2011 the V8 project authors. All rights reserved. -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are -- met: -- -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above -- copyright notice, this list of conditions and the following -- disclaimer in the documentation and/or other materials provided -- with the distribution. -- * Neither the name of Google Inc. nor the names of its -- contributors may be used to endorse or promote products derived -- from this software without specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- This is an auxiliary tool that reads gccauses file generated by -- gcmole.lua and prints tree of the calls that can potentially cause a GC -- inside a given function. -- -- Usage: lua tools/gcmole/gccause.lua -- assert(loadfile "gccauses")() local P = ... local T = {} local function TrackCause(name, lvl) io.write((" "):rep(lvl or 0), name, "\n") if GC[name] then local causes = GC[name] for i = 1, #causes do local f = causes[i] if not T[f] then T[f] = true TrackCause(f, (lvl or 0) + 1) end if f == '' then break end end end end for name, _ in pairs(GC) do if name:match(P) then T = {} TrackCause(name) end end node-v4.2.6/deps/v8/tools/gcmole/gcmole.cc000644 000766 000024 00000105554 12650222326 020433 0ustar00iojsstaff000000 000000 // Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This is clang plugin used by gcmole tool. See README for more details. #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/StmtVisitor.h" #include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/CompilerInstance.h" #include "llvm/Support/raw_ostream.h" #include #include #include #include #include #include namespace { typedef std::string MangledName; typedef std::set CalleesSet; static bool GetMangledName(clang::MangleContext* ctx, const clang::NamedDecl* decl, MangledName* result) { if (!llvm::isa(decl) && !llvm::isa(decl)) { llvm::SmallVector output; llvm::raw_svector_ostream out(output); ctx->mangleName(decl, out); *result = out.str().str(); return true; } return false; } static bool InV8Namespace(const clang::NamedDecl* decl) { return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0; } static std::string EXTERNAL("EXTERNAL"); static std::string STATE_TAG("enum v8::internal::StateTag"); static bool IsExternalVMState(const clang::ValueDecl* var) { const clang::EnumConstantDecl* enum_constant = llvm::dyn_cast(var); if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) { clang::QualType type = enum_constant->getType(); return (type.getAsString() == STATE_TAG); } return false; } struct Resolver { explicit Resolver(clang::ASTContext& ctx) : ctx_(ctx), decl_ctx_(ctx.getTranslationUnitDecl()) { } Resolver(clang::ASTContext& ctx, clang::DeclContext* decl_ctx) : ctx_(ctx), decl_ctx_(decl_ctx) { } clang::DeclarationName ResolveName(const char* n) { clang::IdentifierInfo* ident = &ctx_.Idents.get(n); return ctx_.DeclarationNames.getIdentifier(ident); } Resolver ResolveNamespace(const char* n) { return Resolver(ctx_, Resolve(n)); } template T* Resolve(const char* n) { if (decl_ctx_ == NULL) return NULL; clang::DeclContext::lookup_result result = decl_ctx_->lookup(ResolveName(n)); clang::DeclContext::lookup_iterator end = result.end(); for (clang::DeclContext::lookup_iterator i = result.begin(); i != end; i++) { if (llvm::isa(*i)) return llvm::cast(*i); } return NULL; } private: clang::ASTContext& ctx_; clang::DeclContext* decl_ctx_; }; class CalleesPrinter : public clang::RecursiveASTVisitor { public: explicit CalleesPrinter(clang::MangleContext* ctx) : ctx_(ctx) { } virtual bool VisitCallExpr(clang::CallExpr* expr) { const clang::FunctionDecl* callee = expr->getDirectCallee(); if (callee != NULL) AnalyzeFunction(callee); return true; } virtual bool VisitDeclRefExpr(clang::DeclRefExpr* expr) { // If function mentions EXTERNAL VMState add artificial garbage collection // mark. if (IsExternalVMState(expr->getDecl())) AddCallee("CollectGarbage"); return true; } void AnalyzeFunction(const clang::FunctionDecl* f) { MangledName name; if (InV8Namespace(f) && GetMangledName(ctx_, f, &name)) { AddCallee(name); const clang::FunctionDecl* body = NULL; if (f->hasBody(body) && !Analyzed(name)) { EnterScope(name); TraverseStmt(body->getBody()); LeaveScope(); } } } typedef std::map Callgraph; bool Analyzed(const MangledName& name) { return callgraph_[name] != NULL; } void EnterScope(const MangledName& name) { CalleesSet* callees = callgraph_[name]; if (callees == NULL) { callgraph_[name] = callees = new CalleesSet(); } scopes_.push(callees); } void LeaveScope() { scopes_.pop(); } void AddCallee(const MangledName& name) { if (!scopes_.empty()) scopes_.top()->insert(name); } void PrintCallGraph() { for (Callgraph::const_iterator i = callgraph_.begin(), e = callgraph_.end(); i != e; ++i) { std::cout << i->first << "\n"; CalleesSet* callees = i->second; for (CalleesSet::const_iterator j = callees->begin(), e = callees->end(); j != e; ++j) { std::cout << "\t" << *j << "\n"; } } } private: clang::MangleContext* ctx_; std::stack scopes_; Callgraph callgraph_; }; class FunctionDeclarationFinder : public clang::ASTConsumer, public clang::RecursiveASTVisitor { public: explicit FunctionDeclarationFinder(clang::DiagnosticsEngine& d, clang::SourceManager& sm, const std::vector& args) : d_(d), sm_(sm) {} virtual void HandleTranslationUnit(clang::ASTContext &ctx) { mangle_context_ = clang::ItaniumMangleContext::create(ctx, d_); callees_printer_ = new CalleesPrinter(mangle_context_); TraverseDecl(ctx.getTranslationUnitDecl()); callees_printer_->PrintCallGraph(); } virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { callees_printer_->AnalyzeFunction(decl); return true; } private: clang::DiagnosticsEngine& d_; clang::SourceManager& sm_; clang::MangleContext* mangle_context_; CalleesPrinter* callees_printer_; }; static bool loaded = false; static CalleesSet gc_suspects; static void LoadGCSuspects() { if (loaded) return; std::ifstream fin("gcsuspects"); std::string s; while (fin >> s) gc_suspects.insert(s); loaded = true; } static bool KnownToCauseGC(clang::MangleContext* ctx, const clang::FunctionDecl* decl) { LoadGCSuspects(); if (!InV8Namespace(decl)) return false; MangledName name; if (GetMangledName(ctx, decl, &name)) { return gc_suspects.find(name) != gc_suspects.end(); } return false; } static const int kNoEffect = 0; static const int kCausesGC = 1; static const int kRawDef = 2; static const int kRawUse = 4; static const int kAllEffects = kCausesGC | kRawDef | kRawUse; class Environment; class ExprEffect { public: bool hasGC() { return (effect_ & kCausesGC) != 0; } void setGC() { effect_ |= kCausesGC; } bool hasRawDef() { return (effect_ & kRawDef) != 0; } void setRawDef() { effect_ |= kRawDef; } bool hasRawUse() { return (effect_ & kRawUse) != 0; } void setRawUse() { effect_ |= kRawUse; } static ExprEffect None() { return ExprEffect(kNoEffect, NULL); } static ExprEffect NoneWithEnv(Environment* env) { return ExprEffect(kNoEffect, env); } static ExprEffect RawUse() { return ExprEffect(kRawUse, NULL); } static ExprEffect Merge(ExprEffect a, ExprEffect b); static ExprEffect MergeSeq(ExprEffect a, ExprEffect b); ExprEffect Define(const std::string& name); Environment* env() { return reinterpret_cast(effect_ & ~kAllEffects); } static ExprEffect GC() { return ExprEffect(kCausesGC, NULL); } private: ExprEffect(int effect, Environment* env) : effect_((effect & kAllEffects) | reinterpret_cast(env)) { } intptr_t effect_; }; const std::string BAD_EXPR_MSG("Possible problem with evaluation order."); const std::string DEAD_VAR_MSG("Possibly dead variable."); class Environment { public: Environment() { } static Environment Unreachable() { Environment env; env.live_.set(); return env; } static Environment Merge(const Environment& l, const Environment& r) { return Environment(l, r); } Environment ApplyEffect(ExprEffect effect) const { Environment out = effect.hasGC() ? Environment() : Environment(*this); if (effect.env() != NULL) out.live_ |= effect.env()->live_; return out; } typedef std::map SymbolTable; bool IsAlive(const std::string& name) const { SymbolTable::iterator code = symbol_table_.find(name); if (code == symbol_table_.end()) return false; return live_[code->second]; } bool Equal(const Environment& env) { return live_ == env.live_; } Environment Define(const std::string& name) const { return Environment(*this, SymbolToCode(name)); } void MDefine(const std::string& name) { live_.set(SymbolToCode(name)); } static int SymbolToCode(const std::string& name) { SymbolTable::iterator code = symbol_table_.find(name); if (code == symbol_table_.end()) { int new_code = symbol_table_.size(); symbol_table_.insert(std::make_pair(name, new_code)); return new_code; } return code->second; } static void ClearSymbolTable() { std::vector::iterator end = envs_.end(); for (std::vector::iterator i = envs_.begin(); i != end; ++i) { delete *i; } envs_.clear(); symbol_table_.clear(); } void Print() const { bool comma = false; std::cout << "{"; SymbolTable::iterator end = symbol_table_.end(); for (SymbolTable::iterator i = symbol_table_.begin(); i != end; ++i) { if (live_[i->second]) { if (comma) std::cout << ", "; std::cout << i->first; comma = true; } } std::cout << "}"; } static Environment* Allocate(const Environment& env) { Environment* allocated_env = new Environment(env); envs_.push_back(allocated_env); return allocated_env; } private: Environment(const Environment& l, const Environment& r) : live_(l.live_ & r.live_) { } Environment(const Environment& l, int code) : live_(l.live_) { live_.set(code); } static SymbolTable symbol_table_; static std::vector envs_; static const int kMaxNumberOfLocals = 256; std::bitset live_; friend class ExprEffect; friend class CallProps; }; class CallProps { public: CallProps() : env_(NULL) { } void SetEffect(int arg, ExprEffect in) { if (in.hasGC()) gc_.set(arg); if (in.hasRawDef()) raw_def_.set(arg); if (in.hasRawUse()) raw_use_.set(arg); if (in.env() != NULL) { if (env_ == NULL) env_ = in.env(); env_->live_ |= in.env()->live_; } } ExprEffect ComputeCumulativeEffect(bool result_is_raw) { ExprEffect out = ExprEffect::NoneWithEnv(env_); if (gc_.any()) out.setGC(); if (raw_use_.any()) out.setRawUse(); if (result_is_raw) out.setRawDef(); return out; } bool IsSafe() { if (!gc_.any()) return true; std::bitset raw = (raw_def_ | raw_use_); if (!raw.any()) return true; return gc_.count() == 1 && !((raw ^ gc_).any()); } private: static const int kMaxNumberOfArguments = 64; std::bitset raw_def_; std::bitset raw_use_; std::bitset gc_; Environment* env_; }; Environment::SymbolTable Environment::symbol_table_; std::vector Environment::envs_; ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) { Environment* a_env = a.env(); Environment* b_env = b.env(); Environment* out = NULL; if (a_env != NULL && b_env != NULL) { out = Environment::Allocate(*a_env); out->live_ &= b_env->live_; } return ExprEffect(a.effect_ | b.effect_, out); } ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) { Environment* a_env = b.hasGC() ? NULL : a.env(); Environment* b_env = b.env(); Environment* out = (b_env == NULL) ? a_env : b_env; if (a_env != NULL && b_env != NULL) { out = Environment::Allocate(*b_env); out->live_ |= a_env->live_; } return ExprEffect(a.effect_ | b.effect_, out); } ExprEffect ExprEffect::Define(const std::string& name) { Environment* e = env(); if (e == NULL) { e = Environment::Allocate(Environment()); } e->MDefine(name); return ExprEffect(effect_, e); } static std::string THIS ("this"); class FunctionAnalyzer { public: FunctionAnalyzer(clang::MangleContext* ctx, clang::DeclarationName handle_decl_name, clang::CXXRecordDecl* object_decl, clang::CXXRecordDecl* smi_decl, clang::DiagnosticsEngine& d, clang::SourceManager& sm, bool dead_vars_analysis) : ctx_(ctx), handle_decl_name_(handle_decl_name), object_decl_(object_decl), smi_decl_(smi_decl), d_(d), sm_(sm), block_(NULL), dead_vars_analysis_(dead_vars_analysis) {} // -------------------------------------------------------------------------- // Expressions // -------------------------------------------------------------------------- ExprEffect VisitExpr(clang::Expr* expr, const Environment& env) { #define VISIT(type) \ do { \ clang::type* concrete_expr = llvm::dyn_cast_or_null(expr); \ if (concrete_expr != NULL) { \ return Visit##type(concrete_expr, env); \ } \ } while (0); VISIT(AbstractConditionalOperator); VISIT(AddrLabelExpr); VISIT(ArraySubscriptExpr); VISIT(BinaryOperator); VISIT(BlockExpr); VISIT(CallExpr); VISIT(CastExpr); VISIT(CharacterLiteral); VISIT(ChooseExpr); VISIT(CompoundLiteralExpr); VISIT(CXXBindTemporaryExpr); VISIT(CXXBoolLiteralExpr); VISIT(CXXConstructExpr); VISIT(CXXDefaultArgExpr); VISIT(CXXDeleteExpr); VISIT(CXXDependentScopeMemberExpr); VISIT(CXXNewExpr); VISIT(CXXNoexceptExpr); VISIT(CXXNullPtrLiteralExpr); VISIT(CXXPseudoDestructorExpr); VISIT(CXXScalarValueInitExpr); VISIT(CXXThisExpr); VISIT(CXXThrowExpr); VISIT(CXXTypeidExpr); VISIT(CXXUnresolvedConstructExpr); VISIT(CXXUuidofExpr); VISIT(DeclRefExpr); VISIT(DependentScopeDeclRefExpr); VISIT(DesignatedInitExpr); VISIT(ExprWithCleanups); VISIT(ExtVectorElementExpr); VISIT(FloatingLiteral); VISIT(GNUNullExpr); VISIT(ImaginaryLiteral); VISIT(ImplicitValueInitExpr); VISIT(InitListExpr); VISIT(IntegerLiteral); VISIT(MemberExpr); VISIT(OffsetOfExpr); VISIT(OpaqueValueExpr); VISIT(OverloadExpr); VISIT(PackExpansionExpr); VISIT(ParenExpr); VISIT(ParenListExpr); VISIT(PredefinedExpr); VISIT(ShuffleVectorExpr); VISIT(SizeOfPackExpr); VISIT(StmtExpr); VISIT(StringLiteral); VISIT(SubstNonTypeTemplateParmPackExpr); VISIT(TypeTraitExpr); VISIT(UnaryOperator); VISIT(VAArgExpr); #undef VISIT return ExprEffect::None(); } #define DECL_VISIT_EXPR(type) \ ExprEffect Visit##type (clang::type* expr, const Environment& env) #define IGNORE_EXPR(type) \ ExprEffect Visit##type (clang::type* expr, const Environment& env) { \ return ExprEffect::None(); \ } IGNORE_EXPR(AddrLabelExpr); IGNORE_EXPR(BlockExpr); IGNORE_EXPR(CharacterLiteral); IGNORE_EXPR(ChooseExpr); IGNORE_EXPR(CompoundLiteralExpr); IGNORE_EXPR(CXXBoolLiteralExpr); IGNORE_EXPR(CXXDependentScopeMemberExpr); IGNORE_EXPR(CXXNullPtrLiteralExpr); IGNORE_EXPR(CXXPseudoDestructorExpr); IGNORE_EXPR(CXXScalarValueInitExpr); IGNORE_EXPR(CXXNoexceptExpr); IGNORE_EXPR(CXXTypeidExpr); IGNORE_EXPR(CXXUnresolvedConstructExpr); IGNORE_EXPR(CXXUuidofExpr); IGNORE_EXPR(DependentScopeDeclRefExpr); IGNORE_EXPR(DesignatedInitExpr); IGNORE_EXPR(ExtVectorElementExpr); IGNORE_EXPR(FloatingLiteral); IGNORE_EXPR(ImaginaryLiteral); IGNORE_EXPR(IntegerLiteral); IGNORE_EXPR(OffsetOfExpr); IGNORE_EXPR(ImplicitValueInitExpr); IGNORE_EXPR(PackExpansionExpr); IGNORE_EXPR(PredefinedExpr); IGNORE_EXPR(ShuffleVectorExpr); IGNORE_EXPR(SizeOfPackExpr); IGNORE_EXPR(StmtExpr); IGNORE_EXPR(StringLiteral); IGNORE_EXPR(SubstNonTypeTemplateParmPackExpr); IGNORE_EXPR(TypeTraitExpr); IGNORE_EXPR(VAArgExpr); IGNORE_EXPR(GNUNullExpr); IGNORE_EXPR(OverloadExpr); DECL_VISIT_EXPR(CXXThisExpr) { return Use(expr, expr->getType(), THIS, env); } DECL_VISIT_EXPR(AbstractConditionalOperator) { Environment after_cond = env.ApplyEffect(VisitExpr(expr->getCond(), env)); return ExprEffect::Merge(VisitExpr(expr->getTrueExpr(), after_cond), VisitExpr(expr->getFalseExpr(), after_cond)); } DECL_VISIT_EXPR(ArraySubscriptExpr) { clang::Expr* exprs[2] = {expr->getBase(), expr->getIdx()}; return Par(expr, 2, exprs, env); } bool IsRawPointerVar(clang::Expr* expr, std::string* var_name) { if (llvm::isa(expr)) { *var_name = llvm::cast(expr)->getDecl()->getNameAsString(); return true; } return false; } DECL_VISIT_EXPR(BinaryOperator) { clang::Expr* lhs = expr->getLHS(); clang::Expr* rhs = expr->getRHS(); clang::Expr* exprs[2] = {lhs, rhs}; switch (expr->getOpcode()) { case clang::BO_Comma: return Seq(expr, 2, exprs, env); case clang::BO_LAnd: case clang::BO_LOr: return ExprEffect::Merge(VisitExpr(lhs, env), VisitExpr(rhs, env)); case clang::BO_Assign: { std::string var_name; if (IsRawPointerVar(lhs, &var_name)) { return VisitExpr(rhs, env).Define(var_name); } return Par(expr, 2, exprs, env); } default: return Par(expr, 2, exprs, env); } } DECL_VISIT_EXPR(CXXBindTemporaryExpr) { return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(CXXConstructExpr) { return VisitArguments<>(expr, env); } DECL_VISIT_EXPR(CXXDefaultArgExpr) { return VisitExpr(expr->getExpr(), env); } DECL_VISIT_EXPR(CXXDeleteExpr) { return VisitExpr(expr->getArgument(), env); } DECL_VISIT_EXPR(CXXNewExpr) { return VisitExpr(expr->getInitializer(), env); } DECL_VISIT_EXPR(ExprWithCleanups) { return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(CXXThrowExpr) { return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(InitListExpr) { return Seq(expr, expr->getNumInits(), expr->getInits(), env); } DECL_VISIT_EXPR(MemberExpr) { return VisitExpr(expr->getBase(), env); } DECL_VISIT_EXPR(OpaqueValueExpr) { return VisitExpr(expr->getSourceExpr(), env); } DECL_VISIT_EXPR(ParenExpr) { return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(ParenListExpr) { return Par(expr, expr->getNumExprs(), expr->getExprs(), env); } DECL_VISIT_EXPR(UnaryOperator) { // TODO We are treating all expressions that look like &raw_pointer_var // as definitions of raw_pointer_var. This should be changed to // recognize less generic pattern: // // if (maybe_object->ToObject(&obj)) return maybe_object; // if (expr->getOpcode() == clang::UO_AddrOf) { std::string var_name; if (IsRawPointerVar(expr->getSubExpr(), &var_name)) { return ExprEffect::None().Define(var_name); } } return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(CastExpr) { return VisitExpr(expr->getSubExpr(), env); } DECL_VISIT_EXPR(DeclRefExpr) { return Use(expr, expr->getDecl(), env); } ExprEffect Par(clang::Expr* parent, int n, clang::Expr** exprs, const Environment& env) { CallProps props; for (int i = 0; i < n; ++i) { props.SetEffect(i, VisitExpr(exprs[i], env)); } if (!props.IsSafe()) ReportUnsafe(parent, BAD_EXPR_MSG); return props.ComputeCumulativeEffect(IsRawPointerType(parent->getType())); } ExprEffect Seq(clang::Stmt* parent, int n, clang::Expr** exprs, const Environment& env) { ExprEffect out = ExprEffect::None(); Environment out_env = env; for (int i = 0; i < n; ++i) { out = ExprEffect::MergeSeq(out, VisitExpr(exprs[i], out_env)); out_env = out_env.ApplyEffect(out); } return out; } ExprEffect Use(const clang::Expr* parent, const clang::QualType& var_type, const std::string& var_name, const Environment& env) { if (IsRawPointerType(var_type)) { if (!env.IsAlive(var_name) && dead_vars_analysis_) { ReportUnsafe(parent, DEAD_VAR_MSG); } return ExprEffect::RawUse(); } return ExprEffect::None(); } ExprEffect Use(const clang::Expr* parent, const clang::ValueDecl* var, const Environment& env) { if (IsExternalVMState(var)) { return ExprEffect::GC(); } return Use(parent, var->getType(), var->getNameAsString(), env); } template ExprEffect VisitArguments(ExprType* call, const Environment& env) { CallProps props; VisitArguments<>(call, &props, env); if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); return props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); } template void VisitArguments(ExprType* call, CallProps* props, const Environment& env) { for (unsigned arg = 0; arg < call->getNumArgs(); arg++) { props->SetEffect(arg + 1, VisitExpr(call->getArg(arg), env)); } } ExprEffect VisitCallExpr(clang::CallExpr* call, const Environment& env) { CallProps props; clang::CXXMemberCallExpr* memcall = llvm::dyn_cast_or_null(call); if (memcall != NULL) { clang::Expr* receiver = memcall->getImplicitObjectArgument(); props.SetEffect(0, VisitExpr(receiver, env)); } VisitArguments<>(call, &props, env); if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); ExprEffect out = props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); clang::FunctionDecl* callee = call->getDirectCallee(); if ((callee != NULL) && KnownToCauseGC(ctx_, callee)) { out.setGC(); } return out; } // -------------------------------------------------------------------------- // Statements // -------------------------------------------------------------------------- Environment VisitStmt(clang::Stmt* stmt, const Environment& env) { #define VISIT(type) \ do { \ clang::type* concrete_stmt = llvm::dyn_cast_or_null(stmt); \ if (concrete_stmt != NULL) { \ return Visit##type(concrete_stmt, env); \ } \ } while (0); if (clang::Expr* expr = llvm::dyn_cast_or_null(stmt)) { return env.ApplyEffect(VisitExpr(expr, env)); } VISIT(AsmStmt); VISIT(BreakStmt); VISIT(CompoundStmt); VISIT(ContinueStmt); VISIT(CXXCatchStmt); VISIT(CXXTryStmt); VISIT(DeclStmt); VISIT(DoStmt); VISIT(ForStmt); VISIT(GotoStmt); VISIT(IfStmt); VISIT(IndirectGotoStmt); VISIT(LabelStmt); VISIT(NullStmt); VISIT(ReturnStmt); VISIT(CaseStmt); VISIT(DefaultStmt); VISIT(SwitchStmt); VISIT(WhileStmt); #undef VISIT return env; } #define DECL_VISIT_STMT(type) \ Environment Visit##type (clang::type* stmt, const Environment& env) #define IGNORE_STMT(type) \ Environment Visit##type (clang::type* stmt, const Environment& env) { \ return env; \ } IGNORE_STMT(IndirectGotoStmt); IGNORE_STMT(NullStmt); IGNORE_STMT(AsmStmt); // We are ignoring control flow for simplicity. IGNORE_STMT(GotoStmt); IGNORE_STMT(LabelStmt); // We are ignoring try/catch because V8 does not use them. IGNORE_STMT(CXXCatchStmt); IGNORE_STMT(CXXTryStmt); class Block { public: Block(const Environment& in, FunctionAnalyzer* owner) : in_(in), out_(Environment::Unreachable()), changed_(false), owner_(owner) { parent_ = owner_->EnterBlock(this); } ~Block() { owner_->LeaveBlock(parent_); } void MergeIn(const Environment& env) { Environment old_in = in_; in_ = Environment::Merge(in_, env); changed_ = !old_in.Equal(in_); } bool changed() { if (changed_) { changed_ = false; return true; } return false; } const Environment& in() { return in_; } const Environment& out() { return out_; } void MergeOut(const Environment& env) { out_ = Environment::Merge(out_, env); } void Seq(clang::Stmt* a, clang::Stmt* b, clang::Stmt* c) { Environment a_out = owner_->VisitStmt(a, in()); Environment b_out = owner_->VisitStmt(b, a_out); Environment c_out = owner_->VisitStmt(c, b_out); MergeOut(c_out); } void Seq(clang::Stmt* a, clang::Stmt* b) { Environment a_out = owner_->VisitStmt(a, in()); Environment b_out = owner_->VisitStmt(b, a_out); MergeOut(b_out); } void Loop(clang::Stmt* a, clang::Stmt* b, clang::Stmt* c) { Seq(a, b, c); MergeIn(out()); } void Loop(clang::Stmt* a, clang::Stmt* b) { Seq(a, b); MergeIn(out()); } private: Environment in_; Environment out_; bool changed_; FunctionAnalyzer* owner_; Block* parent_; }; DECL_VISIT_STMT(BreakStmt) { block_->MergeOut(env); return Environment::Unreachable(); } DECL_VISIT_STMT(ContinueStmt) { block_->MergeIn(env); return Environment::Unreachable(); } DECL_VISIT_STMT(CompoundStmt) { Environment out = env; clang::CompoundStmt::body_iterator end = stmt->body_end(); for (clang::CompoundStmt::body_iterator s = stmt->body_begin(); s != end; ++s) { out = VisitStmt(*s, out); } return out; } DECL_VISIT_STMT(WhileStmt) { Block block (env, this); do { block.Loop(stmt->getCond(), stmt->getBody()); } while (block.changed()); return block.out(); } DECL_VISIT_STMT(DoStmt) { Block block (env, this); do { block.Loop(stmt->getBody(), stmt->getCond()); } while (block.changed()); return block.out(); } DECL_VISIT_STMT(ForStmt) { Block block (VisitStmt(stmt->getInit(), env), this); do { block.Loop(stmt->getCond(), stmt->getBody(), stmt->getInc()); } while (block.changed()); return block.out(); } DECL_VISIT_STMT(IfStmt) { Environment cond_out = VisitStmt(stmt->getCond(), env); Environment then_out = VisitStmt(stmt->getThen(), cond_out); Environment else_out = VisitStmt(stmt->getElse(), cond_out); return Environment::Merge(then_out, else_out); } DECL_VISIT_STMT(SwitchStmt) { Block block (env, this); block.Seq(stmt->getCond(), stmt->getBody()); return block.out(); } DECL_VISIT_STMT(CaseStmt) { Environment in = Environment::Merge(env, block_->in()); Environment after_lhs = VisitStmt(stmt->getLHS(), in); return VisitStmt(stmt->getSubStmt(), after_lhs); } DECL_VISIT_STMT(DefaultStmt) { Environment in = Environment::Merge(env, block_->in()); return VisitStmt(stmt->getSubStmt(), in); } DECL_VISIT_STMT(ReturnStmt) { VisitExpr(stmt->getRetValue(), env); return Environment::Unreachable(); } const clang::TagType* ToTagType(const clang::Type* t) { if (t == NULL) { return NULL; } else if (llvm::isa(t)) { return llvm::cast(t); } else if (llvm::isa(t)) { return ToTagType(llvm::cast(t) ->getReplacementType() .getTypePtr()); } else { return NULL; } } bool IsDerivedFrom(clang::CXXRecordDecl* record, clang::CXXRecordDecl* base) { return (record == base) || record->isDerivedFrom(base); } bool IsRawPointerType(clang::QualType qtype) { const clang::PointerType* type = llvm::dyn_cast_or_null(qtype.getTypePtrOrNull()); if (type == NULL) return false; const clang::TagType* pointee = ToTagType(type->getPointeeType().getTypePtr()); if (pointee == NULL) return false; clang::CXXRecordDecl* record = llvm::dyn_cast_or_null(pointee->getDecl()); if (record == NULL) return false; if (!InV8Namespace(record)) return false; if (!record->hasDefinition()) return false; record = record->getDefinition(); return IsDerivedFrom(record, object_decl_) && !IsDerivedFrom(record, smi_decl_); } Environment VisitDecl(clang::Decl* decl, const Environment& env) { if (clang::VarDecl* var = llvm::dyn_cast(decl)) { Environment out = var->hasInit() ? VisitStmt(var->getInit(), env) : env; if (IsRawPointerType(var->getType())) { out = out.Define(var->getNameAsString()); } return out; } // TODO: handle other declarations? return env; } DECL_VISIT_STMT(DeclStmt) { Environment out = env; clang::DeclStmt::decl_iterator end = stmt->decl_end(); for (clang::DeclStmt::decl_iterator decl = stmt->decl_begin(); decl != end; ++decl) { out = VisitDecl(*decl, out); } return out; } void DefineParameters(const clang::FunctionDecl* f, Environment* env) { env->MDefine(THIS); clang::FunctionDecl::param_const_iterator end = f->param_end(); for (clang::FunctionDecl::param_const_iterator p = f->param_begin(); p != end; ++p) { env->MDefine((*p)->getNameAsString()); } } void AnalyzeFunction(const clang::FunctionDecl* f) { const clang::FunctionDecl* body = NULL; if (f->hasBody(body)) { Environment env; DefineParameters(body, &env); VisitStmt(body->getBody(), env); Environment::ClearSymbolTable(); } } Block* EnterBlock(Block* block) { Block* parent = block_; block_ = block; return parent; } void LeaveBlock(Block* block) { block_ = block; } private: void ReportUnsafe(const clang::Expr* expr, const std::string& msg) { d_.Report(clang::FullSourceLoc(expr->getExprLoc(), sm_), d_.getCustomDiagID(clang::DiagnosticsEngine::Warning, "%0")) << msg; } clang::MangleContext* ctx_; clang::DeclarationName handle_decl_name_; clang::CXXRecordDecl* object_decl_; clang::CXXRecordDecl* smi_decl_; clang::DiagnosticsEngine& d_; clang::SourceManager& sm_; Block* block_; bool dead_vars_analysis_; }; class ProblemsFinder : public clang::ASTConsumer, public clang::RecursiveASTVisitor { public: ProblemsFinder(clang::DiagnosticsEngine& d, clang::SourceManager& sm, const std::vector& args) : d_(d), sm_(sm), dead_vars_analysis_(false) { for (unsigned i = 0; i < args.size(); ++i) { if (args[i] == "--dead-vars") { dead_vars_analysis_ = true; } } } virtual void HandleTranslationUnit(clang::ASTContext &ctx) { Resolver r(ctx); clang::CXXRecordDecl* object_decl = r.ResolveNamespace("v8").ResolveNamespace("internal"). Resolve("Object"); clang::CXXRecordDecl* smi_decl = r.ResolveNamespace("v8").ResolveNamespace("internal"). Resolve("Smi"); if (object_decl != NULL) object_decl = object_decl->getDefinition(); if (smi_decl != NULL) smi_decl = smi_decl->getDefinition(); if (object_decl != NULL && smi_decl != NULL) { function_analyzer_ = new FunctionAnalyzer( clang::ItaniumMangleContext::create(ctx, d_), r.ResolveName("Handle"), object_decl, smi_decl, d_, sm_, dead_vars_analysis_); TraverseDecl(ctx.getTranslationUnitDecl()); } else { if (object_decl == NULL) { llvm::errs() << "Failed to resolve v8::internal::Object\n"; } if (smi_decl == NULL) { llvm::errs() << "Failed to resolve v8::internal::Smi\n"; } } } virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { function_analyzer_->AnalyzeFunction(decl); return true; } private: clang::DiagnosticsEngine& d_; clang::SourceManager& sm_; bool dead_vars_analysis_; FunctionAnalyzer* function_analyzer_; }; template class Action : public clang::PluginASTAction { protected: clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef InFile) { return new ConsumerType(CI.getDiagnostics(), CI.getSourceManager(), args_); } bool ParseArgs(const clang::CompilerInstance &CI, const std::vector& args) { args_ = args; return true; } void PrintHelp(llvm::raw_ostream& ros) { } private: std::vector args_; }; } static clang::FrontendPluginRegistry::Add > FindProblems("find-problems", "Find GC-unsafe places."); static clang::FrontendPluginRegistry::Add< Action > DumpCallees("dump-callees", "Dump callees for each function."); node-v4.2.6/deps/v8/tools/gcmole/gcmole.lua000644 000766 000024 00000033064 12650222326 020623 0ustar00iojsstaff000000 000000 -- Copyright 2011 the V8 project authors. All rights reserved. -- Redistribution and use in source and binary forms, with or without -- modification, are permitted provided that the following conditions are -- met: -- -- * Redistributions of source code must retain the above copyright -- notice, this list of conditions and the following disclaimer. -- * Redistributions in binary form must reproduce the above -- copyright notice, this list of conditions and the following -- disclaimer in the documentation and/or other materials provided -- with the distribution. -- * Neither the name of Google Inc. nor the names of its -- contributors may be used to endorse or promote products derived -- from this software without specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- This is main driver for gcmole tool. See README for more details. -- Usage: CLANG_BIN=clang-bin-dir lua tools/gcmole/gcmole.lua [arm|ia32|x64] local DIR = arg[0]:match("^(.+)/[^/]+$") local FLAGS = { -- Do not build gcsuspects file and reuse previously generated one. reuse_gcsuspects = false; -- Don't use parallel python runner. sequential = false; -- Print commands to console before executing them. verbose = false; -- Perform dead variable analysis (generates many false positives). -- TODO add some sort of whiteliste to filter out false positives. dead_vars = false; -- When building gcsuspects whitelist certain functions as if they -- can be causing GC. Currently used to reduce number of false -- positives in dead variables analysis. See TODO for WHITELIST -- below. whitelist = true; } local ARGS = {} for i = 1, #arg do local flag = arg[i]:match "^%-%-([%w_-]+)$" if flag then local no, real_flag = flag:match "^(no)([%w_-]+)$" if real_flag then flag = real_flag end flag = flag:gsub("%-", "_") if FLAGS[flag] ~= nil then FLAGS[flag] = (no ~= "no") else error("Unknown flag: " .. flag) end else table.insert(ARGS, arg[i]) end end local ARCHS = ARGS[1] and { ARGS[1] } or { 'ia32', 'arm', 'x64', 'arm64' } local io = require "io" local os = require "os" function log(...) io.stderr:write(string.format(...)) io.stderr:write "\n" end ------------------------------------------------------------------------------- -- Clang invocation local CLANG_BIN = os.getenv "CLANG_BIN" local CLANG_PLUGINS = os.getenv "CLANG_PLUGINS" if not CLANG_BIN or CLANG_BIN == "" then error "CLANG_BIN not set" end if not CLANG_PLUGINS or CLANG_PLUGINS == "" then CLANG_PLUGINS = DIR end local function MakeClangCommandLine( plugin, plugin_args, triple, arch_define, arch_options) if plugin_args then for i = 1, #plugin_args do plugin_args[i] = "-Xclang -plugin-arg-" .. plugin .. " -Xclang " .. plugin_args[i] end plugin_args = " " .. table.concat(plugin_args, " ") end return CLANG_BIN .. "/clang++ -std=c++11 -c " .. " -Xclang -load -Xclang " .. CLANG_PLUGINS .. "/libgcmole.so" .. " -Xclang -plugin -Xclang " .. plugin .. (plugin_args or "") .. " -Xclang -triple -Xclang " .. triple .. " -D" .. arch_define .. " -DENABLE_DEBUGGER_SUPPORT" .. " -DV8_I18N_SUPPORT" .. " -I./" .. " -Ithird_party/icu/source/common" .. " -Ithird_party/icu/source/i18n" .. " " .. arch_options end local function IterTable(t) return coroutine.wrap(function () for i, v in ipairs(t) do coroutine.yield(v) end end) end local function SplitResults(lines, func) -- Splits the output of parallel.py and calls func on each result. -- Bails out in case of an error in one of the executions. local current = {} local filename = "" for line in lines do local new_file = line:match "^______________ (.*)$" local code = line:match "^______________ finish (%d+) ______________$" if code then if tonumber(code) > 0 then log(table.concat(current, "\n")) log("Failed to examine " .. filename) return false end log("-- %s", filename) func(filename, IterTable(current)) elseif new_file then filename = new_file current = {} else table.insert(current, line) end end return true end function InvokeClangPluginForEachFile(filenames, cfg, func) local cmd_line = MakeClangCommandLine(cfg.plugin, cfg.plugin_args, cfg.triple, cfg.arch_define, cfg.arch_options) if FLAGS.sequential then log("** Sequential execution.") for _, filename in ipairs(filenames) do log("-- %s", filename) local action = cmd_line .. " " .. filename .. " 2>&1" if FLAGS.verbose then print('popen ', action) end local pipe = io.popen(action) func(filename, pipe:lines()) local success = pipe:close() if not success then error("Failed to run: " .. action) end end else log("** Parallel execution.") local action = "python tools/gcmole/parallel.py \"" .. cmd_line .. "\" " .. table.concat(filenames, " ") if FLAGS.verbose then print('popen ', action) end local pipe = io.popen(action) local success = SplitResults(pipe:lines(), func) local closed = pipe:close() if not (success and closed) then error("Failed to run: " .. action) end end end ------------------------------------------------------------------------------- -- GYP file parsing local function ParseGYPFile() local gyp = "" local gyp_files = { "tools/gyp/v8.gyp", "test/cctest/cctest.gyp" } for i = 1, #gyp_files do local f = assert(io.open(gyp_files[i]), "failed to open GYP file") local t = f:read('*a') gyp = gyp .. t f:close() end local result = {} for condition, sources in gyp:gmatch "'sources': %[.-### gcmole%((.-)%) ###(.-)%]" do if result[condition] == nil then result[condition] = {} end for file in sources:gmatch "'%.%./%.%./src/([^']-%.cc)'" do table.insert(result[condition], "src/" .. file) end for file in sources:gmatch "'(test-[^']-%.cc)'" do table.insert(result[condition], "test/cctest/" .. file) end end return result end local function EvaluateCondition(cond, props) if cond == 'all' then return true end local p, v = cond:match "(%w+):(%w+)" assert(p and v, "failed to parse condition: " .. cond) assert(props[p] ~= nil, "undefined configuration property: " .. p) return props[p] == v end local function BuildFileList(sources, props) local list = {} for condition, files in pairs(sources) do if EvaluateCondition(condition, props) then for i = 1, #files do table.insert(list, files[i]) end end end return list end local sources = ParseGYPFile() local function FilesForArch(arch) return BuildFileList(sources, { os = 'linux', arch = arch, mode = 'debug', simulator = ''}) end local mtConfig = {} mtConfig.__index = mtConfig local function config (t) return setmetatable(t, mtConfig) end function mtConfig:extend(t) local e = {} for k, v in pairs(self) do e[k] = v end for k, v in pairs(t) do e[k] = v end return config(e) end local ARCHITECTURES = { ia32 = config { triple = "i586-unknown-linux", arch_define = "V8_TARGET_ARCH_IA32", arch_options = "-m32" }, arm = config { triple = "i586-unknown-linux", arch_define = "V8_TARGET_ARCH_ARM", arch_options = "-m32" }, x64 = config { triple = "x86_64-unknown-linux", arch_define = "V8_TARGET_ARCH_X64", arch_options = "" }, arm64 = config { triple = "x86_64-unknown-linux", arch_define = "V8_TARGET_ARCH_ARM64", arch_options = "" }, } ------------------------------------------------------------------------------- -- GCSuspects Generation local gc, gc_caused, funcs local WHITELIST = { -- The following functions call CEntryStub which is always present. "MacroAssembler.*CallExternalReference", "MacroAssembler.*CallRuntime", "CompileCallLoadPropertyWithInterceptor", "CallIC.*GenerateMiss", -- DirectCEntryStub is a special stub used on ARM. -- It is pinned and always present. "DirectCEntryStub.*GenerateCall", -- TODO GCMole currently is sensitive enough to understand that certain -- functions only cause GC and return Failure simulataneously. -- Callsites of such functions are safe as long as they are properly -- check return value and propagate the Failure to the caller. -- It should be possible to extend GCMole to understand this. "Heap.*AllocateFunctionPrototype", -- Ignore all StateTag methods. "StateTag", -- Ignore printing of elements transition. "PrintElementsTransition" }; local function AddCause(name, cause) local t = gc_caused[name] if not t then t = {} gc_caused[name] = t end table.insert(t, cause) end local function resolve(name) local f = funcs[name] if not f then f = {} funcs[name] = f if name:match "Collect.*Garbage" then gc[name] = true AddCause(name, "") end if FLAGS.whitelist then for i = 1, #WHITELIST do if name:match(WHITELIST[i]) then gc[name] = false end end end end return f end local function parse (filename, lines) local scope for funcname in lines do if funcname:sub(1, 1) ~= '\t' then resolve(funcname) scope = funcname else local name = funcname:sub(2) resolve(name)[scope] = true end end end local function propagate () log "** Propagating GC information" local function mark(from, callers) for caller, _ in pairs(callers) do if gc[caller] == nil then gc[caller] = true mark(caller, funcs[caller]) end AddCause(caller, from) end end for funcname, callers in pairs(funcs) do if gc[funcname] then mark(funcname, callers) end end end local function GenerateGCSuspects(arch, files, cfg) -- Reset the global state. gc, gc_caused, funcs = {}, {}, {} log ("** Building GC Suspects for %s", arch) InvokeClangPluginForEachFile (files, cfg:extend { plugin = "dump-callees" }, parse) propagate() local out = assert(io.open("gcsuspects", "w")) for name, value in pairs(gc) do if value then out:write (name, '\n') end end out:close() local out = assert(io.open("gccauses", "w")) out:write "GC = {" for name, causes in pairs(gc_caused) do out:write("['", name, "'] = {") for i = 1, #causes do out:write ("'", causes[i], "';") end out:write("};\n") end out:write "}" out:close() log ("** GCSuspects generated for %s", arch) end -------------------------------------------------------------------------------- -- Analysis local function CheckCorrectnessForArch(arch) local files = FilesForArch(arch) local cfg = ARCHITECTURES[arch] if not FLAGS.reuse_gcsuspects then GenerateGCSuspects(arch, files, cfg) end local processed_files = 0 local errors_found = false local function SearchForErrors(filename, lines) processed_files = processed_files + 1 for l in lines do errors_found = errors_found or l:match "^[^:]+:%d+:%d+:" or l:match "error" or l:match "warning" print(l) end end log("** Searching for evaluation order problems%s for %s", FLAGS.dead_vars and " and dead variables" or "", arch) local plugin_args if FLAGS.dead_vars then plugin_args = { "--dead-vars" } end InvokeClangPluginForEachFile(files, cfg:extend { plugin = "find-problems", plugin_args = plugin_args }, SearchForErrors) log("** Done processing %d files. %s", processed_files, errors_found and "Errors found" or "No errors found") return errors_found end local function SafeCheckCorrectnessForArch(arch) local status, errors = pcall(CheckCorrectnessForArch, arch) if not status then print(string.format("There was an error: %s", errors)) errors = true end return errors end local errors = false for _, arch in ipairs(ARCHS) do if not ARCHITECTURES[arch] then error ("Unknown arch: " .. arch) end errors = SafeCheckCorrectnessForArch(arch, report) or errors end os.exit(errors and 1 or 0) node-v4.2.6/deps/v8/tools/gcmole/Makefile000644 000766 000024 00000004245 12650222326 020311 0ustar00iojsstaff000000 000000 # Copyright 2011 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # This is Makefile for clang plugin part of gcmole tool. See README. LLVM_INCLUDE:=$(LLVM_SRC_ROOT)/include CLANG_INCLUDE:=$(LLVM_SRC_ROOT)/tools/clang/include libgcmole.so: gcmole.cc $(CXX) -I$(LLVM_INCLUDE) -I$(CLANG_INCLUDE) -I. -D_DEBUG \ -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS \ -D__STDC_LIMIT_MACROS -O3 -fomit-frame-pointer -fno-exceptions \ -fno-rtti -fPIC -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing \ -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter \ -Wwrite-strings -std=c++0x -shared -o libgcmole.so gcmole.cc clean: $(RM) libgcmole.so node-v4.2.6/deps/v8/tools/gcmole/parallel.py000755 000766 000024 00000002571 12650222326 021022 0ustar00iojsstaff000000 000000 #!/usr/bin/env python # Copyright 2015 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ This script calls the first argument for each of the following arguments in parallel. E.g. parallel.py "clang --opt" file1 file2 calls clang --opt file1 clang --opt file2 The output (stdout and stderr) is concatenated sequentially in the form: ______________ file1 ______________ finish ______________ ______________ file2 ______________ finish ______________ """ import itertools import multiprocessing import subprocess import sys def invoke(cmdline): try: return (subprocess.check_output( cmdline, shell=True, stderr=subprocess.STDOUT), 0) except subprocess.CalledProcessError as e: return (e.output, e.returncode) if __name__ == '__main__': assert len(sys.argv) > 2 processes = multiprocessing.cpu_count() pool = multiprocessing.Pool(processes=processes) cmdlines = ["%s %s" % (sys.argv[1], filename) for filename in sys.argv[2:]] for filename, result in itertools.izip( sys.argv[2:], pool.imap(invoke, cmdlines)): print "______________ %s" % filename print result[0] print "______________ finish %d ______________" % result[1] node-v4.2.6/deps/v8/tools/gcmole/README000644 000766 000024 00000004316 12650222326 017530 0ustar00iojsstaff000000 000000 DESCRIPTION ------------------------------------------------------------------- gcmole is a simple static analysis tool used to find possible evaluation order dependent GC-unsafe places in the V8 codebase. For example the following code is GC-unsafe: Handle Foo(); // Assume Foo can trigger a GC. void Bar(Object*, Object*); Handle baz; baz->Qux(*Foo()); // (a) Bar(*Foo(), *baz); // (b) Both in cases (a) and (b) compiler is free to evaluate call arguments (that includes receiver) in any order. That means it can dereference baz before calling to Foo and save a raw pointer to a heap object in the register or on the stack. PREREQUISITES ----------------------------------------------------------------- 1) Install Lua 5.1 2) Get LLVM 2.9 and Clang 2.9 sources and build them. Follow the instructions on http://clang.llvm.org/get_started.html. Make sure to pass --enable-optimized to configure to get Release build instead of a Debug one. 3) Build gcmole Clang plugin (libgcmole.so) In the tools/gcmole execute the following command: LLVM_SRC_ROOT= make USING GCMOLE ------------------------------------------------------------------ gcmole consists of driver script written in Lua and Clang plugin that does C++ AST processing. Plugin (libgcmole.so) is expected to be in the same folder as driver (gcmole.lua). To start analysis cd into the root of v8 checkout and execute the following command: CLANG_BIN= lua tools/gcmole/gcmole.lua [] where arch should be one of architectures supported by V8 (arm, ia32, x64). Analysis will be performed in 2 stages: - on the first stage driver will parse all files and build a global callgraph approximation to find all functions that might potentially cause GC, list of this functions will be written into gcsuspects file. - on the second stage driver will parse all files again and will locate all callsites that might be GC-unsafe based on the list of functions causing GC. Such places are marked with a "Possible problem with evaluation order." warning. Messages "Failed to resolve v8::internal::Object" are benign and can be ignored. If any errors were found driver exits with non-zero status. node-v4.2.6/deps/v8/tools/blink_tests/TestExpectations000644 000766 000024 00000000260 12650222326 023146 0ustar00iojsstaff000000 000000 [ Linux ] virtual/pointerevent/fast/events/mouse-cursor-style-change-iframe.html [ Skip ] # Turn off Slimming Paint tests on linux. [ Linux ] virtual/slimmingpaint/ [ Skip ] node-v4.2.6/deps/v8/testing/gmock-support.h000644 000766 000024 00000004501 12650222326 020676 0ustar00iojsstaff000000 000000 // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_TESTING_GMOCK_SUPPORT_H_ #define V8_TESTING_GMOCK_SUPPORT_H_ #include #include #include #include "testing/gmock/include/gmock/gmock.h" namespace testing { template class Capture { public: Capture() : value_(), has_value_(false) {} const T& value() const { return value_; } bool has_value() const { return has_value_; } void SetValue(const T& value) { DCHECK(!has_value()); value_ = value; has_value_ = true; } private: T value_; bool has_value_; }; namespace internal { template class CaptureEqMatcher : public MatcherInterface { public: explicit CaptureEqMatcher(Capture* capture) : capture_(capture) {} virtual void DescribeTo(std::ostream* os) const { *os << "captured by " << static_cast(capture_); if (capture_->has_value()) *os << " which has value " << capture_->value(); } virtual bool MatchAndExplain(T value, MatchResultListener* listener) const { if (!capture_->has_value()) { capture_->SetValue(value); return true; } if (value != capture_->value()) { *listener << "which is not equal to " << capture_->value(); return false; } return true; } private: Capture* capture_; }; } // namespace internal // Creates a polymorphic matcher that matches anything whose bit representation // is equal to that of {x}. MATCHER_P(BitEq, x, std::string(negation ? "isn't" : "is") + " bitwise equal to " + PrintToString(x)) { static_assert(sizeof(x) == sizeof(arg), "Size mismatch"); return std::memcmp(&arg, &x, sizeof(x)) == 0; } // CaptureEq(capture) captures the value passed in during matching as long as it // is unset, and once set, compares the value for equality with the argument. template inline Matcher CaptureEq(Capture* capture) { return MakeMatcher(new internal::CaptureEqMatcher(capture)); } // Creates a polymorphic matcher that matches any floating point NaN value. MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " not a number") { return std::isnan(arg); } } // namespace testing #endif // V8_TESTING_GMOCK_SUPPORT_H_ node-v4.2.6/deps/v8/testing/gmock.gyp000644 000766 000024 00000004106 12650222326 017535 0ustar00iojsstaff000000 000000 # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. { 'targets': [ { 'target_name': 'gmock', 'type': 'static_library', 'dependencies': [ 'gtest.gyp:gtest', ], 'sources': [ # Sources based on files in r173 of gmock. 'gmock/include/gmock/gmock-actions.h', 'gmock/include/gmock/gmock-cardinalities.h', 'gmock/include/gmock/gmock-generated-actions.h', 'gmock/include/gmock/gmock-generated-function-mockers.h', 'gmock/include/gmock/gmock-generated-matchers.h', 'gmock/include/gmock/gmock-generated-nice-strict.h', 'gmock/include/gmock/gmock-matchers.h', 'gmock/include/gmock/gmock-spec-builders.h', 'gmock/include/gmock/gmock.h', 'gmock/include/gmock/internal/gmock-generated-internal-utils.h', 'gmock/include/gmock/internal/gmock-internal-utils.h', 'gmock/include/gmock/internal/gmock-port.h', 'gmock/src/gmock-all.cc', 'gmock/src/gmock-cardinalities.cc', 'gmock/src/gmock-internal-utils.cc', 'gmock/src/gmock-matchers.cc', 'gmock/src/gmock-spec-builders.cc', 'gmock/src/gmock.cc', 'gmock-support.h', # gMock helpers ], 'sources!': [ 'gmock/src/gmock-all.cc', # Not needed by our build. ], 'include_dirs': [ 'gmock', 'gmock/include', ], 'direct_dependent_settings': { 'include_dirs': [ 'gmock/include', # So that gmock headers can find themselves. ], }, 'export_dependent_settings': [ 'gtest.gyp:gtest', ], 'conditions': [ ['want_separate_host_toolset==1', { 'toolsets': ['host', 'target'], }, { 'toolsets': ['target'], }], ], }, { 'target_name': 'gmock_main', 'type': 'static_library', 'dependencies': [ 'gmock', ], 'sources': [ 'gmock/src/gmock_main.cc', ], }, ], } node-v4.2.6/deps/v8/testing/gtest-support.h000644 000766 000024 00000004163 12650222326 020730 0ustar00iojsstaff000000 000000 // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_TESTING_GTEST_SUPPORT_H_ #define V8_TESTING_GTEST_SUPPORT_H_ #include "testing/gtest/include/gtest/gtest.h" namespace testing { namespace internal { #define GET_TYPE_NAME(type) \ template <> \ inline std::string GetTypeName() { \ return #type; \ } GET_TYPE_NAME(bool) GET_TYPE_NAME(signed char) GET_TYPE_NAME(unsigned char) GET_TYPE_NAME(short) GET_TYPE_NAME(unsigned short) GET_TYPE_NAME(int) GET_TYPE_NAME(unsigned int) GET_TYPE_NAME(long) GET_TYPE_NAME(unsigned long) GET_TYPE_NAME(long long) GET_TYPE_NAME(unsigned long long) GET_TYPE_NAME(float) GET_TYPE_NAME(double) #undef GET_TYPE_NAME // TRACED_FOREACH(type, var, container) expands to a loop that assigns |var| // every item in the |container| and adds a SCOPED_TRACE() message for the // |var| while inside the loop body. #define TRACED_FOREACH(_type, _var, _container) \ for (_type const _var : _container) \ for (bool _done = false; !_done;) \ for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \ !_done; _done = true) // TRACED_FORRANGE(type, var, low, high) expands to a loop that assigns |var| // every value in the range |low| to (including) |high| and adds a // SCOPED_TRACE() message for the |var| while inside the loop body. // TODO(bmeurer): Migrate to C++11 once we're ready. #define TRACED_FORRANGE(_type, _var, _low, _high) \ for (_type _i = _low; _i <= _high; ++_i) \ for (bool _done = false; !_done;) \ for (_type const _var = _i; !_done;) \ for (SCOPED_TRACE(::testing::Message() << #_var << " = " << _var); \ !_done; _done = true) } // namespace internal } // namespace testing #endif // V8_TESTING_GTEST_SUPPORT_H_ node-v4.2.6/deps/v8/testing/gtest.gyp000644 000766 000024 00000012354 12650222326 017567 0ustar00iojsstaff000000 000000 # Copyright 2014 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. { 'targets': [ { 'target_name': 'gtest', 'toolsets': ['host', 'target'], 'type': 'static_library', 'sources': [ 'gtest/include/gtest/gtest-death-test.h', 'gtest/include/gtest/gtest-message.h', 'gtest/include/gtest/gtest-param-test.h', 'gtest/include/gtest/gtest-printers.h', 'gtest/include/gtest/gtest-spi.h', 'gtest/include/gtest/gtest-test-part.h', 'gtest/include/gtest/gtest-typed-test.h', 'gtest/include/gtest/gtest.h', 'gtest/include/gtest/gtest_pred_impl.h', 'gtest/include/gtest/internal/gtest-death-test-internal.h', 'gtest/include/gtest/internal/gtest-filepath.h', 'gtest/include/gtest/internal/gtest-internal.h', 'gtest/include/gtest/internal/gtest-linked_ptr.h', 'gtest/include/gtest/internal/gtest-param-util-generated.h', 'gtest/include/gtest/internal/gtest-param-util.h', 'gtest/include/gtest/internal/gtest-port.h', 'gtest/include/gtest/internal/gtest-string.h', 'gtest/include/gtest/internal/gtest-tuple.h', 'gtest/include/gtest/internal/gtest-type-util.h', 'gtest/src/gtest-all.cc', 'gtest/src/gtest-death-test.cc', 'gtest/src/gtest-filepath.cc', 'gtest/src/gtest-internal-inl.h', 'gtest/src/gtest-port.cc', 'gtest/src/gtest-printers.cc', 'gtest/src/gtest-test-part.cc', 'gtest/src/gtest-typed-test.cc', 'gtest/src/gtest.cc', 'gtest-support.h', ], 'sources!': [ 'gtest/src/gtest-all.cc', # Not needed by our build. ], 'include_dirs': [ 'gtest', 'gtest/include', ], 'dependencies': [ 'gtest_prod', ], 'defines': [ # In order to allow regex matches in gtest to be shared between Windows # and other systems, we tell gtest to always use it's internal engine. 'GTEST_HAS_POSIX_RE=0', # Chrome doesn't support / require C++11, yet. 'GTEST_LANG_CXX11=0', ], 'all_dependent_settings': { 'defines': [ 'GTEST_HAS_POSIX_RE=0', 'GTEST_LANG_CXX11=0', ], }, 'conditions': [ ['os_posix == 1', { 'defines': [ # gtest isn't able to figure out when RTTI is disabled for gcc # versions older than 4.3.2, and assumes it's enabled. Our Mac # and Linux builds disable RTTI, and cannot guarantee that the # compiler will be 4.3.2. or newer. The Mac, for example, uses # 4.2.1 as that is the latest available on that platform. gtest # must be instructed that RTTI is disabled here, and for any # direct dependents that might include gtest headers. 'GTEST_HAS_RTTI=0', ], 'direct_dependent_settings': { 'defines': [ 'GTEST_HAS_RTTI=0', ], }, }], ['OS=="android"', { 'defines': [ 'GTEST_HAS_CLONE=0', ], 'direct_dependent_settings': { 'defines': [ 'GTEST_HAS_CLONE=0', ], }, }], ['OS=="android"', { # We want gtest features that use tr1::tuple, but we currently # don't support the variadic templates used by libstdc++'s # implementation. gtest supports this scenario by providing its # own implementation but we must opt in to it. 'defines': [ 'GTEST_USE_OWN_TR1_TUPLE=1', # GTEST_USE_OWN_TR1_TUPLE only works if GTEST_HAS_TR1_TUPLE is set. # gtest r625 made it so that GTEST_HAS_TR1_TUPLE is set to 0 # automatically on android, so it has to be set explicitly here. 'GTEST_HAS_TR1_TUPLE=1', ], 'direct_dependent_settings': { 'defines': [ 'GTEST_USE_OWN_TR1_TUPLE=1', 'GTEST_HAS_TR1_TUPLE=1', ], }, }], ], 'direct_dependent_settings': { 'defines': [ 'UNIT_TEST', ], 'include_dirs': [ 'gtest/include', # So that gtest headers can find themselves. ], 'target_conditions': [ ['_type=="executable"', { 'test': 1, 'conditions': [ ['OS=="mac"', { 'run_as': { 'action????': ['${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}'], }, }], ['OS=="win"', { 'run_as': { 'action????': ['$(TargetPath)', '--gtest_print_time'], }, }], ], }], ], 'msvs_disabled_warnings': [4800], }, }, { 'target_name': 'gtest_main', 'type': 'static_library', 'dependencies': [ 'gtest', ], 'sources': [ 'gtest/src/gtest_main.cc', ], }, { 'target_name': 'gtest_prod', 'toolsets': ['host', 'target'], 'type': 'none', 'sources': [ 'gtest/include/gtest/gtest_prod.h', ], }, ], } node-v4.2.6/deps/v8/src/accessors.cc000644 000766 000024 00000137704 12650222324 017333 0ustar00iojsstaff000000 000000 // Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/v8.h" #include "src/accessors.h" #include "src/api.h" #include "src/contexts.h" #include "src/deoptimizer.h" #include "src/execution.h" #include "src/factory.h" #include "src/frames-inl.h" #include "src/isolate.h" #include "src/list-inl.h" #include "src/messages.h" #include "src/property-details.h" #include "src/prototype.h" namespace v8 { namespace internal { Handle Accessors::MakeAccessor( Isolate* isolate, Handle name, AccessorNameGetterCallback getter, AccessorNameSetterCallback setter, PropertyAttributes attributes) { Factory* factory = isolate->factory(); Handle info = factory->NewExecutableAccessorInfo(); info->set_property_attributes(attributes); info->set_all_can_read(false); info->set_all_can_write(false); info->set_is_special_data_property(true); info->set_name(*name); Handle get = v8::FromCData(isolate, getter); Handle set = v8::FromCData(isolate, setter); info->set_getter(*get); info->set_setter(*set); return info; } Handle Accessors::CloneAccessor( Isolate* isolate, Handle accessor) { Factory* factory = isolate->factory(); Handle info = factory->NewExecutableAccessorInfo(); info->set_name(accessor->name()); info->set_flag(accessor->flag()); info->set_expected_receiver_type(accessor->expected_receiver_type()); info->set_getter(accessor->getter()); info->set_setter(accessor->setter()); info->set_data(accessor->data()); return info; } static V8_INLINE bool CheckForName(Handle name, Handle property_name, int offset, int* object_offset) { if (Name::Equals(name, property_name)) { *object_offset = offset; return true; } return false; } // Returns true for properties that are accessors to object fields. // If true, *object_offset contains offset of object field. bool Accessors::IsJSObjectFieldAccessor(Handle map, Handle name, int* object_offset) { Isolate* isolate = name->GetIsolate(); switch (map->instance_type()) { case JS_ARRAY_TYPE: return CheckForName(name, isolate->factory()->length_string(), JSArray::kLengthOffset, object_offset); case JS_ARRAY_BUFFER_TYPE: return CheckForName(name, isolate->factory()->byte_length_string(), JSArrayBuffer::kByteLengthOffset, object_offset); default: if (map->instance_type() < FIRST_NONSTRING_TYPE) { return CheckForName(name, isolate->factory()->length_string(), String::kLengthOffset, object_offset); } return false; } } bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle map, Handle name, int* object_offset) { Isolate* isolate = name->GetIsolate(); switch (map->instance_type()) { case JS_TYPED_ARRAY_TYPE: { if (!CheckForName(name, isolate->factory()->length_string(), JSTypedArray::kLengthOffset, object_offset) && !CheckForName(name, isolate->factory()->byte_length_string(), JSTypedArray::kByteLengthOffset, object_offset) && !CheckForName(name, isolate->factory()->byte_offset_string(), JSTypedArray::kByteOffsetOffset, object_offset)) { return false; } if (map->is_dictionary_map()) return false; // Check if the property is overridden on the instance. DescriptorArray* descriptors = map->instance_descriptors(); int descriptor = descriptors->SearchWithCache(*name, *map); if (descriptor != DescriptorArray::kNotFound) return false; Handle proto = Handle(map->prototype(), isolate); if (!proto->IsJSReceiver()) return false; // Check if the property is defined in the prototype chain. LookupIterator it(proto, name); if (!it.IsFound()) return false; Object* original_proto = JSFunction::cast(map->GetConstructor())->prototype(); // Property is not configurable. It is enough to verify that // the holder is the same. return *it.GetHolder() == original_proto; } case JS_DATA_VIEW_TYPE: return CheckForName(name, isolate->factory()->byte_length_string(), JSDataView::kByteLengthOffset, object_offset) || CheckForName(name, isolate->factory()->byte_offset_string(), JSDataView::kByteOffsetOffset, object_offset); default: return false; } } // // Accessors::ArgumentsIterator // void Accessors::ArgumentsIteratorGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* result = isolate->native_context()->array_values_iterator(); info.GetReturnValue().Set(Utils::ToLocal(Handle(result, isolate))); } void Accessors::ArgumentsIteratorSetter( v8::Local name, v8::Local val, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); HandleScope scope(isolate); Handle object = Utils::OpenHandle(*info.This()); Handle value = Utils::OpenHandle(*val); LookupIterator it(object, Utils::OpenHandle(*name)); CHECK_EQ(LookupIterator::ACCESSOR, it.state()); DCHECK(it.HolderIsReceiverOrHiddenPrototype()); if (Object::SetDataProperty(&it, value).is_null()) { isolate->OptionalRescheduleException(false); } } Handle Accessors::ArgumentsIteratorInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name = isolate->factory()->iterator_symbol(); return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, &ArgumentsIteratorSetter, attributes); } // // Accessors::ArrayLength // void Accessors::ArrayLengthGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder())); Object* result = holder->length(); info.GetReturnValue().Set(Utils::ToLocal(Handle(result, isolate))); } // Tries to non-observably convert |value| to a valid array length. // Returns false if it fails. static bool FastAsArrayLength(Isolate* isolate, Handle value, uint32_t* length) { if (value->ToArrayLength(length)) return true; // We don't support AsArrayLength, so use AsArrayIndex for now. This just // misses out on kMaxUInt32. if (value->IsString()) return String::cast(*value)->AsArrayIndex(length); return false; } void Accessors::ArrayLengthSetter( v8::Local name, v8::Local val, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); HandleScope scope(isolate); Handle object = Utils::OpenHandle(*info.This()); Handle array = Handle::cast(object); Handle length_obj = Utils::OpenHandle(*val); uint32_t length = 0; if (!FastAsArrayLength(isolate, length_obj, &length)) { Handle uint32_v; if (!Execution::ToUint32(isolate, length_obj).ToHandle(&uint32_v)) { isolate->OptionalRescheduleException(false); return; } Handle number_v; if (!Execution::ToNumber(isolate, length_obj).ToHandle(&number_v)) { isolate->OptionalRescheduleException(false); return; } if (uint32_v->Number() != number_v->Number()) { Handle exception = isolate->factory()->NewRangeError( MessageTemplate::kInvalidArrayLength); return isolate->ScheduleThrow(*exception); } CHECK(uint32_v->ToArrayLength(&length)); } if (JSArray::ObservableSetLength(array, length).is_null()) { isolate->OptionalRescheduleException(false); } } Handle Accessors::ArrayLengthInfo( Isolate* isolate, PropertyAttributes attributes) { return MakeAccessor(isolate, isolate->factory()->length_string(), &ArrayLengthGetter, &ArrayLengthSetter, attributes); } // // Accessors::StringLength // void Accessors::StringLengthGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); // We have a slight impedance mismatch between the external API and the way we // use callbacks internally: Externally, callbacks can only be used with // v8::Object, but internally we have callbacks on entities which are higher // in the hierarchy, in this case for String values. Object* value = *Utils::OpenHandle(*v8::Local(info.This())); if (!value->IsString()) { // Not a string value. That means that we either got a String wrapper or // a Value with a String wrapper in its prototype chain. value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value(); } Object* result = Smi::FromInt(String::cast(value)->length()); info.GetReturnValue().Set(Utils::ToLocal(Handle(result, isolate))); } void Accessors::StringLengthSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::StringLengthInfo( Isolate* isolate, PropertyAttributes attributes) { return MakeAccessor(isolate, isolate->factory()->length_string(), &StringLengthGetter, &StringLengthSetter, attributes); } // // Accessors::ScriptColumnOffset // void Accessors::ScriptColumnOffsetGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* res = Script::cast(JSValue::cast(object)->value())->column_offset(); info.GetReturnValue().Set(Utils::ToLocal(Handle(res, isolate))); } void Accessors::ScriptColumnOffsetSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptColumnOffsetInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name(isolate->factory()->InternalizeOneByteString( STATIC_CHAR_VECTOR("column_offset"))); return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, &ScriptColumnOffsetSetter, attributes); } // // Accessors::ScriptId // void Accessors::ScriptIdGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* id = Script::cast(JSValue::cast(object)->value())->id(); info.GetReturnValue().Set(Utils::ToLocal(Handle(id, isolate))); } void Accessors::ScriptIdSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptIdInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name( isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id"))); return MakeAccessor(isolate, name, &ScriptIdGetter, &ScriptIdSetter, attributes); } // // Accessors::ScriptName // void Accessors::ScriptNameGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* source = Script::cast(JSValue::cast(object)->value())->name(); info.GetReturnValue().Set(Utils::ToLocal(Handle(source, isolate))); } void Accessors::ScriptNameSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptNameInfo( Isolate* isolate, PropertyAttributes attributes) { return MakeAccessor(isolate, isolate->factory()->name_string(), &ScriptNameGetter, &ScriptNameSetter, attributes); } // // Accessors::ScriptSource // void Accessors::ScriptSourceGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* source = Script::cast(JSValue::cast(object)->value())->source(); info.GetReturnValue().Set(Utils::ToLocal(Handle(source, isolate))); } void Accessors::ScriptSourceSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptSourceInfo( Isolate* isolate, PropertyAttributes attributes) { return MakeAccessor(isolate, isolate->factory()->source_string(), &ScriptSourceGetter, &ScriptSourceSetter, attributes); } // // Accessors::ScriptLineOffset // void Accessors::ScriptLineOffsetGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* res = Script::cast(JSValue::cast(object)->value())->line_offset(); info.GetReturnValue().Set(Utils::ToLocal(Handle(res, isolate))); } void Accessors::ScriptLineOffsetSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptLineOffsetInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name(isolate->factory()->InternalizeOneByteString( STATIC_CHAR_VECTOR("line_offset"))); return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, &ScriptLineOffsetSetter, attributes); } // // Accessors::ScriptType // void Accessors::ScriptTypeGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* res = Script::cast(JSValue::cast(object)->value())->type(); info.GetReturnValue().Set(Utils::ToLocal(Handle(res, isolate))); } void Accessors::ScriptTypeSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptTypeInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name( isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type"))); return MakeAccessor(isolate, name, &ScriptTypeGetter, &ScriptTypeSetter, attributes); } // // Accessors::ScriptCompilationType // void Accessors::ScriptCompilationTypeGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); DisallowHeapAllocation no_allocation; HandleScope scope(isolate); Object* object = *Utils::OpenHandle(*info.This()); Object* res = Smi::FromInt( Script::cast(JSValue::cast(object)->value())->compilation_type()); info.GetReturnValue().Set(Utils::ToLocal(Handle(res, isolate))); } void Accessors::ScriptCompilationTypeSetter( v8::Local name, v8::Local value, const v8::PropertyCallbackInfo& info) { UNREACHABLE(); } Handle Accessors::ScriptCompilationTypeInfo( Isolate* isolate, PropertyAttributes attributes) { Handle name(isolate->factory()->InternalizeOneByteString( STATIC_CHAR_VECTOR("compilation_type"))); return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, &ScriptCompilationTypeSetter, attributes); } // // Accessors::ScriptGetLineEnds // void Accessors::ScriptLineEndsGetter( v8::Local name, const v8::PropertyCallbackInfo& info) { i::Isolate* isolate = reinterpret_cast(info.GetIsolate()); HandleScope scope(isolate); Handle object = Utils::OpenHandle(*info.This()); Handle

V8 Benchmark Suite - version ?

Warning! This is not the latest version of the V8 benchmark suite. Consider running the latest version.
This page contains a suite of pure JavaScript benchmarks that we have used to tune V8. The final score is computed as the geometric mean of the individual results to make it independent of the running times of the individual benchmarks and of a reference system (score 100). Scores are not comparable across benchmark suite versions and higher scores means better performance: Bigger is better!
  • Richards
    OS kernel simulation benchmark, originally written in BCPL by Martin Richards (539 lines).
  • DeltaBlue
    One-way constraint solver, originally written in Smalltalk by John Maloney and Mario Wolczko (880 lines).
  • Crypto
    Encryption and decryption benchmark based on code by Tom Wu (1698 lines).
  • RayTrace
    Ray tracer benchmark based on code by Adam Burmister (904 lines).
  • EarleyBoyer
    Classic Scheme benchmarks, translated to JavaScript by Florian Loitsch's Scheme2Js compiler (4684 lines).
  • RegExp
    Regular expression benchmark generated by extracting regular expression operations from 50 of the most popular web pages (1761 lines).
  • Splay
    Data manipulation benchmark that deals with splay trees and exercises the automatic memory management subsystem (394 lines).
  • NavierStokes
    Solves NavierStokes equations in 2D, heavily manipulating double precision arrays. Based on Oliver Hunt's code (387 lines).

Note that benchmark results are not comparable unless both results are run with the same revision of the benchmark suite. We will be making revisions from time to time in order to fix bugs or expand the scope of the benchmark suite. For previous revisions and the change log see the revisions page.

Starting...
node-v4.2.6/deps/v8/benchmarks/run.js000644 000766 000024 00000004340 12650222324 017514 0ustar00iojsstaff000000 000000 // Copyright 2008 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. load('base.js'); load('richards.js'); load('deltablue.js'); load('crypto.js'); load('raytrace.js'); load('earley-boyer.js'); load('regexp.js'); load('splay.js'); load('navier-stokes.js'); var success = true; function PrintResult(name, result) { print(name + ': ' + result); } function PrintError(name, error) { PrintResult(name, error); success = false; } function PrintScore(score) { if (success) { print('----'); print('Score (version ' + BenchmarkSuite.version + '): ' + score); } } BenchmarkSuite.RunSuites({ NotifyResult: PrintResult, NotifyError: PrintError, NotifyScore: PrintScore }); node-v4.2.6/deps/v8/benchmarks/spinning-balls/000755 000766 000024 00000000000 12650222324 021271 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/v8/benchmarks/splay.js000644 000766 000024 00000024772 12650222324 020053 0ustar00iojsstaff000000 000000 // Copyright 2009 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This benchmark is based on a JavaScript log processing module used // by the V8 profiler to generate execution time profiles for runs of // JavaScript applications, and it effectively measures how fast the // JavaScript engine is at allocating nodes and reclaiming the memory // used for old nodes. Because of the way splay trees work, the engine // also has to deal with a lot of changes to the large tree object // graph. var Splay = new BenchmarkSuite('Splay', 81491, [ new Benchmark("Splay", SplayRun, SplaySetup, SplayTearDown) ]); // Configuration. var kSplayTreeSize = 8000; var kSplayTreeModifications = 80; var kSplayTreePayloadDepth = 5; var splayTree = null; function GeneratePayloadTree(depth, tag) { if (depth == 0) { return { array : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], string : 'String for key ' + tag + ' in leaf node' }; } else { return { left: GeneratePayloadTree(depth - 1, tag), right: GeneratePayloadTree(depth - 1, tag) }; } } function GenerateKey() { // The benchmark framework guarantees that Math.random is // deterministic; see base.js. return Math.random(); } function InsertNewNode() { // Insert new node with a unique key. var key; do { key = GenerateKey(); } while (splayTree.find(key) != null); var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key)); splayTree.insert(key, payload); return key; } function SplaySetup() { splayTree = new SplayTree(); for (var i = 0; i < kSplayTreeSize; i++) InsertNewNode(); } function SplayTearDown() { // Allow the garbage collector to reclaim the memory // used by the splay tree no matter how we exit the // tear down function. var keys = splayTree.exportKeys(); splayTree = null; // Verify that the splay tree has the right size. var length = keys.length; if (length != kSplayTreeSize) { throw new Error("Splay tree has wrong size"); } // Verify that the splay tree has sorted, unique keys. for (var i = 0; i < length - 1; i++) { if (keys[i] >= keys[i + 1]) { throw new Error("Splay tree not sorted"); } } } function SplayRun() { // Replace a few nodes in the splay tree. for (var i = 0; i < kSplayTreeModifications; i++) { var key = InsertNewNode(); var greatest = splayTree.findGreatestLessThan(key); if (greatest == null) splayTree.remove(key); else splayTree.remove(greatest.key); } } /** * Constructs a Splay tree. A splay tree is a self-balancing binary * search tree with the additional property that recently accessed * elements are quick to access again. It performs basic operations * such as insertion, look-up and removal in O(log(n)) amortized time. * * @constructor */ function SplayTree() { }; /** * Pointer to the root node of the tree. * * @type {SplayTree.Node} * @private */ SplayTree.prototype.root_ = null; /** * @return {boolean} Whether the tree is empty. */ SplayTree.prototype.isEmpty = function() { return !this.root_; }; /** * Inserts a node into the tree with the specified key and value if * the tree does not already contain a node with the specified key. If * the value is inserted, it becomes the root of the tree. * * @param {number} key Key to insert into the tree. * @param {*} value Value to insert into the tree. */ SplayTree.prototype.insert = function(key, value) { if (this.isEmpty()) { this.root_ = new SplayTree.Node(key, value); return; } // Splay on the key to move the last node on the search path for // the key to the root of the tree. this.splay_(key); if (this.root_.key == key) { return; } var node = new SplayTree.Node(key, value); if (key > this.root_.key) { node.left = this.root_; node.right = this.root_.right; this.root_.right = null; } else { node.right = this.root_; node.left = this.root_.left; this.root_.left = null; } this.root_ = node; }; /** * Removes a node with the specified key from the tree if the tree * contains a node with this key. The removed node is returned. If the * key is not found, an exception is thrown. * * @param {number} key Key to find and remove from the tree. * @return {SplayTree.Node} The removed node. */ SplayTree.prototype.remove = function(key) { if (this.isEmpty()) { throw Error('Key not found: ' + key); } this.splay_(key); if (this.root_.key != key) { throw Error('Key not found: ' + key); } var removed = this.root_; if (!this.root_.left) { this.root_ = this.root_.right; } else { var right = this.root_.right; this.root_ = this.root_.left; // Splay to make sure that the new root has an empty right child. this.splay_(key); // Insert the original right child as the right child of the new // root. this.root_.right = right; } return removed; }; /** * Returns the node having the specified key or null if the tree doesn't contain * a node with the specified key. * * @param {number} key Key to find in the tree. * @return {SplayTree.Node} Node having the specified key. */ SplayTree.prototype.find = function(key) { if (this.isEmpty()) { return null; } this.splay_(key); return this.root_.key == key ? this.root_ : null; }; /** * @return {SplayTree.Node} Node having the maximum key value. */ SplayTree.prototype.findMax = function(opt_startNode) { if (this.isEmpty()) { return null; } var current = opt_startNode || this.root_; while (current.right) { current = current.right; } return current; }; /** * @return {SplayTree.Node} Node having the maximum key value that * is less than the specified key value. */ SplayTree.prototype.findGreatestLessThan = function(key) { if (this.isEmpty()) { return null; } // Splay on the key to move the node with the given key or the last // node on the search path to the top of the tree. this.splay_(key); // Now the result is either the root node or the greatest node in // the left subtree. if (this.root_.key < key) { return this.root_; } else if (this.root_.left) { return this.findMax(this.root_.left); } else { return null; } }; /** * @return {Array<*>} An array containing all the keys of tree's nodes. */ SplayTree.prototype.exportKeys = function() { var result = []; if (!this.isEmpty()) { this.root_.traverse_(function(node) { result.push(node.key); }); } return result; }; /** * Perform the splay operation for the given key. Moves the node with * the given key to the top of the tree. If no node has the given * key, the last node on the search path is moved to the top of the * tree. This is the simplified top-down splaying algorithm from: * "Self-adjusting Binary Search Trees" by Sleator and Tarjan * * @param {number} key Key to splay the tree on. * @private */ SplayTree.prototype.splay_ = function(key) { if (this.isEmpty()) { return; } // Create a dummy node. The use of the dummy node is a bit // counter-intuitive: The right child of the dummy node will hold // the L tree of the algorithm. The left child of the dummy node // will hold the R tree of the algorithm. Using a dummy node, left // and right will always be nodes and we avoid special cases. var dummy, left, right; dummy = left = right = new SplayTree.Node(null, null); var current = this.root_; while (true) { if (key < current.key) { if (!current.left) { break; } if (key < current.left.key) { // Rotate right. var tmp = current.left; current.left = tmp.right; tmp.right = current; current = tmp; if (!current.left) { break; } } // Link right. right.left = current; right = current; current = current.left; } else if (key > current.key) { if (!current.right) { break; } if (key > current.right.key) { // Rotate left. var tmp = current.right; current.right = tmp.left; tmp.left = current; current = tmp; if (!current.right) { break; } } // Link left. left.right = current; left = current; current = current.right; } else { break; } } // Assemble. left.right = current.left; right.left = current.right; current.left = dummy.right; current.right = dummy.left; this.root_ = current; }; /** * Constructs a Splay tree node. * * @param {number} key Key. * @param {*} value Value. */ SplayTree.Node = function(key, value) { this.key = key; this.value = value; }; /** * @type {SplayTree.Node} */ SplayTree.Node.prototype.left = null; /** * @type {SplayTree.Node} */ SplayTree.Node.prototype.right = null; /** * Performs an ordered traversal of the subtree starting at * this SplayTree.Node. * * @param {function(SplayTree.Node)} f Visitor function. * @private */ SplayTree.Node.prototype.traverse_ = function(f) { var current = this; while (current) { var left = current.left; if (left) left.traverse_(f); f(current); current = current.right; } }; node-v4.2.6/deps/v8/benchmarks/style.css000644 000766 000024 00000002217 12650222324 020225 0ustar00iojsstaff000000 000000 hr { border: 1px solid; border-color: #36C; margin: 1em 0; } h1, h2, h3, h4 { margin: 0; margin-bottom: 0; } h1 { font-size: 154%; height: 1.2em; } li { margin: .3em 0 1em 0; } body { font-family: Helvetica,Arial,sans-serif; color: #000; background-color: #fff; } div.title { background-color: rgb(229, 236, 249); border-top: 1px solid rgb(51, 102, 204); text-align: center; padding-top: 0.2em; padding-bottom: 0.2em; margin-bottom: 20px; } div.subtitle { border-bottom: 1px solid rgb(51, 102, 204); margin-top: 2em; } td.contents { text-align: left; } div.run { margin: 20px; width: 300px; height: 300px; float: right; background-color: rgb(229, 236, 249); background-image: url(v8-logo.png); background-position: center center; background-repeat: no-repeat; border: 1px solid rgb(51, 102, 204); } div.warning { background: #ffffd9; border: 1px solid #d2d26a; display: none; margin: 1em 0 2em; padding: 8px; text-align: center; } #status { text-align: center; margin-top: 50px; font-size: 120%; font-weight: bold; } #results { text-align: left; margin: 30px 0 0 90px; } node-v4.2.6/deps/v8/benchmarks/v8-logo.png000644 000766 000024 00000057345 12650222324 020370 0ustar00iojsstaff000000 000000 PNG  IHDR7vubKGD pHYs  tIME  % IDATxvʮ, f&;><]xiʖlIkYU2y?w-weYhYjfӸ0o4+C~Ӹ13圩i9Ӳ,d!c zzĘe**m&Z?q?rΔRi(HKDMC,S$g]GZJ)/BZ1Q۶Q?y=D݌h1DMC3Q, WQ<7 TRS3d}q?{G3hQ֖ȝ"|x1j׶zƬizR{ާ#4u۽ a-g0K >6{üѡm u]' +iBm[97:C&- Xu3ƍQ3YG1<- 9G91~֚Nu*O0x/tW+|#ӴRzF ~?pzbԶ-:G)r?g :'?Z:9c. c:E3MӐgJ9QtZ]y}{1FOڙCNJEii396nNb1 m8%%Y4C @)Qʉi*i96rkURNPC gmL(VD 3T~0H1/>?#Fvd*->3[mp0oKG r֭BɐSWMБqT?ϪTji:HkRnR^'72,M}B,Cܓ3u]/?c[/u]/Nj@Q' ia ֚:H>DZ h\ NJc%ߡ.-sK]ׯZbq:׮Rˇl=Yr4lNۯmوQx ~W>Xu5MHee&=m44"8}?>,!ZeXB˲ȁ)9Xk>X>1sy_-g2r"Z$%yCI׫S^c tQ]3 gWז\Xxe8G#ZV_822BT[ǶUD4{ylۖ2\_ࡌmDiѵ1 (Ad8$=&wÐ#i7|6xlLl(«ϳ|GÑk;2Uz{D9@FPӀCd#iqܽےmLNt][׾iEiVٗe_%h!j3%ߚ1cV6-&l%gY܋yYАA%ըm. 8g^25t42\Tա7MC3ĠLba۩H瀺yE82!J2nlbMPp-o`=1,:@J n1?~}Z>;0XD[HBqUHGl2_P^_b)BFQ݁U (%X^*y2Q ;SـԙiV0%?β,DL~nY?ʸeyŨd#ߩWE1IDhғdH5:,h7m;}PYp4 y_"sCWXf[Ssuī\VvAmʎD[]t8e8Sks@ v SGp*CCA+3]wyR )ǥ1Fa> ZCF?Lzk>lMSE`Qéh˓j2itؾx #3JVj1 Ժv|vɎ4vӲ̤0|s׭I=:m]tc,֔"l4NAn9oWF]}wx#UΊ}Q:ե=>MЁZZ"t@60X#jТ%jpJʥEmHj"'he,tD͇~XS%;P( 3#䐄/𼯊}!L!O)F5L̢=j/XRb s0h'iftHH+pHu3V&u{ܺ3Q5 RAe} !dbTP#W:/|Q{NܳR,b&6#ϸԤ:ќo+x H==W}+~U-PCԬmvFOX Z:eC:9M7䙦iȲYo0UV_y`BHh){$䞈3XNUPLs:Il@Þs |ٸ(c H _nZMurkFQ!,t8Rx+ ml9j[e#zZ sw+ HeÈ ofPǞ.Y3[^¡>?}.\^\YJydlZczi"z}+f]e0\rf~y9xeR1._j3jq!eYr̺#Z*HRJeI}AJ- ;(QVx$;l+raW#O0Aa*{޺t½)9*E9Q 2薬eg%>H8Ji㤁:G}4X̧[SpMvgBU|sqCAȐ^)z0J9pTD D,tLZג%Nـ5V!""6QC)hQ:)Pd0~]F395)rpLz3a܀,{/#@χqdP!}&*臌Z+KjzI"غaPF QN㒶 /j.ubW:?ߗ{Nk:?ZĠ'~ϮUdX9qv!,Ŗ]m9G Bi]sEZ\OFPYg{MVH:"J#֠jc$ !1W|(,@Ÿϭ侲QO!D ?ce*R%gj0b8Y]30A~V0dQx^omi:hV%;,L7ƍ+f>ci,(4P;+m&Nz_06ܪm'BʨS[g8kl]孉+9 \{6'S,YS"j]*bR>r4÷p#z{&dڵ @m yɫts{Z fW QE[f[V (,]W1PCz3&RsjVO󊏐cqkzyϜyﭰ1^nbf笗LF:=۸ݏHu^ 6 |!8 pڙvؑڃoZنA#t=xL5Y5O߿hfຖGO1/3ϋNbDua<䡍3~f:>T:OSiQϬ׶ P)N ~{M2g-Pl3}FZ6cC:㹺Sʧ7Li῜Vz)-j]uouM'δ;J/R/1`z5PsTq֑ϞˢI} Y?_Xrg^\}TBAkc-TYk [OVꍘߞRS7SGXs HRHɀs`w1k\_{o*]|mܨKS$s+VRi:9L8X*, Rxo\P+ooC~-+"-yͲ,t8%j6emܗ8VQґEtQh%4B9zkfH #[&o UZ,!W{>b7n-AҪzrZn\dE;kۧa|pE !/ D\\F}Tci1CmFl, oxߵdžr*ep^s!"ԑ'"aW #@ٖ懱cZCzLmiBWҋdRaEOcp̘4]təjQ>˞ݚ%1ncp^2-8tjWƭm>( в% V"ڶVT?a-6W־% }+{ @5|J<jyxj:vnJD+͞z 0 +֒Q5Zq44){k%Zw;Y6 $ oϬ8ֵzbV{_ZU۶L -2 Adt$YKD% IO4iԷ-C)TDm˸<_}@.d2w6~[4 M$;N4z&㫓Zsv%!Nm!޷iJ_O3oyX<4RjEu)::ۣ5;|!JF!6xfCJ,Kjp(a)~l M6%|/.LC(% .y"QͥMR^`%:{9ƝF0knpum~謧-Rj8[.e9 4O=_Z졡b,k`Ba^択=5a/K0Y6 j+ȩ{ kt:©ck~r*7GsbZK)x;g^c4 QϞ Y2S+r|SLD$2="FEoc E^, 2,hxv`=GI|]Owgc|306U[QNƭ  aogwь#sr@6wYSI/,g{{d @A'n.·VgSHH=(۶=Xnj,o"pyyg(c(_^HtH`VLRnQCEɉFm^ݍi:q|y4;1=mXk,^^)E+87S͆HYK)Ѹ{yXᰧ%,B+xOgHks!bEIؓXrY4i#rЃlYrzqAiڎB G=ySD1G2)6Eﵹtu\ YG!QyT8qw>bwHTM#9 BWӸ =Ƒbt8"*hmж ,jyiG}w_cm/tzsH4M4vΜќˈ3w֭HZ2깦jǣ]*Xt F6.9瑎D=?ς)ȖWD~4pHkx*B.-B[T֣?<]C~@M7<4|iCr0:.S06JDrpVἙS-A6'*=!#}^a?0C;R\G9Q{~R[ɷDzia0 N`ə R4 }h. "ڶ4M9P)F ]tK" y!j^`cж4s1ݎ"{,eبE[?l4eF/՜{Vm{_g98ޤ+Y]DzrL HC?Y~^[C2n!(Vh1Tz}]ɐ:䘈x=/}_+k-hU(o Dκx%{~.X,Lc(.QZJ]T--"fU8aY@Sgh(>@\DmbQ-=ύ5xE -!]ĵ4sxEQ$ԇ8z0EF*]{/i1AF3xACo[6ڜ`'p@SJ+[(Ot֪(m1nV1f`Vy $*T; SeC*=.">]yPg]4ǭ$ zN9ruG8E;ſpkRo]![g3f.H\EXi9Qu]O -JH{aw zė^XCdǵ-um!,)ukEk{1t8 %u3OLAgYK)Bպ·57iVE!0YGs: 15p*9eY$~Jx0^?+A™0=V9$JXVgmj[/]qrVl/!$}% !3"fM9#}4l-7Zp?zYc(AxԐW8SrFcƍ{i9jFk0hQMZ4P}nm (mB(xWvL;6F]Xq-u궢oq[݌~A\6JMܛYyYZө8Pݤ+.0Fiݼ귞A#-=O.dE9:6a4"bzpC;傑4lzkf۶'yߵ6ȍ?LA5ѿNlm-zJUr?%j--2>{55es~Op1CrδMHʨav>{m`پ{^L^<82#<}S^T\ i2ǎB=YjLt7!FHl^^HrMC2g.@C+ӚR3.uvԧH\vsmg[8K+pO]IFݰX7}T'"K8bd5{sfZ\ qB?G 04:զC)^ъ8ϫR";Sĕ&[YtGc1r^A$:aUG.g!ܗ^:xFH,fv/40mT߹~Ns$"-tT՚`A߈#3=Ը[׾Iem p!}ʞ  194Xo"dKhVAњ]jڞ܉m7ҕM=9^Ͳ\[آLj"rgtnۖ)%|X|~`f5bE=96#VXW,RoiY_cO@JqQc[72h 5,x[| /tPmXmmt~A(aZ[ -y5l4ʮ9zy#PkG MtfzUn9[= c}OڣW泇 But S=i 1|tzk !A<$(B}H74\N!cت-#5Ptvd|ȭŢ~֥&m}uqiV41u ;/!mW=a- ^mwv8^7^ ,MC݋(\rjj9*uxf~9SB,w]9dV lY>03@z []*1nG"P^P`"-(3mZK  R8JqMON)\ӱ ]yu@^;x/ulʉLBKypmϔR/Ē̏8F8`@ɒ̈́g\5~Mu)?4d( 6 ]>^Zl]l[-"62܆a\aHɵ^`"b j6ure5neE C`RRLP<+"0VZ}뛟Oz:$=CJj,#[J;, 0We룵)hl,|(WҸ۝mXZ_Z+ Q1fࢨ(ip][Q10OS) M'|"akcΙeiuQHH'k~ OTXYJtBv]l־[j~Oy@5>κȿSc卐bX %[tLc(7Y9,]۰u/8gZHӸ)89*\u]Mo-EgPMWhYrLA2٩c_"uR,ђm^ҟY>[Z=d b__D)c:Z8ԛ?!\daNm˸vSP* h]Lm8`=u R4:qы]3` 6Z^Jծi˭&_ȨMȊ%osN桡v/oWH+A zə|b}9Ui&hY= C_)tYQe`)c7?殽-&汵aj@*5n➴DQk^c[jAJmBA~%2;Բxl!@(J4Qc]׋kVmy7Vy$G;'•[^ʣզpsD?Űᐵ{>ȭjC,{ɡִT-oh#TZnnXqfVy QvuMi``ާgy4 #zV9< *eRdM0o,PPIE$vz;.-Zq'ŔEIq z:=1l5xBJ|AO!i%?ϲYD3Rgueo?#+hޞܰkL%U Pk%7j a\iA,`gs5w_&uuԾlTэVS,X.r-R\{P6e,;z)*T( uoJsu% #+aԇKd͎=W(z;Skֿ(HƦt|TND7e5joX)Qv}>}ڻ/ + 1<d%gJes}gM!OAj+)+sRwN!dZJKµ.@36fU%+b na] ≺6>Q~`əP`I+Dْ*H-~vqky=ضEި1t}/ת)vיQI%xUKh@PtXoxDƳi>> dͭJ](FiQϼW,:$91u蒳a XiEOѢ떵gB4MD4ޣv Ê-F6hYH5-L໣{N`90 P#*fx=m6TD d--~Y/2"pՈ-R)8-< R^ڲs·k?lR!`?)Hs3ZP(J-gK;i[p*tưΆm@+& 0R€^S\QSzc4g0BZ0bxeBY,Ĕ=u}U2;h*j-2(cx-L g=9%"Ln7MgreGrb&iw>D`X:0qf׶2Z }L1+t W=eg? baK)|DV Ջ%a%oZE犭"T&wZEO0oax(q |7C``ean{yh:-Gi0hX=Ycep}p=T(e  pRk+4R,R b!H*1غUG,rn \@ o ]EWZ_3 nB gE@0Oqɦv\3]_e\SM -XcтINzina-'kWS[FwXu}/8luE9U]NMpTa;z ?? s-@b\6Y΅{:z5wF]2rĕd/iO,=J2#Յh 2d/:OY]9%zv] u]g_Mia,ԶtyVf5f[+֞RuU½um{;0jH> )g'.Z$z;CpAeӒ]:ɋ7yZ9S|aVحս[Zw{hw佧U2ֵRw䥇_6np Î1Z#9NŦe=Xv,!Ib׿+ySaQ42#{ (RI!d\Ddr6KΑ_<1v]i3B2l47VJ -{A\ozCf6l4_\Co322 AEeYȶ\Ni/}!aI=oؔF}Z<@4I]2T/H8вضV#eM)QZ٨L9/}Lׁ!LCqXcyvвqNqHt'D;A&@ѓ,|(uq j9X#fC{#]"h"l? b tM1JaF3ʋaړG4R5 f6&G;x@4Z+%7lH"UbRB~/T׊زKQW%"ѯI5IL3!TԢDK<`=HҨés4SڑuY\Ga捲%jԮd7~NXGNe [Wrsj Bsu5 ³gZwBN=iG@ozj& -5r/FhIM<,['h`A.=+b,$,u[r.-uhӔAm}ݨIsjsqf_/ɤ^/NUϜӺ(e;o 5_TF-["S[W*nj܈"j9r$ )3{j u8Zl(b6pBMŶ adH636wH5-t\H q/j9LQs{{2G{Iޣa?mW1SgjAџ}HIaLj(K8 'ZN g]>ԇ;_h*Kh{s֭3FiqTlZySYki@:!W`QXMA:j࣡F"~]שG-YOE%_/B_ 9բ+F!Pݸ۽ƁT[Q3pDikm@U~9xC5΢>z6B^{ԀO -"~ZpՌ۽obܦ:rK>9G%ޣE#0H u;4SNe)O Qsr:9_^`Ȃ#3u߬ ]v=vы.ś^9P޼x"0Eӈ<k9k;׏kf w4"IZ\zIjúc~9*}+*6L)q=ƠEc=^νKD溞M4|?U_'-۠! gPw#]SٿԿq )EyC?;cVq+9$B\ ?x]fD6@]8cpvO@Ԫ6ny^q!sC:&4V*xGn+ jƭJ 'HE1y;ѳՑPω/_+yڎ:~.iq\ 4fQtF[+i%5kU^䥾Ѹ5[0#Tgs&W!c@۽иP|' bQ hXC-kbL ;'ˌ)b֕_d0"Doi/{Κ-WA޶ SO/oK4F n?4qG?BJU^1Ԧ0g~nagYxLSDć!2 NVZ2^1eQ =d-ty ;WIi伴"t)%*k3CXL~qkhjWZHo k~X0; ׳ ϕV!%BYӜmdsHkkVyF::yLa%$Ҹ[x!ecR~qiK1R^"̒5zVFMcO}:H>m ^6e1c9k`*WgEb.ۨ5\mٙ(+/}ܽПqIn|zz ZɊ%$&X4M _-8CXy -GBߠޡq^;(0nɌ6P\5{;BGg91d{+GD+aȮ~- -MTV@1y/R{\TtvQ|Q`6-y,>01q%Q `WO<bwxڕ?phD<[8Rp 21mTZcE8/yѸޚٌ@Yv{c /hs5 g>>LL㸻@fh;jmp^xkH05t+){g۶{Usˋ6k8s4* {!XS"9ZgIG㽁rkZlP,TޔΜ3ֶ2EFq `ع2ltsGv5O>X\x7ܖ Y<I;Š -Bn%v4ʯ a bQq Rd }j]H$un~NlVuEk-Zp8ⱴbCI )QsyT;D8JSGs5y2Q_ڮC?aձkdQWB z*[DDmy)YSD5u/`h]%?D^&r@7^\s֊XӲ=8pE9G݋w~l<" 9g~5.NDqji6}F闫kFE 34RYidܚ P ѴIJ YU{ZE cj,؂?J(|=3֖}0>nN5m1y$μY'N6 \Z:'N#>kRA]eUE%`]S? IyH{ҧ_j6NGKDeNQ>TVryL@[D1/Y5! c0D*7P-)$Do"9 h&桯qa%!rN^i:wx?˖q_\뇡Om1MkOE Flێ :&"~\z7- u%+L4FjRpjWh)`"E}MtFy3Lʹ>7mR5XM}e\-#~^m4PD#'T!HROa7ӢGLQ#;@$(jӴZz3QC =n>[kdXԂH1QF}Q{_2R{N\ ڮ Q0U-DsHc:j^O)MGSDklAvnjDVV9Ca .nXp -V>o4n=ޠ;Oӗܚz2e2q]s[RT@w\`눧 [kz/׊41Ei&q 2 IS1mF{ 0{S!gBjw} DI"n!{J qH"$lsY3($iEldSrk_Z}}+=7ZA4út;Ц{/8$kŸ5c Wk]?U@].%3cPkGz !3,_R\&dy҉ v8&sqm[72Q3j0{\;b<2 ,)5&adӰq y盝oe8d=BYVƬ -"}Y@:'ŸDĀp6Ȇ-{Vw9bsqyj#7]` sAZ(X(R~/,1GAlxSiC4(Xu2b\ᰗ{51Pg&pQJᵳm sJ^oclZ`Ւ={^O> 0 E@\$up^ox|ƘҼ1< gᤧTR¹ˆ/]_<_"B& yX;v>\%sޫP({BQa|G2ea*pb[?fq|(MZwW'g1~P`Q-nKrb2jϡgve{x^O>y2-4vD1k xс6"]Q.[kE Gѿ.QJIXڶ{3YddFPYW?WS@! eYp˟##FIy;bXDG"Mӡ|vc[{)%gWYYCѰ[0"g 4yu&ʼ"A iқ4S2׆du:uI1R^2s"XTgvRpQ sj)aO~XKSFi7=X냗nL%"b˶Gp ʏycZ"9(pV+r?m]RCYGkCtaqIky=.Cp֎BOmip node-v4.2.6/deps/v8/benchmarks/spinning-balls/splay-tree.js000644 000766 000024 00000021303 12650222324 023713 0ustar00iojsstaff000000 000000 // Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * Constructs a Splay tree. A splay tree is a self-balancing binary * search tree with the additional property that recently accessed * elements are quick to access again. It performs basic operations * such as insertion, look-up and removal in O(log(n)) amortized time. * * @constructor */ function SplayTree() { }; /** * Pointer to the root node of the tree. * * @type {SplayTree.Node} * @private */ SplayTree.prototype.root_ = null; /** * @return {boolean} Whether the tree is empty. */ SplayTree.prototype.isEmpty = function() { return !this.root_; }; /** * Inserts a node into the tree with the specified key and value if * the tree does not already contain a node with the specified key. If * the value is inserted, it becomes the root of the tree. * * @param {number} key Key to insert into the tree. * @param {*} value Value to insert into the tree. */ SplayTree.prototype.insert = function(key, value) { if (this.isEmpty()) { this.root_ = new SplayTree.Node(key, value); return; } // Splay on the key to move the last node on the search path for // the key to the root of the tree. this.splay_(key); if (this.root_.key == key) { return; } var node = new SplayTree.Node(key, value); if (key > this.root_.key) { node.left = this.root_; node.right = this.root_.right; this.root_.right = null; } else { node.right = this.root_; node.left = this.root_.left; this.root_.left = null; } this.root_ = node; }; /** * Removes a node with the specified key from the tree if the tree * contains a node with this key. The removed node is returned. If the * key is not found, an exception is thrown. * * @param {number} key Key to find and remove from the tree. * @return {SplayTree.Node} The removed node. */ SplayTree.prototype.remove = function(key) { if (this.isEmpty()) { throw Error('Key not found: ' + key); } this.splay_(key); if (this.root_.key != key) { throw Error('Key not found: ' + key); } var removed = this.root_; if (!this.root_.left) { this.root_ = this.root_.right; } else { var right = this.root_.right; this.root_ = this.root_.left; // Splay to make sure that the new root has an empty right child. this.splay_(key); // Insert the original right child as the right child of the new // root. this.root_.right = right; } return removed; }; /** * Returns the node having the specified key or null if the tree doesn't contain * a node with the specified key. * * @param {number} key Key to find in the tree. * @return {SplayTree.Node} Node having the specified key. */ SplayTree.prototype.find = function(key) { if (this.isEmpty()) { return null; } this.splay_(key); return this.root_.key == key ? this.root_ : null; }; /** * @return {SplayTree.Node} Node having the maximum key value. */ SplayTree.prototype.findMax = function(opt_startNode) { if (this.isEmpty()) { return null; } var current = opt_startNode || this.root_; while (current.right) { current = current.right; } return current; }; /** * @return {SplayTree.Node} Node having the maximum key value that * is less than the specified key value. */ SplayTree.prototype.findGreatestLessThan = function(key) { if (this.isEmpty()) { return null; } // Splay on the key to move the node with the given key or the last // node on the search path to the top of the tree. this.splay_(key); // Now the result is either the root node or the greatest node in // the left subtree. if (this.root_.key < key) { return this.root_; } else if (this.root_.left) { return this.findMax(this.root_.left); } else { return null; } }; /** * @return {Array<*>} An array containing all the keys of tree's nodes. */ SplayTree.prototype.exportKeys = function() { var result = []; if (!this.isEmpty()) { this.root_.traverse_(function(node) { result.push(node.key); }); } return result; }; /** * Perform the splay operation for the given key. Moves the node with * the given key to the top of the tree. If no node has the given * key, the last node on the search path is moved to the top of the * tree. This is the simplified top-down splaying algorithm from: * "Self-adjusting Binary Search Trees" by Sleator and Tarjan * * @param {number} key Key to splay the tree on. * @private */ SplayTree.prototype.splay_ = function(key) { if (this.isEmpty()) { return; } // Create a dummy node. The use of the dummy node is a bit // counter-intuitive: The right child of the dummy node will hold // the L tree of the algorithm. The left child of the dummy node // will hold the R tree of the algorithm. Using a dummy node, left // and right will always be nodes and we avoid special cases. var dummy, left, right; dummy = left = right = new SplayTree.Node(null, null); var current = this.root_; while (true) { if (key < current.key) { if (!current.left) { break; } if (key < current.left.key) { // Rotate right. var tmp = current.left; current.left = tmp.right; tmp.right = current; current = tmp; if (!current.left) { break; } } // Link right. right.left = current; right = current; current = current.left; } else if (key > current.key) { if (!current.right) { break; } if (key > current.right.key) { // Rotate left. var tmp = current.right; current.right = tmp.left; tmp.left = current; current = tmp; if (!current.right) { break; } } // Link left. left.right = current; left = current; current = current.right; } else { break; } } // Assemble. left.right = current.left; right.left = current.right; current.left = dummy.right; current.right = dummy.left; this.root_ = current; }; /** * Constructs a Splay tree node. * * @param {number} key Key. * @param {*} value Value. */ SplayTree.Node = function(key, value) { this.key = key; this.value = value; }; /** * @type {SplayTree.Node} */ SplayTree.Node.prototype.left = null; /** * @type {SplayTree.Node} */ SplayTree.Node.prototype.right = null; /** * Performs an ordered traversal of the subtree starting at * this SplayTree.Node. * * @param {function(SplayTree.Node)} f Visitor function. * @private */ SplayTree.Node.prototype.traverse_ = function(f) { var current = this; while (current) { var left = current.left; if (left) left.traverse_(f); f(current); current = current.right; } }; SplayTree.prototype.traverseBreadthFirst = function (f) { if (f(this.root_.value)) return; var stack = [this.root_]; var length = 1; while (length > 0) { var new_stack = new Array(stack.length * 2); var new_length = 0; for (var i = 0; i < length; i++) { var n = stack[i]; var l = n.left; var r = n.right; if (l) { if (f(l.value)) return; new_stack[new_length++] = l; } if (r) { if (f(r.value)) return; new_stack[new_length++] = r; } } stack = new_stack; length = new_length; } }; node-v4.2.6/deps/v8/benchmarks/spinning-balls/v.js000644 000766 000024 00000031151 12650222324 022075 0ustar00iojsstaff000000 000000 // Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** * This function provides requestAnimationFrame in a cross browser way. * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ */ if ( !window.requestAnimationFrame ) { window.requestAnimationFrame = ( function() { return window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) { window.setTimeout( callback, 1000 / 60 ); }; } )(); } var kNPoints = 8000; var kNModifications = 20; var kNVisiblePoints = 200; var kDecaySpeed = 20; var kPointRadius = 4; var kInitialLifeForce = 100; var livePoints = void 0; var dyingPoints = void 0; var scene = void 0; var renderingStartTime = void 0; var scene = void 0; var pausePlot = void 0; var splayTree = void 0; var numberOfFrames = 0; var sumOfSquaredPauses = 0; var benchmarkStartTime = void 0; var benchmarkTimeLimit = void 0; var autoScale = void 0; var pauseDistribution = []; function Point(x, y, z, payload) { this.x = x; this.y = y; this.z = z; this.next = null; this.prev = null; this.payload = payload; this.lifeForce = kInitialLifeForce; } Point.prototype.color = function () { return "rgba(0, 0, 0, " + (this.lifeForce / kInitialLifeForce) + ")"; }; Point.prototype.decay = function () { this.lifeForce -= kDecaySpeed; return this.lifeForce <= 0; }; function PointsList() { this.head = null; this.count = 0; } PointsList.prototype.add = function (point) { if (this.head !== null) this.head.prev = point; point.next = this.head; this.head = point; this.count++; } PointsList.prototype.remove = function (point) { if (point.next !== null) { point.next.prev = point.prev; } if (point.prev !== null) { point.prev.next = point.next; } else { this.head = point.next; } this.count--; } function GeneratePayloadTree(depth, tag) { if (depth == 0) { return { array : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ], string : 'String for key ' + tag + ' in leaf node' }; } else { return { left: GeneratePayloadTree(depth - 1, tag), right: GeneratePayloadTree(depth - 1, tag) }; } } // To make the benchmark results predictable, we replace Math.random // with a 100% deterministic alternative. Math.random = (function() { var seed = 49734321; return function() { // Robert Jenkins' 32 bit integer hash function. seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff; seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff; seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff; seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff; seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff; seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff; return (seed & 0xfffffff) / 0x10000000; }; })(); function GenerateKey() { // The benchmark framework guarantees that Math.random is // deterministic; see base.js. return Math.random(); } function CreateNewPoint() { // Insert new node with a unique key. var key; do { key = GenerateKey(); } while (splayTree.find(key) != null); var point = new Point(Math.random() * 40 - 20, Math.random() * 40 - 20, Math.random() * 40 - 20, GeneratePayloadTree(5, "" + key)); livePoints.add(point); splayTree.insert(key, point); return key; } function ModifyPointsSet() { if (livePoints.count < kNPoints) { for (var i = 0; i < kNModifications; i++) { CreateNewPoint(); } } else if (kNModifications === 20) { kNModifications = 80; kDecay = 30; } for (var i = 0; i < kNModifications; i++) { var key = CreateNewPoint(); var greatest = splayTree.findGreatestLessThan(key); if (greatest == null) { var point = splayTree.remove(key).value; } else { var point = splayTree.remove(greatest.key).value; } livePoints.remove(point); point.payload = null; dyingPoints.add(point); } } function PausePlot(width, height, size, scale) { var canvas = document.createElement("canvas"); canvas.width = this.width = width; canvas.height = this.height = height; document.body.appendChild(canvas); this.ctx = canvas.getContext('2d'); if (typeof scale !== "number") { this.autoScale = true; this.maxPause = 0; } else { this.autoScale = false; this.maxPause = scale; } this.size = size; // Initialize cyclic buffer for pauses. this.pauses = new Array(this.size); this.start = this.size; this.idx = 0; } PausePlot.prototype.addPause = function (p) { if (this.idx === this.size) { this.idx = 0; } if (this.idx === this.start) { this.start++; } if (this.start === this.size) { this.start = 0; } this.pauses[this.idx++] = p; }; PausePlot.prototype.iteratePauses = function (f) { if (this.start < this.idx) { for (var i = this.start; i < this.idx; i++) { f.call(this, i - this.start, this.pauses[i]); } } else { for (var i = this.start; i < this.size; i++) { f.call(this, i - this.start, this.pauses[i]); } var offs = this.size - this.start; for (var i = 0; i < this.idx; i++) { f.call(this, i + offs, this.pauses[i]); } } }; PausePlot.prototype.draw = function () { var first = null; if (this.autoScale) { this.iteratePauses(function (i, v) { if (first === null) { first = v; } this.maxPause = Math.max(v, this.maxPause); }); } var dx = this.width / this.size; var dy = this.height / this.maxPause; this.ctx.save(); this.ctx.clearRect(0, 0, this.width, this.height); this.ctx.beginPath(); this.ctx.moveTo(1, dy * this.pauses[this.start]); var p = first; this.iteratePauses(function (i, v) { var delta = v - p; var x = 1 + dx * i; var y = dy * v; this.ctx.lineTo(x, y); if (delta > 2 * (p / 3)) { this.ctx.font = "bold 12px sans-serif"; this.ctx.textBaseline = "bottom"; this.ctx.fillText(v + "ms", x + 2, y); } p = v; }); this.ctx.strokeStyle = "black"; this.ctx.stroke(); this.ctx.restore(); } function Scene(width, height) { var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; document.body.appendChild(canvas); this.ctx = canvas.getContext('2d'); this.width = canvas.width; this.height = canvas.height; // Projection configuration. this.x0 = canvas.width / 2; this.y0 = canvas.height / 2; this.z0 = 100; this.f = 1000; // Focal length. // Camera is rotating around y-axis. this.angle = 0; } Scene.prototype.drawPoint = function (x, y, z, color) { // Rotate the camera around y-axis. var rx = x * Math.cos(this.angle) - z * Math.sin(this.angle); var ry = y; var rz = x * Math.sin(this.angle) + z * Math.cos(this.angle); // Perform perspective projection. var px = (this.f * rx) / (rz - this.z0) + this.x0; var py = (this.f * ry) / (rz - this.z0) + this.y0; this.ctx.save(); this.ctx.fillStyle = color this.ctx.beginPath(); this.ctx.arc(px, py, kPointRadius, 0, 2 * Math.PI, true); this.ctx.fill(); this.ctx.restore(); }; Scene.prototype.drawDyingPoints = function () { var point_next = null; for (var point = dyingPoints.head; point !== null; point = point_next) { // Rotate the scene around y-axis. scene.drawPoint(point.x, point.y, point.z, point.color()); point_next = point.next; // Decay the current point and remove it from the list // if it's life-force ran out. if (point.decay()) { dyingPoints.remove(point); } } }; Scene.prototype.draw = function () { this.ctx.save(); this.ctx.clearRect(0, 0, this.width, this.height); this.drawDyingPoints(); this.ctx.restore(); this.angle += Math.PI / 90.0; }; function updateStats(pause) { numberOfFrames++; if (pause > 20) { sumOfSquaredPauses += (pause - 20) * (pause - 20); } pauseDistribution[Math.floor(pause / 10)] |= 0; pauseDistribution[Math.floor(pause / 10)]++; } function renderStats() { var msg = document.createElement("p"); msg.innerHTML = "Score " + Math.round(numberOfFrames * 1000 / sumOfSquaredPauses); var table = document.createElement("table"); table.align = "center"; for (var i = 0; i < pauseDistribution.length; i++) { if (pauseDistribution[i] > 0) { var row = document.createElement("tr"); var time = document.createElement("td"); var count = document.createElement("td"); time.innerHTML = i*10 + "-" + (i+1)*10 + "ms"; count.innerHTML = " => " + pauseDistribution[i]; row.appendChild(time); row.appendChild(count); table.appendChild(row); } } div.appendChild(msg); div.appendChild(table); } function render() { if (typeof renderingStartTime === 'undefined') { renderingStartTime = Date.now(); benchmarkStartTime = renderingStartTime; } ModifyPointsSet(); scene.draw(); var renderingEndTime = Date.now(); var pause = renderingEndTime - renderingStartTime; pausePlot.addPause(pause); renderingStartTime = renderingEndTime; pausePlot.draw(); updateStats(pause); div.innerHTML = livePoints.count + "/" + dyingPoints.count + " " + pause + "(max = " + pausePlot.maxPause + ") ms " + numberOfFrames + " frames"; if (renderingEndTime < benchmarkStartTime + benchmarkTimeLimit) { // Schedule next frame. requestAnimationFrame(render); } else { renderStats(); } } function Form() { function create(tag) { return document.createElement(tag); } function text(value) { return document.createTextNode(value); } this.form = create("form"); this.form.setAttribute("action", "javascript:start()"); var table = create("table"); table.setAttribute("style", "margin-left: auto; margin-right: auto;"); function col(a) { var td = create("td"); td.appendChild(a); return td; } function row(a, b) { var tr = create("tr"); tr.appendChild(col(a)); tr.appendChild(col(b)); return tr; } this.timelimit = create("input"); this.timelimit.setAttribute("value", "60"); table.appendChild(row(text("Time limit in seconds"), this.timelimit)); this.autoscale = create("input"); this.autoscale.setAttribute("type", "checkbox"); this.autoscale.setAttribute("checked", "true"); table.appendChild(row(text("Autoscale pauses plot"), this.autoscale)); var button = create("input"); button.setAttribute("type", "submit"); button.setAttribute("value", "Start"); this.form.appendChild(table); this.form.appendChild(button); document.body.appendChild(this.form); } Form.prototype.remove = function () { document.body.removeChild(this.form); }; function init() { livePoints = new PointsList; dyingPoints = new PointsList; splayTree = new SplayTree(); scene = new Scene(640, 480); div = document.createElement("div"); document.body.appendChild(div); pausePlot = new PausePlot(480, autoScale ? 240 : 500, 160, autoScale ? void 0 : 500); } function start() { benchmarkTimeLimit = form.timelimit.value * 1000; autoScale = form.autoscale.checked; form.remove(); init(); render(); } var form = new Form(); node-v4.2.6/deps/http_parser/.gitignore000644 000766 000024 00000000361 12650222322 020220 0ustar00iojsstaff000000 000000 /out/ core tags *.o test test_g test_fast bench url_parser parsertrace parsertrace_g *.mk *.Makefile *.so.* *.a # Visual Studio uglies *.suo *.sln *.vcxproj *.vcxproj.filters *.vcxproj.user *.opensdf *.ncrunchsolution* *.sdf *.vsp *.psess node-v4.2.6/deps/http_parser/.mailmap000644 000766 000024 00000000740 12650222322 017652 0ustar00iojsstaff000000 000000 # update AUTHORS with: # git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS Ryan Dahl Salman Haq Simon Zimmermann Thomas LE ROUX LE ROUX Thomas Thomas LE ROUX Thomas LE ROUX Fedor Indutny node-v4.2.6/deps/http_parser/.travis.yml000644 000766 000024 00000000204 12650222322 020335 0ustar00iojsstaff000000 000000 language: c compiler: - clang - gcc script: - "make" notifications: email: false irc: - "irc.freenode.net#node-ci" node-v4.2.6/deps/http_parser/AUTHORS000644 000766 000024 00000004644 12650222322 017310 0ustar00iojsstaff000000 000000 # Authors ordered by first contribution. Ryan Dahl Jeremy Hinegardner Sergey Shepelev Joe Damato tomika Phoenix Sol Cliff Frey Ewen Cheslack-Postava Santiago Gala Tim Becker Jeff Terrace Ben Noordhuis Nathan Rajlich Mark Nottingham Aman Gupta Tim Becker Sean Cunningham Peter Griess Salman Haq Cliff Frey Jon Kolb Fouad Mardini Paul Querna Felix Geisendörfer koichik Andre Caron Ivo Raisr James McLaughlin David Gwynne Thomas LE ROUX Randy Rizun Andre Louis Caron Simon Zimmermann Erik Dubbelboer Martell Malone Bertrand Paquet BogDan Vatra Peter Faiman Corey Richardson Tóth Tamás Cam Swords Chris Dickinson Uli Köhler Charlie Somerville Patrik Stutz Fedor Indutny runner Alexis Campailla David Wragg Vinnie Falco Alex Butum Rex Feng Alex Kocharin Mark Koopman Helge Heß Alexis La Goutte George Miroshnykov Maciej Małecki Marc O'Morain Jeff Pinner Timothy J Fontaine Akagi201 Romain Giraud Jay Satiro Arne Steen Kjell Schubert node-v4.2.6/deps/http_parser/bench.c000644 000766 000024 00000006510 12650222322 017455 0ustar00iojsstaff000000 000000 /* Copyright Fedor Indutny. 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 "http_parser.h" #include #include #include #include static const char data[] = "POST /joyent/http-parser HTTP/1.1\r\n" "Host: github.com\r\n" "DNT: 1\r\n" "Accept-Encoding: gzip, deflate, sdch\r\n" "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/39.0.2171.65 Safari/537.36\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9," "image/webp,*/*;q=0.8\r\n" "Referer: https://github.com/joyent/http-parser\r\n" "Connection: keep-alive\r\n" "Transfer-Encoding: chunked\r\n" "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n\r\n"; static const size_t data_len = sizeof(data) - 1; static int on_info(http_parser* p) { return 0; } static int on_data(http_parser* p, const char *at, size_t length) { return 0; } static http_parser_settings settings = { .on_message_begin = on_info, .on_headers_complete = on_info, .on_message_complete = on_info, .on_header_field = on_data, .on_header_value = on_data, .on_url = on_data, .on_status = on_data, .on_body = on_data }; int bench(int iter_count, int silent) { struct http_parser parser; int i; int err; struct timeval start; struct timeval end; float rps; if (!silent) { err = gettimeofday(&start, NULL); assert(err == 0); } for (i = 0; i < iter_count; i++) { size_t parsed; http_parser_init(&parser, HTTP_REQUEST); parsed = http_parser_execute(&parser, &settings, data, data_len); assert(parsed == data_len); } if (!silent) { err = gettimeofday(&end, NULL); assert(err == 0); fprintf(stdout, "Benchmark result:\n"); rps = (float) (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) * 1e-6f; fprintf(stdout, "Took %f seconds to run\n", rps); rps = (float) iter_count / rps; fprintf(stdout, "%f req/sec\n", rps); fflush(stdout); } return 0; } int main(int argc, char** argv) { if (argc == 2 && strcmp(argv[1], "infinite") == 0) { for (;;) bench(5000000, 1); return 0; } else { return bench(5000000, 0); } } node-v4.2.6/deps/http_parser/contrib/000755 000766 000024 00000000000 12650222322 017670 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/http_parser/http_parser.c000644 000766 000024 00000211317 12650222322 020734 0ustar00iojsstaff000000 000000 /* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev * * Additional changes are licensed under the same terms as NGINX and * 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 "http_parser.h" #include #include #include #include #include #include #ifndef ULLONG_MAX # define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ #endif #ifndef MIN # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef ARRAY_SIZE # define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #endif #ifndef BIT_AT # define BIT_AT(a, i) \ (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ (1 << ((unsigned int) (i) & 7)))) #endif #ifndef ELEM_AT # define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) #endif #define SET_ERRNO(e) \ do { \ parser->http_errno = (e); \ } while(0) #define CURRENT_STATE() p_state #define UPDATE_STATE(V) p_state = (enum state) (V); #define RETURN(V) \ do { \ parser->state = CURRENT_STATE(); \ return (V); \ } while (0); #define REEXECUTE() \ goto reexecute; \ #ifdef __GNUC__ # define LIKELY(X) __builtin_expect(!!(X), 1) # define UNLIKELY(X) __builtin_expect(!!(X), 0) #else # define LIKELY(X) (X) # define UNLIKELY(X) (X) #endif /* Run the notify callback FOR, returning ER if it fails */ #define CALLBACK_NOTIFY_(FOR, ER) \ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ if (LIKELY(settings->on_##FOR)) { \ parser->state = CURRENT_STATE(); \ if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ } while (0) /* Run the notify callback FOR and consume the current byte */ #define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) /* Run the notify callback FOR and don't consume the current byte */ #define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) /* Run data callback FOR with LEN bytes, returning ER if it fails */ #define CALLBACK_DATA_(FOR, LEN, ER) \ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ if (FOR##_mark) { \ if (LIKELY(settings->on_##FOR)) { \ parser->state = CURRENT_STATE(); \ if (UNLIKELY(0 != \ settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ FOR##_mark = NULL; \ } \ } while (0) /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) /* Run the data callback FOR and don't consume the current byte */ #define CALLBACK_DATA_NOADVANCE(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) /* Set the mark FOR; non-destructive if mark is already set */ #define MARK(FOR) \ do { \ if (!FOR##_mark) { \ FOR##_mark = p; \ } \ } while (0) /* Don't allow the total size of the HTTP headers (including the status * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect * embedders against denial-of-service attacks where the attacker feeds * us a never-ending header that the embedder keeps buffering. * * This check is arguably the responsibility of embedders but we're doing * it on the embedder's behalf because most won't bother and this way we * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger * than any reasonable request or response so this should never affect * day-to-day operation. */ #define COUNT_HEADER_SIZE(V) \ do { \ parser->nread += (V); \ if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ SET_ERRNO(HPE_HEADER_OVERFLOW); \ goto error; \ } \ } while (0) #define PROXY_CONNECTION "proxy-connection" #define CONNECTION "connection" #define CONTENT_LENGTH "content-length" #define TRANSFER_ENCODING "transfer-encoding" #define UPGRADE "upgrade" #define CHUNKED "chunked" #define KEEP_ALIVE "keep-alive" #define CLOSE "close" static const char *method_strings[] = { #define XX(num, name, string) #string, HTTP_METHOD_MAP(XX) #undef XX }; /* Tokens as defined by rfc 2616. Also lowercases them. * token = 1* * separators = "(" | ")" | "<" | ">" | "@" * | "," | ";" | ":" | "\" | <"> * | "/" | "[" | "]" | "?" | "=" * | "{" | "}" | SP | HT */ static const char tokens[256] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ 0, 0, 0, 0, 0, 0, 0, 0, /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ 0, 0, 0, 0, 0, 0, 0, 0, /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ 0, 0, 0, 0, 0, 0, 0, 0, /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ 0, 0, 0, 0, 0, 0, 0, 0, /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ 0, '!', 0, '#', '$', '%', '&', '\'', /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ 0, 0, '*', '+', 0, '-', '.', 0, /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ '0', '1', '2', '3', '4', '5', '6', '7', /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ '8', '9', 0, 0, 0, 0, 0, 0, /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ 'x', 'y', 'z', 0, 0, 0, '^', '_', /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ 'x', 'y', 'z', 0, '|', 0, '~', 0 }; static const int8_t unhex[256] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; #if HTTP_PARSER_STRICT # define T(v) 0 #else # define T(v) v #endif static const uint8_t normal_url_char[32] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; #undef T enum state { s_dead = 1 /* important that this is > 0 */ , s_start_req_or_res , s_res_or_resp_H , s_start_res , s_res_H , s_res_HT , s_res_HTT , s_res_HTTP , s_res_first_http_major , s_res_http_major , s_res_first_http_minor , s_res_http_minor , s_res_first_status_code , s_res_status_code , s_res_status_start , s_res_status , s_res_line_almost_done , s_start_req , s_req_method , s_req_spaces_before_url , s_req_schema , s_req_schema_slash , s_req_schema_slash_slash , s_req_server_start , s_req_server , s_req_server_with_at , s_req_path , s_req_query_string_start , s_req_query_string , s_req_fragment_start , s_req_fragment , s_req_http_start , s_req_http_H , s_req_http_HT , s_req_http_HTT , s_req_http_HTTP , s_req_first_http_major , s_req_http_major , s_req_first_http_minor , s_req_http_minor , s_req_line_almost_done , s_header_field_start , s_header_field , s_header_value_discard_ws , s_header_value_discard_ws_almost_done , s_header_value_discard_lws , s_header_value_start , s_header_value , s_header_value_lws , s_header_almost_done , s_chunk_size_start , s_chunk_size , s_chunk_parameters , s_chunk_size_almost_done , s_headers_almost_done , s_headers_done /* Important: 's_headers_done' must be the last 'header' state. All * states beyond this must be 'body' states. It is used for overflow * checking. See the PARSING_HEADER() macro. */ , s_chunk_data , s_chunk_data_almost_done , s_chunk_data_done , s_body_identity , s_body_identity_eof , s_message_done }; #define PARSING_HEADER(state) (state <= s_headers_done) enum header_states { h_general = 0 , h_C , h_CO , h_CON , h_matching_connection , h_matching_proxy_connection , h_matching_content_length , h_matching_transfer_encoding , h_matching_upgrade , h_connection , h_content_length , h_transfer_encoding , h_upgrade , h_matching_transfer_encoding_chunked , h_matching_connection_token_start , h_matching_connection_keep_alive , h_matching_connection_close , h_matching_connection_upgrade , h_matching_connection_token , h_transfer_encoding_chunked , h_connection_keep_alive , h_connection_close , h_connection_upgrade }; enum http_host_state { s_http_host_dead = 1 , s_http_userinfo_start , s_http_userinfo , s_http_host_start , s_http_host_v6_start , s_http_host , s_http_host_v6 , s_http_host_v6_end , s_http_host_port_start , s_http_host_port }; /* Macros for character classes; depends on strict-mode */ #define CR '\r' #define LF '\n' #define LOWER(c) (unsigned char)(c | 0x20) #define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') #define IS_NUM(c) ((c) >= '0' && (c) <= '9') #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) #define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) #define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ (c) == ')') #define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ (c) == '$' || (c) == ',') #define STRICT_TOKEN(c) (tokens[(unsigned char)c]) #if HTTP_PARSER_STRICT #define TOKEN(c) (tokens[(unsigned char)c]) #define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) #define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') #else #define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) #define IS_URL_CHAR(c) \ (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) #define IS_HOST_CHAR(c) \ (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') #endif #define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) #if HTTP_PARSER_STRICT # define STRICT_CHECK(cond) \ do { \ if (cond) { \ SET_ERRNO(HPE_STRICT); \ goto error; \ } \ } while (0) # define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) #else # define STRICT_CHECK(cond) # define NEW_MESSAGE() start_state #endif /* Map errno values to strings for human-readable output */ #define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, static struct { const char *name; const char *description; } http_strerror_tab[] = { HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) }; #undef HTTP_STRERROR_GEN int http_message_needs_eof(const http_parser *parser); /* Our URL parser. * * This is designed to be shared by http_parser_execute() for URL validation, * hence it has a state transition + byte-for-byte interface. In addition, it * is meant to be embedded in http_parser_parse_url(), which does the dirty * work of turning state transitions URL components for its API. * * This function should only be invoked with non-space characters. It is * assumed that the caller cares about (and can detect) the transition between * URL and non-URL states by looking for these. */ static enum state parse_url_char(enum state s, const char ch) { if (ch == ' ' || ch == '\r' || ch == '\n') { return s_dead; } #if HTTP_PARSER_STRICT if (ch == '\t' || ch == '\f') { return s_dead; } #endif switch (s) { case s_req_spaces_before_url: /* Proxied requests are followed by scheme of an absolute URI (alpha). * All methods except CONNECT are followed by '/' or '*'. */ if (ch == '/' || ch == '*') { return s_req_path; } if (IS_ALPHA(ch)) { return s_req_schema; } break; case s_req_schema: if (IS_ALPHA(ch)) { return s; } if (ch == ':') { return s_req_schema_slash; } break; case s_req_schema_slash: if (ch == '/') { return s_req_schema_slash_slash; } break; case s_req_schema_slash_slash: if (ch == '/') { return s_req_server_start; } break; case s_req_server_with_at: if (ch == '@') { return s_dead; } /* FALLTHROUGH */ case s_req_server_start: case s_req_server: if (ch == '/') { return s_req_path; } if (ch == '?') { return s_req_query_string_start; } if (ch == '@') { return s_req_server_with_at; } if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { return s_req_server; } break; case s_req_path: if (IS_URL_CHAR(ch)) { return s; } switch (ch) { case '?': return s_req_query_string_start; case '#': return s_req_fragment_start; } break; case s_req_query_string_start: case s_req_query_string: if (IS_URL_CHAR(ch)) { return s_req_query_string; } switch (ch) { case '?': /* allow extra '?' in query string */ return s_req_query_string; case '#': return s_req_fragment_start; } break; case s_req_fragment_start: if (IS_URL_CHAR(ch)) { return s_req_fragment; } switch (ch) { case '?': return s_req_fragment; case '#': return s; } break; case s_req_fragment: if (IS_URL_CHAR(ch)) { return s; } switch (ch) { case '?': case '#': return s; } break; default: break; } /* We should never fall out of the switch above unless there's an error */ return s_dead; } size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; int8_t unhex_val; const char *p = data; const char *header_field_mark = 0; const char *header_value_mark = 0; const char *url_mark = 0; const char *body_mark = 0; const char *status_mark = 0; enum state p_state = (enum state) parser->state; /* We're in an error state. Don't bother doing anything. */ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { return 0; } if (len == 0) { switch (CURRENT_STATE()) { case s_body_identity_eof: /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if * we got paused. */ CALLBACK_NOTIFY_NOADVANCE(message_complete); return 0; case s_dead: case s_start_req_or_res: case s_start_res: case s_start_req: return 0; default: SET_ERRNO(HPE_INVALID_EOF_STATE); return 1; } } if (CURRENT_STATE() == s_header_field) header_field_mark = data; if (CURRENT_STATE() == s_header_value) header_value_mark = data; switch (CURRENT_STATE()) { case s_req_path: case s_req_schema: case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: case s_req_server: case s_req_server_with_at: case s_req_query_string_start: case s_req_query_string: case s_req_fragment_start: case s_req_fragment: url_mark = data; break; case s_res_status: status_mark = data; break; default: break; } for (p=data; p != data + len; p++) { ch = *p; if (PARSING_HEADER(CURRENT_STATE())) COUNT_HEADER_SIZE(1); reexecute: switch (CURRENT_STATE()) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ if (LIKELY(ch == CR || ch == LF)) break; SET_ERRNO(HPE_CLOSED_CONNECTION); goto error; case s_start_req_or_res: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = ULLONG_MAX; if (ch == 'H') { UPDATE_STATE(s_res_or_resp_H); CALLBACK_NOTIFY(message_begin); } else { parser->type = HTTP_REQUEST; UPDATE_STATE(s_start_req); REEXECUTE(); } break; } case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; UPDATE_STATE(s_res_HT); } else { if (UNLIKELY(ch != 'E')) { SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; parser->index = 2; UPDATE_STATE(s_req_method); } break; case s_start_res: { parser->flags = 0; parser->content_length = ULLONG_MAX; switch (ch) { case 'H': UPDATE_STATE(s_res_H); break; case CR: case LF: break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } CALLBACK_NOTIFY(message_begin); break; } case s_res_H: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_res_HT); break; case s_res_HT: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_res_HTT); break; case s_res_HTT: STRICT_CHECK(ch != 'P'); UPDATE_STATE(s_res_HTTP); break; case s_res_HTTP: STRICT_CHECK(ch != '/'); UPDATE_STATE(s_res_first_http_major); break; case s_res_first_http_major: if (UNLIKELY(ch < '0' || ch > '9')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; UPDATE_STATE(s_res_http_major); break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { UPDATE_STATE(s_res_first_http_minor); break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (UNLIKELY(parser->http_major > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; UPDATE_STATE(s_res_http_minor); break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { UPDATE_STATE(s_res_first_status_code); break; } if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (UNLIKELY(parser->http_minor > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } case s_res_first_status_code: { if (!IS_NUM(ch)) { if (ch == ' ') { break; } SET_ERRNO(HPE_INVALID_STATUS); goto error; } parser->status_code = ch - '0'; UPDATE_STATE(s_res_status_code); break; } case s_res_status_code: { if (!IS_NUM(ch)) { switch (ch) { case ' ': UPDATE_STATE(s_res_status_start); break; case CR: UPDATE_STATE(s_res_line_almost_done); break; case LF: UPDATE_STATE(s_header_field_start); break; default: SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (UNLIKELY(parser->status_code > 999)) { SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } case s_res_status_start: { if (ch == CR) { UPDATE_STATE(s_res_line_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); break; } MARK(status); UPDATE_STATE(s_res_status); parser->index = 0; break; } case s_res_status: if (ch == CR) { UPDATE_STATE(s_res_line_almost_done); CALLBACK_DATA(status); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); CALLBACK_DATA(status); break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_field_start); break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = ULLONG_MAX; if (UNLIKELY(!IS_ALPHA(ch))) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } parser->method = (enum http_method) 0; parser->index = 1; switch (ch) { case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; case 'L': parser->method = HTTP_LOCK; break; case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ break; case 'R': parser->method = HTTP_REPORT; break; case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; case 'T': parser->method = HTTP_TRACE; break; case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; } UPDATE_STATE(s_req_method); CALLBACK_NOTIFY(message_begin); break; } case s_req_method: { const char *matcher; if (UNLIKELY(ch == '\0')) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } matcher = method_strings[parser->method]; if (ch == ' ' && matcher[parser->index] == '\0') { UPDATE_STATE(s_req_spaces_before_url); } else if (ch == matcher[parser->index]) { ; /* nada */ } else if (parser->method == HTTP_CONNECT) { if (parser->index == 1 && ch == 'H') { parser->method = HTTP_CHECKOUT; } else if (parser->index == 2 && ch == 'P') { parser->method = HTTP_COPY; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_MKCOL) { if (parser->index == 1 && ch == 'O') { parser->method = HTTP_MOVE; } else if (parser->index == 1 && ch == 'E') { parser->method = HTTP_MERGE; } else if (parser->index == 1 && ch == '-') { parser->method = HTTP_MSEARCH; } else if (parser->index == 2 && ch == 'A') { parser->method = HTTP_MKACTIVITY; } else if (parser->index == 3 && ch == 'A') { parser->method = HTTP_MKCALENDAR; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_SUBSCRIBE) { if (parser->index == 1 && ch == 'E') { parser->method = HTTP_SEARCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 1 && parser->method == HTTP_POST) { if (ch == 'R') { parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ } else if (ch == 'U') { parser->method = HTTP_PUT; /* or HTTP_PURGE */ } else if (ch == 'A') { parser->method = HTTP_PATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 2) { if (parser->method == HTTP_PUT) { if (ch == 'R') { parser->method = HTTP_PURGE; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_UNLOCK) { if (ch == 'S') { parser->method = HTTP_UNSUBSCRIBE; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } ++parser->index; break; } case s_req_spaces_before_url: { if (ch == ' ') break; MARK(url); if (parser->method == HTTP_CONNECT) { UPDATE_STATE(s_req_server_start); } UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } break; } case s_req_schema: case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: { switch (ch) { /* No whitespace allowed here */ case ' ': case CR: case LF: SET_ERRNO(HPE_INVALID_URL); goto error; default: UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } } break; } case s_req_server: case s_req_server_with_at: case s_req_path: case s_req_query_string_start: case s_req_query_string: case s_req_fragment_start: case s_req_fragment: { switch (ch) { case ' ': UPDATE_STATE(s_req_http_start); CALLBACK_DATA(url); break; case CR: case LF: parser->http_major = 0; parser->http_minor = 9; UPDATE_STATE((ch == CR) ? s_req_line_almost_done : s_header_field_start); CALLBACK_DATA(url); break; default: UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } } break; } case s_req_http_start: switch (ch) { case 'H': UPDATE_STATE(s_req_http_H); break; case ' ': break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_req_http_HT); break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_req_http_HTT); break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); UPDATE_STATE(s_req_http_HTTP); break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); UPDATE_STATE(s_req_first_http_major); break; /* first digit of major HTTP version */ case s_req_first_http_major: if (UNLIKELY(ch < '1' || ch > '9')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; UPDATE_STATE(s_req_http_major); break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { UPDATE_STATE(s_req_first_http_minor); break; } if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (UNLIKELY(parser->http_major > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; UPDATE_STATE(s_req_http_minor); break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { UPDATE_STATE(s_req_line_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); break; } /* XXX allow spaces after digit? */ if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (UNLIKELY(parser->http_minor > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* end of request line */ case s_req_line_almost_done: { if (UNLIKELY(ch != LF)) { SET_ERRNO(HPE_LF_EXPECTED); goto error; } UPDATE_STATE(s_header_field_start); break; } case s_header_field_start: { if (ch == CR) { UPDATE_STATE(s_headers_almost_done); break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ UPDATE_STATE(s_headers_almost_done); REEXECUTE(); } c = TOKEN(ch); if (UNLIKELY(!c)) { SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } MARK(header_field); parser->index = 0; UPDATE_STATE(s_header_field); switch (c) { case 'c': parser->header_state = h_C; break; case 'p': parser->header_state = h_matching_proxy_connection; break; case 't': parser->header_state = h_matching_transfer_encoding; break; case 'u': parser->header_state = h_matching_upgrade; break; default: parser->header_state = h_general; break; } break; } case s_header_field: { const char* start = p; for (; p != data + len; p++) { ch = *p; c = TOKEN(ch); if (!c) break; switch (parser->header_state) { case h_general: break; case h_C: parser->index++; parser->header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: parser->index++; parser->header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: parser->index++; switch (c) { case 'n': parser->header_state = h_matching_connection; break; case 't': parser->header_state = h_matching_content_length; break; default: parser->header_state = h_general; break; } break; /* connection */ case h_matching_connection: parser->index++; if (parser->index > sizeof(CONNECTION)-1 || c != CONNECTION[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(CONNECTION)-2) { parser->header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: parser->index++; if (parser->index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { parser->header_state = h_connection; } break; /* content-length */ case h_matching_content_length: parser->index++; if (parser->index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { parser->header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: parser->index++; if (parser->index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { parser->header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: parser->index++; if (parser->index > sizeof(UPGRADE)-1 || c != UPGRADE[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(UPGRADE)-2) { parser->header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') parser->header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } } COUNT_HEADER_SIZE(p - start); if (p == data + len) { --p; break; } if (ch == ':') { UPDATE_STATE(s_header_value_discard_ws); CALLBACK_DATA(header_field); break; } SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } case s_header_value_discard_ws: if (ch == ' ' || ch == '\t') break; if (ch == CR) { UPDATE_STATE(s_header_value_discard_ws_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_value_discard_lws); break; } /* FALLTHROUGH */ case s_header_value_start: { MARK(header_value); UPDATE_STATE(s_header_value); parser->index = 0; c = LOWER(ch); switch (parser->header_state) { case h_upgrade: parser->flags |= F_UPGRADE; parser->header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { parser->header_state = h_matching_transfer_encoding_chunked; } else { parser->header_state = h_general; } break; case h_content_length: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { parser->header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { parser->header_state = h_matching_connection_close; } else if (c == 'u') { parser->header_state = h_matching_connection_upgrade; } else { parser->header_state = h_matching_connection_token; } break; /* Multi-value `Connection` header */ case h_matching_connection_token_start: break; default: parser->header_state = h_general; break; } break; } case s_header_value: { const char* start = p; enum header_states h_state = (enum header_states) parser->header_state; for (; p != data + len; p++) { ch = *p; if (ch == CR) { UPDATE_STATE(s_header_almost_done); parser->header_state = h_state; CALLBACK_DATA(header_value); break; } if (ch == LF) { UPDATE_STATE(s_header_almost_done); COUNT_HEADER_SIZE(p - start); parser->header_state = h_state; CALLBACK_DATA_NOADVANCE(header_value); REEXECUTE(); } c = LOWER(ch); switch (h_state) { case h_general: { const char* p_cr; const char* p_lf; size_t limit = data + len - p; limit = MIN(limit, HTTP_MAX_HEADER_SIZE); p_cr = (const char*) memchr(p, CR, limit); p_lf = (const char*) memchr(p, LF, limit); if (p_cr != NULL) { if (p_lf != NULL && p_cr >= p_lf) p = p_lf; else p = p_cr; } else if (UNLIKELY(p_lf != NULL)) { p = p_lf; } else { p = data + len; } --p; break; } case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: { uint64_t t; if (ch == ' ') break; if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); parser->header_state = h_state; goto error; } t = parser->content_length; t *= 10; t += ch - '0'; /* Overflow? Test against a conservative limit for simplicity. */ if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); parser->header_state = h_state; goto error; } parser->content_length = t; break; } /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: parser->index++; if (parser->index > sizeof(CHUNKED)-1 || c != CHUNKED[parser->index]) { h_state = h_general; } else if (parser->index == sizeof(CHUNKED)-2) { h_state = h_transfer_encoding_chunked; } break; case h_matching_connection_token_start: /* looking for 'Connection: keep-alive' */ if (c == 'k') { h_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { h_state = h_matching_connection_close; } else if (c == 'u') { h_state = h_matching_connection_upgrade; } else if (STRICT_TOKEN(c)) { h_state = h_matching_connection_token; } else if (c == ' ' || c == '\t') { /* Skip lws */ } else { h_state = h_general; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: parser->index++; if (parser->index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(KEEP_ALIVE)-2) { h_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: parser->index++; if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(CLOSE)-2) { h_state = h_connection_close; } break; /* looking for 'Connection: upgrade' */ case h_matching_connection_upgrade: parser->index++; if (parser->index > sizeof(UPGRADE) - 1 || c != UPGRADE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(UPGRADE)-2) { h_state = h_connection_upgrade; } break; case h_matching_connection_token: if (ch == ',') { h_state = h_matching_connection_token_start; parser->index = 0; } break; case h_transfer_encoding_chunked: if (ch != ' ') h_state = h_general; break; case h_connection_keep_alive: case h_connection_close: case h_connection_upgrade: if (ch == ',') { if (h_state == h_connection_keep_alive) { parser->flags |= F_CONNECTION_KEEP_ALIVE; } else if (h_state == h_connection_close) { parser->flags |= F_CONNECTION_CLOSE; } else if (h_state == h_connection_upgrade) { parser->flags |= F_CONNECTION_UPGRADE; } h_state = h_matching_connection_token_start; parser->index = 0; } else if (ch != ' ') { h_state = h_matching_connection_token; } break; default: UPDATE_STATE(s_header_value); h_state = h_general; break; } } parser->header_state = h_state; COUNT_HEADER_SIZE(p - start); if (p == data + len) --p; break; } case s_header_almost_done: { STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_value_lws); break; } case s_header_value_lws: { if (ch == ' ' || ch == '\t') { UPDATE_STATE(s_header_value_start); REEXECUTE(); } /* finished the header */ switch (parser->header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; case h_connection_upgrade: parser->flags |= F_CONNECTION_UPGRADE; break; default: break; } UPDATE_STATE(s_header_field_start); REEXECUTE(); } case s_header_value_discard_ws_almost_done: { STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_value_discard_lws); break; } case s_header_value_discard_lws: { if (ch == ' ' || ch == '\t') { UPDATE_STATE(s_header_value_discard_ws); break; } else { switch (parser->header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_connection_upgrade: parser->flags |= F_CONNECTION_UPGRADE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } /* header value was empty */ MARK(header_value); UPDATE_STATE(s_header_field_start); CALLBACK_DATA_NOADVANCE(header_value); REEXECUTE(); } } case s_headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ UPDATE_STATE(s_message_done); CALLBACK_NOTIFY_NOADVANCE(chunk_complete); REEXECUTE(); } UPDATE_STATE(s_headers_done); /* Set this here so that on_headers_complete() callbacks can see it */ parser->upgrade = ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) == (F_UPGRADE | F_CONNECTION_UPGRADE) || parser->method == HTTP_CONNECT); /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we * will interpret that as saying that this message has no body. This * is needed for the annoying case of recieving a response to a HEAD * request. * * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so * we have to simulate it by handling a change in errno below. */ if (settings->on_headers_complete) { switch (settings->on_headers_complete(parser)) { case 0: break; case 1: parser->flags |= F_SKIPBODY; break; default: SET_ERRNO(HPE_CB_headers_complete); RETURN(p - data); /* Error */ } } if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { RETURN(p - data); } REEXECUTE(); } case s_headers_done: { STRICT_CHECK(ch != LF); parser->nread = 0; int hasBody = parser->flags & F_CHUNKED || (parser->content_length > 0 && parser->content_length != ULLONG_MAX); if (parser->upgrade && (parser->method == HTTP_CONNECT || (parser->flags & F_SKIPBODY) || !hasBody)) { /* Exit, the rest of the message is in a different protocol. */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); RETURN((p - data) + 1); } if (parser->flags & F_SKIPBODY) { UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ UPDATE_STATE(s_chunk_size_start); } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->content_length != ULLONG_MAX) { /* Content-Length header given and non-zero */ UPDATE_STATE(s_body_identity); } else { if (parser->type == HTTP_REQUEST || !http_message_needs_eof(parser)) { /* Assume content-length 0 - read the next */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else { /* Read body until EOF */ UPDATE_STATE(s_body_identity_eof); } } } break; } case s_body_identity: { uint64_t to_read = MIN(parser->content_length, (uint64_t) ((data + len) - p)); assert(parser->content_length != 0 && parser->content_length != ULLONG_MAX); /* The difference between advancing content_length and p is because * the latter will automaticaly advance on the next loop iteration. * Further, if content_length ends up at 0, we want to see the last * byte again for our message complete callback. */ MARK(body); parser->content_length -= to_read; p += to_read - 1; if (parser->content_length == 0) { UPDATE_STATE(s_message_done); /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. * * The alternative to doing this is to wait for the next byte to * trigger the data callback, just as in every other case. The * problem with this is that this makes it difficult for the test * harness to distinguish between complete-on-EOF and * complete-on-length. It's not clear that this distinction is * important for applications, but let's keep it for now. */ CALLBACK_DATA_(body, p - body_mark + 1, p - data); REEXECUTE(); } break; } /* read until EOF */ case s_body_identity_eof: MARK(body); p = data + len - 1; break; case s_message_done: UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); if (parser->upgrade) { /* Exit, the rest of the message is in a different protocol. */ RETURN((p - data) + 1); } break; case s_chunk_size_start: { assert(parser->nread == 1); assert(parser->flags & F_CHUNKED); unhex_val = unhex[(unsigned char)ch]; if (UNLIKELY(unhex_val == -1)) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length = unhex_val; UPDATE_STATE(s_chunk_size); break; } case s_chunk_size: { uint64_t t; assert(parser->flags & F_CHUNKED); if (ch == CR) { UPDATE_STATE(s_chunk_size_almost_done); break; } unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { if (ch == ';' || ch == ' ') { UPDATE_STATE(s_chunk_parameters); break; } SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } t = parser->content_length; t *= 16; t += unhex_val; /* Overflow? Test against a conservative limit for simplicity. */ if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = t; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { UPDATE_STATE(s_chunk_size_almost_done); break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); parser->nread = 0; if (parser->content_length == 0) { parser->flags |= F_TRAILING; UPDATE_STATE(s_header_field_start); } else { UPDATE_STATE(s_chunk_data); } CALLBACK_NOTIFY(chunk_header); break; } case s_chunk_data: { uint64_t to_read = MIN(parser->content_length, (uint64_t) ((data + len) - p)); assert(parser->flags & F_CHUNKED); assert(parser->content_length != 0 && parser->content_length != ULLONG_MAX); /* See the explanation in s_body_identity for why the content * length and data pointers are managed this way. */ MARK(body); parser->content_length -= to_read; p += to_read - 1; if (parser->content_length == 0) { UPDATE_STATE(s_chunk_data_almost_done); } break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); assert(parser->content_length == 0); STRICT_CHECK(ch != CR); UPDATE_STATE(s_chunk_data_done); CALLBACK_DATA(body); break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); parser->nread = 0; UPDATE_STATE(s_chunk_size_start); CALLBACK_NOTIFY(chunk_complete); break; default: assert(0 && "unhandled state"); SET_ERRNO(HPE_INVALID_INTERNAL_STATE); goto error; } } /* Run callbacks for any marks that we have leftover after we ran our of * bytes. There should be at most one of these set, so it's OK to invoke * them in series (unset marks will not result in callbacks). * * We use the NOADVANCE() variety of callbacks here because 'p' has already * overflowed 'data' and this allows us to correct for the off-by-one that * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' * value that's in-bounds). */ assert(((header_field_mark ? 1 : 0) + (header_value_mark ? 1 : 0) + (url_mark ? 1 : 0) + (body_mark ? 1 : 0) + (status_mark ? 1 : 0)) <= 1); CALLBACK_DATA_NOADVANCE(header_field); CALLBACK_DATA_NOADVANCE(header_value); CALLBACK_DATA_NOADVANCE(url); CALLBACK_DATA_NOADVANCE(body); CALLBACK_DATA_NOADVANCE(status); RETURN(len); error: if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { SET_ERRNO(HPE_UNKNOWN); } RETURN(p - data); } /* Does the parser need to see an EOF to find the end of the message? */ int http_message_needs_eof (const http_parser *parser) { if (parser->type == HTTP_REQUEST) { return 0; } /* See RFC 2616 section 4.4 */ if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ parser->status_code == 204 || /* No Content */ parser->status_code == 304 || /* Not Modified */ parser->flags & F_SKIPBODY) { /* response to a HEAD request */ return 0; } if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { return 0; } return 1; } int http_should_keep_alive (const http_parser *parser) { if (parser->http_major > 0 && parser->http_minor > 0) { /* HTTP/1.1 */ if (parser->flags & F_CONNECTION_CLOSE) { return 0; } } else { /* HTTP/1.0 or earlier */ if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { return 0; } } return !http_message_needs_eof(parser); } const char * http_method_str (enum http_method m) { return ELEM_AT(method_strings, m, ""); } void http_parser_init (http_parser *parser, enum http_parser_type t) { void *data = parser->data; /* preserve application data */ memset(parser, 0, sizeof(*parser)); parser->data = data; parser->type = t; parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); parser->http_errno = HPE_OK; } void http_parser_settings_init(http_parser_settings *settings) { memset(settings, 0, sizeof(*settings)); } const char * http_errno_name(enum http_errno err) { assert(((size_t) err) < (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].name; } const char * http_errno_description(enum http_errno err) { assert(((size_t) err) < (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].description; } static enum http_host_state http_parse_host_char(enum http_host_state s, const char ch) { switch(s) { case s_http_userinfo: case s_http_userinfo_start: if (ch == '@') { return s_http_host_start; } if (IS_USERINFO_CHAR(ch)) { return s_http_userinfo; } break; case s_http_host_start: if (ch == '[') { return s_http_host_v6_start; } if (IS_HOST_CHAR(ch)) { return s_http_host; } break; case s_http_host: if (IS_HOST_CHAR(ch)) { return s_http_host; } /* FALLTHROUGH */ case s_http_host_v6_end: if (ch == ':') { return s_http_host_port_start; } break; case s_http_host_v6: if (ch == ']') { return s_http_host_v6_end; } /* FALLTHROUGH */ case s_http_host_v6_start: if (IS_HEX(ch) || ch == ':' || ch == '.') { return s_http_host_v6; } break; case s_http_host_port: case s_http_host_port_start: if (IS_NUM(ch)) { return s_http_host_port; } break; default: break; } return s_http_host_dead; } static int http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { enum http_host_state s; const char *p; size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; u->field_data[UF_HOST].len = 0; s = found_at ? s_http_userinfo_start : s_http_host_start; for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { enum http_host_state new_s = http_parse_host_char(s, *p); if (new_s == s_http_host_dead) { return 1; } switch(new_s) { case s_http_host: if (s != s_http_host) { u->field_data[UF_HOST].off = p - buf; } u->field_data[UF_HOST].len++; break; case s_http_host_v6: if (s != s_http_host_v6) { u->field_data[UF_HOST].off = p - buf; } u->field_data[UF_HOST].len++; break; case s_http_host_port: if (s != s_http_host_port) { u->field_data[UF_PORT].off = p - buf; u->field_data[UF_PORT].len = 0; u->field_set |= (1 << UF_PORT); } u->field_data[UF_PORT].len++; break; case s_http_userinfo: if (s != s_http_userinfo) { u->field_data[UF_USERINFO].off = p - buf ; u->field_data[UF_USERINFO].len = 0; u->field_set |= (1 << UF_USERINFO); } u->field_data[UF_USERINFO].len++; break; default: break; } s = new_s; } /* Make sure we don't end somewhere unexpected */ switch (s) { case s_http_host_start: case s_http_host_v6_start: case s_http_host_v6: case s_http_host_port_start: case s_http_userinfo: case s_http_userinfo_start: return 1; default: break; } return 0; } int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u) { enum state s; const char *p; enum http_parser_url_fields uf, old_uf; int found_at = 0; u->port = u->field_set = 0; s = is_connect ? s_req_server_start : s_req_spaces_before_url; old_uf = UF_MAX; for (p = buf; p < buf + buflen; p++) { s = parse_url_char(s, *p); /* Figure out the next field that we're operating on */ switch (s) { case s_dead: return 1; /* Skip delimeters */ case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: case s_req_query_string_start: case s_req_fragment_start: continue; case s_req_schema: uf = UF_SCHEMA; break; case s_req_server_with_at: found_at = 1; /* FALLTROUGH */ case s_req_server: uf = UF_HOST; break; case s_req_path: uf = UF_PATH; break; case s_req_query_string: uf = UF_QUERY; break; case s_req_fragment: uf = UF_FRAGMENT; break; default: assert(!"Unexpected state"); return 1; } /* Nothing's changed; soldier on */ if (uf == old_uf) { u->field_data[uf].len++; continue; } u->field_data[uf].off = p - buf; u->field_data[uf].len = 1; u->field_set |= (1 << uf); old_uf = uf; } /* host must be present if there is a schema */ /* parsing http:///toto will fail */ if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { if (http_parse_host(buf, u, found_at) != 0) { return 1; } } /* CONNECT requests can only contain "hostname:port" */ if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { return 1; } if (u->field_set & (1 << UF_PORT)) { /* Don't bother with endp; we've already validated the string */ unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); /* Ports have a max value of 2^16 */ if (v > 0xffff) { return 1; } u->port = (uint16_t) v; } return 0; } void http_parser_pause(http_parser *parser, int paused) { /* Users should only be pausing/unpausing a parser that is not in an error * state. In non-debug builds, there's not much that we can do about this * other than ignore it. */ if (HTTP_PARSER_ERRNO(parser) == HPE_OK || HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); } else { assert(0 && "Attempting to pause parser in error state"); } } int http_body_is_final(const struct http_parser *parser) { return parser->state == s_message_done; } unsigned long http_parser_version(void) { return HTTP_PARSER_VERSION_MAJOR * 0x10000 | HTTP_PARSER_VERSION_MINOR * 0x00100 | HTTP_PARSER_VERSION_PATCH * 0x00001; } node-v4.2.6/deps/http_parser/http_parser.gyp000644 000766 000024 00000005447 12650222322 021316 0ustar00iojsstaff000000 000000 # This file is used with the GYP meta build system. # http://code.google.com/p/gyp/ # To build try this: # svn co http://gyp.googlecode.com/svn/trunk gyp # ./gyp/gyp -f make --depth=`pwd` http_parser.gyp # ./out/Debug/test { 'target_defaults': { 'default_configuration': 'Debug', 'configurations': { # TODO: hoist these out and put them somewhere common, because # RuntimeLibrary MUST MATCH across the entire project 'Debug': { 'defines': [ 'DEBUG', '_DEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ], 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 1, # static debug }, }, }, 'Release': { 'defines': [ 'NDEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O3' ], 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 0, # static release }, }, } }, 'msvs_settings': { 'VCCLCompilerTool': { }, 'VCLibrarianTool': { }, 'VCLinkerTool': { 'GenerateDebugInformation': 'true', }, }, 'conditions': [ ['OS == "win"', { 'defines': [ 'WIN32' ], }] ], }, 'targets': [ { 'target_name': 'http_parser', 'type': 'static_library', 'include_dirs': [ '.' ], 'direct_dependent_settings': { 'defines': [ 'HTTP_PARSER_STRICT=0' ], 'include_dirs': [ '.' ], }, 'defines': [ 'HTTP_PARSER_STRICT=0' ], 'sources': [ './http_parser.c', ], 'conditions': [ ['OS=="win"', { 'msvs_settings': { 'VCCLCompilerTool': { # Compile as C++. http_parser.c is actually C99, but C++ is # close enough in this case. 'CompileAs': 2, }, }, }] ], }, { 'target_name': 'http_parser_strict', 'type': 'static_library', 'include_dirs': [ '.' ], 'direct_dependent_settings': { 'defines': [ 'HTTP_PARSER_STRICT=1' ], 'include_dirs': [ '.' ], }, 'defines': [ 'HTTP_PARSER_STRICT=1' ], 'sources': [ './http_parser.c', ], 'conditions': [ ['OS=="win"', { 'msvs_settings': { 'VCCLCompilerTool': { # Compile as C++. http_parser.c is actually C99, but C++ is # close enough in this case. 'CompileAs': 2, }, }, }] ], }, { 'target_name': 'test-nonstrict', 'type': 'executable', 'dependencies': [ 'http_parser' ], 'sources': [ 'test.c' ] }, { 'target_name': 'test-strict', 'type': 'executable', 'dependencies': [ 'http_parser_strict' ], 'sources': [ 'test.c' ] } ] } node-v4.2.6/deps/http_parser/http_parser.h000644 000766 000024 00000031277 12650222322 020746 0ustar00iojsstaff000000 000000 /* 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. */ #ifndef http_parser_h #define http_parser_h #ifdef __cplusplus extern "C" { #endif /* Also update SONAME in the Makefile whenever you change these. */ #define HTTP_PARSER_VERSION_MAJOR 2 #define HTTP_PARSER_VERSION_MINOR 5 #define HTTP_PARSER_VERSION_PATCH 0 #include #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) #include #include typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else #include #endif /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run * faster */ #ifndef HTTP_PARSER_STRICT # define HTTP_PARSER_STRICT 1 #endif /* Maximium header size allowed. If the macro is not defined * before including this header then the default is used. To * change the maximum header size, define the macro in the build * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove * the effective limit on the size of the header, define the macro * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) */ #ifndef HTTP_MAX_HEADER_SIZE # define HTTP_MAX_HEADER_SIZE (80*1024) #endif typedef struct http_parser http_parser; typedef struct http_parser_settings http_parser_settings; /* Callbacks should return non-zero to indicate an error. The parser will * then halt execution. * * The one exception is on_headers_complete. In a HTTP_RESPONSE parser * returning '1' from on_headers_complete will tell the parser that it * should not expect a body. This is used when receiving a response to a * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: * chunked' headers that indicate the presence of a body. * * http_data_cb does not return data chunks. It will be called arbitrarily * many times for each string. E.G. you might get 10 callbacks for "on_url" * each providing just a few characters more data. */ typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); typedef int (*http_cb) (http_parser*); /* Request Methods */ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ XX(1, GET, GET) \ XX(2, HEAD, HEAD) \ XX(3, POST, POST) \ XX(4, PUT, PUT) \ /* pathological */ \ XX(5, CONNECT, CONNECT) \ XX(6, OPTIONS, OPTIONS) \ XX(7, TRACE, TRACE) \ /* webdav */ \ XX(8, COPY, COPY) \ XX(9, LOCK, LOCK) \ XX(10, MKCOL, MKCOL) \ XX(11, MOVE, MOVE) \ XX(12, PROPFIND, PROPFIND) \ XX(13, PROPPATCH, PROPPATCH) \ XX(14, SEARCH, SEARCH) \ XX(15, UNLOCK, UNLOCK) \ /* subversion */ \ XX(16, REPORT, REPORT) \ XX(17, MKACTIVITY, MKACTIVITY) \ XX(18, CHECKOUT, CHECKOUT) \ XX(19, MERGE, MERGE) \ /* upnp */ \ XX(20, MSEARCH, M-SEARCH) \ XX(21, NOTIFY, NOTIFY) \ XX(22, SUBSCRIBE, SUBSCRIBE) \ XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ /* RFC-5789 */ \ XX(24, PATCH, PATCH) \ XX(25, PURGE, PURGE) \ /* CalDAV */ \ XX(26, MKCALENDAR, MKCALENDAR) \ enum http_method { #define XX(num, name, string) HTTP_##name = num, HTTP_METHOD_MAP(XX) #undef XX }; enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; /* Flag values for http_parser.flags field */ enum flags { F_CHUNKED = 1 << 0 , F_CONNECTION_KEEP_ALIVE = 1 << 1 , F_CONNECTION_CLOSE = 1 << 2 , F_CONNECTION_UPGRADE = 1 << 3 , F_TRAILING = 1 << 4 , F_UPGRADE = 1 << 5 , F_SKIPBODY = 1 << 6 }; /* Map for errno-related constants * * The provided argument should be a macro that takes 2 arguments. */ #define HTTP_ERRNO_MAP(XX) \ /* No error */ \ XX(OK, "success") \ \ /* Callback-related errors */ \ XX(CB_message_begin, "the on_message_begin callback failed") \ XX(CB_url, "the on_url callback failed") \ XX(CB_header_field, "the on_header_field callback failed") \ XX(CB_header_value, "the on_header_value callback failed") \ XX(CB_headers_complete, "the on_headers_complete callback failed") \ XX(CB_body, "the on_body callback failed") \ XX(CB_message_complete, "the on_message_complete callback failed") \ XX(CB_status, "the on_status callback failed") \ XX(CB_chunk_header, "the on_chunk_header callback failed") \ XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ \ /* Parsing-related errors */ \ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ XX(HEADER_OVERFLOW, \ "too many header bytes seen; overflow detected") \ XX(CLOSED_CONNECTION, \ "data received after completed connection: close message") \ XX(INVALID_VERSION, "invalid HTTP version") \ XX(INVALID_STATUS, "invalid HTTP status code") \ XX(INVALID_METHOD, "invalid HTTP method") \ XX(INVALID_URL, "invalid URL") \ XX(INVALID_HOST, "invalid host") \ XX(INVALID_PORT, "invalid port") \ XX(INVALID_PATH, "invalid path") \ XX(INVALID_QUERY_STRING, "invalid query string") \ XX(INVALID_FRAGMENT, "invalid fragment") \ XX(LF_EXPECTED, "LF character expected") \ XX(INVALID_HEADER_TOKEN, "invalid character in header") \ XX(INVALID_CONTENT_LENGTH, \ "invalid character in content-length header") \ XX(INVALID_CHUNK_SIZE, \ "invalid character in chunk size header") \ XX(INVALID_CONSTANT, "invalid constant string") \ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ XX(STRICT, "strict mode assertion failed") \ XX(PAUSED, "parser is paused") \ XX(UNKNOWN, "an unknown error occurred") /* Define HPE_* values for each errno value above */ #define HTTP_ERRNO_GEN(n, s) HPE_##n, enum http_errno { HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) }; #undef HTTP_ERRNO_GEN /* Get an http_errno value from an http_parser */ #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) struct http_parser { /** PRIVATE **/ unsigned int type : 2; /* enum http_parser_type */ unsigned int flags : 7; /* F_* values from 'flags' enum; semi-public */ unsigned int state : 7; /* enum state from http_parser.c */ unsigned int header_state : 8; /* enum header_state from http_parser.c */ unsigned int index : 8; /* index into current matcher */ uint32_t nread; /* # bytes read in various scenarios */ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ /** READ-ONLY **/ unsigned short http_major; unsigned short http_minor; unsigned int status_code : 16; /* responses only */ unsigned int method : 8; /* requests only */ unsigned int http_errno : 7; /* 1 = Upgrade header was present and the parser has exited because of that. * 0 = No upgrade header present. * Should be checked when http_parser_execute() returns in addition to * error checking. */ unsigned int upgrade : 1; /** PUBLIC **/ void *data; /* A pointer to get hook to the "connection" or "socket" object */ }; struct http_parser_settings { http_cb on_message_begin; http_data_cb on_url; http_data_cb on_status; http_data_cb on_header_field; http_data_cb on_header_value; http_cb on_headers_complete; http_data_cb on_body; http_cb on_message_complete; /* When on_chunk_header is called, the current chunk length is stored * in parser->content_length. */ http_cb on_chunk_header; http_cb on_chunk_complete; }; enum http_parser_url_fields { UF_SCHEMA = 0 , UF_HOST = 1 , UF_PORT = 2 , UF_PATH = 3 , UF_QUERY = 4 , UF_FRAGMENT = 5 , UF_USERINFO = 6 , UF_MAX = 7 }; /* Result structure for http_parser_parse_url(). * * Callers should index into field_data[] with UF_* values iff field_set * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and * because we probably have padding left over), we convert any port to * a uint16_t. */ struct http_parser_url { uint16_t field_set; /* Bitmask of (1 << UF_*) values */ uint16_t port; /* Converted UF_PORT string */ struct { uint16_t off; /* Offset into buffer in which field starts */ uint16_t len; /* Length of run in buffer */ } field_data[UF_MAX]; }; /* Returns the library version. Bits 16-23 contain the major version number, * bits 8-15 the minor version number and bits 0-7 the patch level. * Usage example: * * unsigned long version = http_parser_version(); * unsigned major = (version >> 16) & 255; * unsigned minor = (version >> 8) & 255; * unsigned patch = version & 255; * printf("http_parser v%u.%u.%u\n", major, minor, patch); */ unsigned long http_parser_version(void); void http_parser_init(http_parser *parser, enum http_parser_type type); /* Initialize http_parser_settings members to 0 */ void http_parser_settings_init(http_parser_settings *settings); /* Executes the parser. Returns number of parsed bytes. Sets * `parser->http_errno` on error. */ size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len); /* If http_should_keep_alive() in the on_headers_complete or * on_message_complete callback returns 0, then this should be * the last message on the connection. * If you are the server, respond with the "Connection: close" header. * If you are the client, close the connection. */ int http_should_keep_alive(const http_parser *parser); /* Returns a string version of the HTTP method. */ const char *http_method_str(enum http_method m); /* Return a string name of the given error */ const char *http_errno_name(enum http_errno err); /* Return a string description of the given error */ const char *http_errno_description(enum http_errno err); /* Parse a URL; return nonzero on failure */ int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u); /* Pause or un-pause the parser; a nonzero value pauses */ void http_parser_pause(http_parser *parser, int paused); /* Checks if this is the final chunk of the body. */ int http_body_is_final(const http_parser *parser); #ifdef __cplusplus } #endif #endif node-v4.2.6/deps/http_parser/LICENSE-MIT000644 000766 000024 00000002343 12650222322 017666 0ustar00iojsstaff000000 000000 http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev. Additional changes are licensed under the same terms as NGINX and 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. node-v4.2.6/deps/http_parser/Makefile000644 000766 000024 00000010625 12650222322 017674 0ustar00iojsstaff000000 000000 # 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. PLATFORM ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') SONAME ?= libhttp_parser.so.2.5.0 CC?=gcc AR?=ar CPPFLAGS ?= LDFLAGS ?= CPPFLAGS += -I. CPPFLAGS_DEBUG = $(CPPFLAGS) -DHTTP_PARSER_STRICT=1 CPPFLAGS_DEBUG += $(CPPFLAGS_DEBUG_EXTRA) CPPFLAGS_FAST = $(CPPFLAGS) -DHTTP_PARSER_STRICT=0 CPPFLAGS_FAST += $(CPPFLAGS_FAST_EXTRA) CPPFLAGS_BENCH = $(CPPFLAGS_FAST) CFLAGS += -Wall -Wextra -Werror CFLAGS_DEBUG = $(CFLAGS) -O0 -g $(CFLAGS_DEBUG_EXTRA) CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA) CFLAGS_BENCH = $(CFLAGS_FAST) -Wno-unused-parameter CFLAGS_LIB = $(CFLAGS_FAST) -fPIC LDFLAGS_LIB = $(LDFLAGS) -shared INSTALL ?= install PREFIX ?= $(DESTDIR)/usr/local LIBDIR = $(PREFIX)/lib INCLUDEDIR = $(PREFIX)/include ifneq (darwin,$(PLATFORM)) # TODO(bnoordhuis) The native SunOS linker expects -h rather than -soname... LDFLAGS_LIB += -Wl,-soname=$(SONAME) endif test: test_g test_fast ./test_g ./test_fast test_g: http_parser_g.o test_g.o $(CC) $(CFLAGS_DEBUG) $(LDFLAGS) http_parser_g.o test_g.o -o $@ test_g.o: test.c http_parser.h Makefile $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c test.c -o $@ http_parser_g.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c http_parser.c -o $@ test_fast: http_parser.o test.o http_parser.h $(CC) $(CFLAGS_FAST) $(LDFLAGS) http_parser.o test.o -o $@ test.o: test.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c test.c -o $@ bench: http_parser.o bench.o $(CC) $(CFLAGS_BENCH) $(LDFLAGS) http_parser.o bench.o -o $@ bench.o: bench.c http_parser.h Makefile $(CC) $(CPPFLAGS_BENCH) $(CFLAGS_BENCH) -c bench.c -o $@ http_parser.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c http_parser.c test-run-timed: test_fast while(true) do time ./test_fast > /dev/null; done test-valgrind: test_g valgrind ./test_g libhttp_parser.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_LIB) -c http_parser.c -o libhttp_parser.o library: libhttp_parser.o $(CC) $(LDFLAGS_LIB) -o $(SONAME) $< package: http_parser.o $(AR) rcs libhttp_parser.a http_parser.o url_parser: http_parser.o contrib/url_parser.c $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o $@ url_parser_g: http_parser_g.o contrib/url_parser.c $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o $@ parsertrace: http_parser.o contrib/parsertrace.c $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o parsertrace parsertrace_g: http_parser_g.o contrib/parsertrace.c $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o parsertrace_g tags: http_parser.c http_parser.h test.c ctags $^ install: library $(INSTALL) -D http_parser.h $(INCLUDEDIR)/http_parser.h $(INSTALL) -D $(SONAME) $(LIBDIR)/$(SONAME) ln -s $(LIBDIR)/$(SONAME) $(LIBDIR)/libhttp_parser.so install-strip: library $(INSTALL) -D http_parser.h $(INCLUDEDIR)/http_parser.h $(INSTALL) -D -s $(SONAME) $(LIBDIR)/$(SONAME) ln -s $(LIBDIR)/$(SONAME) $(LIBDIR)/libhttp_parser.so uninstall: rm $(INCLUDEDIR)/http_parser.h rm $(LIBDIR)/$(SONAME) rm $(LIBDIR)/libhttp_parser.so clean: rm -f *.o *.a tags test test_fast test_g \ http_parser.tar libhttp_parser.so.* \ url_parser url_parser_g parsertrace parsertrace_g contrib/url_parser.c: http_parser.h contrib/parsertrace.c: http_parser.h .PHONY: clean package test-run test-run-timed test-valgrind install install-strip uninstall node-v4.2.6/deps/http_parser/README.md000644 000766 000024 00000016331 12650222322 017513 0ustar00iojsstaff000000 000000 HTTP Parser =========== [![Build Status](https://travis-ci.org/joyent/http-parser.png?branch=master)](https://travis-ci.org/joyent/http-parser) This is a parser for HTTP messages written in C. It parses both requests and responses. The parser is designed to be used in performance HTTP applications. It does not make any syscalls nor allocations, it does not buffer data, it can be interrupted at anytime. Depending on your architecture, it only requires about 40 bytes of data per message stream (in a web server that is per connection). Features: * No dependencies * Handles persistent streams (keep-alive). * Decodes chunked encoding. * Upgrade support * Defends against buffer overflow attacks. The parser extracts the following information from HTTP messages: * Header fields and values * Content-Length * Request method * Response status code * Transfer-Encoding * HTTP version * Request URL * Message body Usage ----- One `http_parser` object is used per TCP connection. Initialize the struct using `http_parser_init()` and set the callbacks. That might look something like this for a request parser: ```c http_parser_settings settings; settings.on_url = my_url_callback; settings.on_header_field = my_header_field_callback; /* ... */ http_parser *parser = malloc(sizeof(http_parser)); http_parser_init(parser, HTTP_REQUEST); parser->data = my_socket; ``` When data is received on the socket execute the parser and check for errors. ```c size_t len = 80*1024, nparsed; char buf[len]; ssize_t recved; recved = recv(fd, buf, len, 0); if (recved < 0) { /* Handle error. */ } /* Start up / continue the parser. * Note we pass recved==0 to signal that EOF has been received. */ nparsed = http_parser_execute(parser, &settings, buf, recved); if (parser->upgrade) { /* handle new protocol */ } else if (nparsed != recved) { /* Handle error. Usually just close the connection. */ } ``` HTTP needs to know where the end of the stream is. For example, sometimes servers send responses without Content-Length and expect the client to consume input (for the body) until EOF. To tell http_parser about EOF, give `0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors can still be encountered during an EOF, so one must still be prepared to receive them. Scalar valued message information such as `status_code`, `method`, and the HTTP version are stored in the parser structure. This data is only temporally stored in `http_parser` and gets reset on each new message. If this information is needed later, copy it out of the structure during the `headers_complete` callback. The parser decodes the transfer-encoding for both requests and responses transparently. That is, a chunked encoding is decoded before being sent to the on_body callback. The Special Problem of Upgrade ------------------------------ HTTP supports upgrading the connection to a different protocol. An increasingly common example of this is the Web Socket protocol which sends a request like GET /demo HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: example.com Origin: http://example.com WebSocket-Protocol: sample followed by non-HTTP data. (See http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 for more information the Web Socket protocol.) To support this, the parser will treat this as a normal HTTP message without a body, issuing both on_headers_complete and on_message_complete callbacks. However http_parser_execute() will stop parsing at the end of the headers and return. The user is expected to check if `parser->upgrade` has been set to 1 after `http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied offset by the return value of `http_parser_execute()`. Callbacks --------- During the `http_parser_execute()` call, the callbacks set in `http_parser_settings` will be executed. The parser maintains state and never looks behind, so buffering the data is not necessary. If you need to save certain data for later usage, you can do that from the callbacks. There are two types of callbacks: * notification `typedef int (*http_cb) (http_parser*);` Callbacks: on_message_begin, on_headers_complete, on_message_complete. * data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` Callbacks: (requests only) on_url, (common) on_header_field, on_header_value, on_body; Callbacks must return 0 on success. Returning a non-zero value indicates error to the parser, making it exit immediately. In case you parse HTTP message in chunks (i.e. `read()` request line from socket, parse, read half headers, parse, etc) your data callbacks may be called more than once. Http-parser guarantees that data pointer is only valid for the lifetime of callback. You can also `read()` into a heap allocated buffer to avoid copying memory around if this fits your application. Reading headers may be a tricky task if you read/parse headers partially. Basically, you need to remember whether last header callback was field or value and apply the following logic: (on_header_field and on_header_value shortened to on_h_*) ------------------------ ------------ -------------------------------------------- | State (prev. callback) | Callback | Description/action | ------------------------ ------------ -------------------------------------------- | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | | | | into it | ------------------------ ------------ -------------------------------------------- | value | on_h_field | New header started. | | | | Copy current name,value buffers to headers | | | | list and allocate new buffer for new name | ------------------------ ------------ -------------------------------------------- | field | on_h_field | Previous name continues. Reallocate name | | | | buffer and append callback data to it | ------------------------ ------------ -------------------------------------------- | field | on_h_value | Value for current header started. Allocate | | | | new buffer and copy callback data to it | ------------------------ ------------ -------------------------------------------- | value | on_h_value | Value continues. Reallocate value buffer | | | | and append callback data to it | ------------------------ ------------ -------------------------------------------- Parsing URLs ------------ A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`. Users of this library may wish to use it to parse URLs constructed from consecutive `on_url` callbacks. See examples of reading in headers: * [partial example](http://gist.github.com/155877) in C * [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C * [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript node-v4.2.6/deps/http_parser/test.c000644 000766 000024 00000311167 12650222322 017364 0ustar00iojsstaff000000 000000 /* 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 "http_parser.h" #include #include #include #include /* rand */ #include #include #if defined(__APPLE__) # undef strlcat # undef strlncpy # undef strlcpy #endif /* defined(__APPLE__) */ #undef TRUE #define TRUE 1 #undef FALSE #define FALSE 0 #define MAX_HEADERS 13 #define MAX_ELEMENT_SIZE 2048 #define MAX_CHUNKS 16 #define MIN(a,b) ((a) < (b) ? (a) : (b)) static http_parser *parser; struct message { const char *name; // for debugging purposes const char *raw; enum http_parser_type type; enum http_method method; int status_code; char response_status[MAX_ELEMENT_SIZE]; char request_path[MAX_ELEMENT_SIZE]; char request_url[MAX_ELEMENT_SIZE]; char fragment[MAX_ELEMENT_SIZE]; char query_string[MAX_ELEMENT_SIZE]; char body[MAX_ELEMENT_SIZE]; size_t body_size; const char *host; const char *userinfo; uint16_t port; int num_headers; enum { NONE=0, FIELD, VALUE } last_header_element; char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE]; int should_keep_alive; int num_chunks; int num_chunks_complete; int chunk_lengths[MAX_CHUNKS]; const char *upgrade; // upgraded body unsigned short http_major; unsigned short http_minor; int message_begin_cb_called; int headers_complete_cb_called; int message_complete_cb_called; int message_complete_on_eof; int body_is_final; }; static int currently_parsing_eof; static struct message messages[5]; static int num_messages; static http_parser_settings *current_pause_parser; /* * R E Q U E S T S * */ const struct message requests[] = #define CURL_GET 0 { {.name= "curl get" ,.type= HTTP_REQUEST ,.raw= "GET /test HTTP/1.1\r\n" "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n" "Host: 0.0.0.0=5000\r\n" "Accept: */*\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 3 ,.headers= { { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" } , { "Host", "0.0.0.0=5000" } , { "Accept", "*/*" } } ,.body= "" } #define FIREFOX_GET 1 , {.name= "firefox get" ,.type= HTTP_REQUEST ,.raw= "GET /favicon.ico HTTP/1.1\r\n" "Host: 0.0.0.0=5000\r\n" "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" "Accept-Language: en-us,en;q=0.5\r\n" "Accept-Encoding: gzip,deflate\r\n" "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" "Keep-Alive: 300\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/favicon.ico" ,.request_url= "/favicon.ico" ,.num_headers= 8 ,.headers= { { "Host", "0.0.0.0=5000" } , { "User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" } , { "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } , { "Accept-Language", "en-us,en;q=0.5" } , { "Accept-Encoding", "gzip,deflate" } , { "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" } , { "Keep-Alive", "300" } , { "Connection", "keep-alive" } } ,.body= "" } #define DUMBFUCK 2 , {.name= "dumbfuck" ,.type= HTTP_REQUEST ,.raw= "GET /dumbfuck HTTP/1.1\r\n" "aaaaaaaaaaaaa:++++++++++\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/dumbfuck" ,.request_url= "/dumbfuck" ,.num_headers= 1 ,.headers= { { "aaaaaaaaaaaaa", "++++++++++" } } ,.body= "" } #define FRAGMENT_IN_URI 3 , {.name= "fragment in url" ,.type= HTTP_REQUEST ,.raw= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "page=1" ,.fragment= "posts-17408" ,.request_path= "/forums/1/topics/2375" /* XXX request url does include fragment? */ ,.request_url= "/forums/1/topics/2375?page=1#posts-17408" ,.num_headers= 0 ,.body= "" } #define GET_NO_HEADERS_NO_BODY 4 , {.name= "get no headers no body" ,.type= HTTP_REQUEST ,.raw= "GET /get_no_headers_no_body/world HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE /* would need Connection: close */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_no_headers_no_body/world" ,.request_url= "/get_no_headers_no_body/world" ,.num_headers= 0 ,.body= "" } #define GET_ONE_HEADER_NO_BODY 5 , {.name= "get one header no body" ,.type= HTTP_REQUEST ,.raw= "GET /get_one_header_no_body HTTP/1.1\r\n" "Accept: */*\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE /* would need Connection: close */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_one_header_no_body" ,.request_url= "/get_one_header_no_body" ,.num_headers= 1 ,.headers= { { "Accept" , "*/*" } } ,.body= "" } #define GET_FUNKY_CONTENT_LENGTH 6 , {.name= "get funky content length body hello" ,.type= HTTP_REQUEST ,.raw= "GET /get_funky_content_length_body_hello HTTP/1.0\r\n" "conTENT-Length: 5\r\n" "\r\n" "HELLO" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_funky_content_length_body_hello" ,.request_url= "/get_funky_content_length_body_hello" ,.num_headers= 1 ,.headers= { { "conTENT-Length" , "5" } } ,.body= "HELLO" } #define POST_IDENTITY_BODY_WORLD 7 , {.name= "post identity body world" ,.type= HTTP_REQUEST ,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" "Accept: */*\r\n" "Transfer-Encoding: identity\r\n" "Content-Length: 5\r\n" "\r\n" "World" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "q=search" ,.fragment= "hey" ,.request_path= "/post_identity_body_world" ,.request_url= "/post_identity_body_world?q=search#hey" ,.num_headers= 3 ,.headers= { { "Accept", "*/*" } , { "Transfer-Encoding", "identity" } , { "Content-Length", "5" } } ,.body= "World" } #define POST_CHUNKED_ALL_YOUR_BASE 8 , {.name= "post - chunked body: all your base are belong to us" ,.type= HTTP_REQUEST ,.raw= "POST /post_chunked_all_your_base HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "1e\r\nall your base are belong to us\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/post_chunked_all_your_base" ,.request_url= "/post_chunked_all_your_base" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding" , "chunked" } } ,.body= "all your base are belong to us" ,.num_chunks_complete= 2 ,.chunk_lengths= { 0x1e } } #define TWO_CHUNKS_MULT_ZERO_END 9 , {.name= "two chunks ; triple zero ending" ,.type= HTTP_REQUEST ,.raw= "POST /two_chunks_mult_zero_end HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5\r\nhello\r\n" "6\r\n world\r\n" "000\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/two_chunks_mult_zero_end" ,.request_url= "/two_chunks_mult_zero_end" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define CHUNKED_W_TRAILING_HEADERS 10 , {.name= "chunked with trailing headers. blech." ,.type= HTTP_REQUEST ,.raw= "POST /chunked_w_trailing_headers HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5\r\nhello\r\n" "6\r\n world\r\n" "0\r\n" "Vary: *\r\n" "Content-Type: text/plain\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/chunked_w_trailing_headers" ,.request_url= "/chunked_w_trailing_headers" ,.num_headers= 3 ,.headers= { { "Transfer-Encoding", "chunked" } , { "Vary", "*" } , { "Content-Type", "text/plain" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11 , {.name= "with bullshit after the length" ,.type= HTTP_REQUEST ,.raw= "POST /chunked_w_bullshit_after_length HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n" "6; blahblah; blah\r\n world\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/chunked_w_bullshit_after_length" ,.request_url= "/chunked_w_bullshit_after_length" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define WITH_QUOTES 12 , {.name= "with quotes" ,.type= HTTP_REQUEST ,.raw= "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "foo=\"bar\"" ,.fragment= "" ,.request_path= "/with_\"stupid\"_quotes" ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\"" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define APACHEBENCH_GET 13 /* The server receiving this request SHOULD NOT wait for EOF * to know that content-length == 0. * How to represent this in a unit test? message_complete_on_eof * Compare with NO_CONTENT_LENGTH_RESPONSE. */ , {.name = "apachebench get" ,.type= HTTP_REQUEST ,.raw= "GET /test HTTP/1.0\r\n" "Host: 0.0.0.0:5000\r\n" "User-Agent: ApacheBench/2.3\r\n" "Accept: */*\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 3 ,.headers= { { "Host", "0.0.0.0:5000" } , { "User-Agent", "ApacheBench/2.3" } , { "Accept", "*/*" } } ,.body= "" } #define QUERY_URL_WITH_QUESTION_MARK_GET 14 /* Some clients include '?' characters in query strings. */ , {.name = "query url with question mark" ,.type= HTTP_REQUEST ,.raw= "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "foo=bar?baz" ,.fragment= "" ,.request_path= "/test.cgi" ,.request_url= "/test.cgi?foo=bar?baz" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define PREFIX_NEWLINE_GET 15 /* Some clients, especially after a POST in a keep-alive connection, * will send an extra CRLF before the next request */ , {.name = "newline prefix get" ,.type= HTTP_REQUEST ,.raw= "\r\nGET /test HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define UPGRADE_REQUEST 16 , {.name = "upgrade request" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" "Sec-WebSocket-Protocol: sample\r\n" "Upgrade: WebSocket\r\n" "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" "Origin: http://example.com\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 7 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Upgrade" } , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } , { "Sec-WebSocket-Protocol", "sample" } , { "Upgrade", "WebSocket" } , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } , { "Origin", "http://example.com" } } ,.body= "" } #define CONNECT_REQUEST 17 , {.name = "connect request" ,.type= HTTP_REQUEST ,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" "some data\r\n" "and yet even more data" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "0-home0.netscape.com:443" ,.num_headers= 2 ,.upgrade="some data\r\nand yet even more data" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #define REPORT_REQ 18 , {.name= "report request" ,.type= HTTP_REQUEST ,.raw= "REPORT /test HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_REPORT ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define NO_HTTP_VERSION 19 , {.name= "request with no http version" ,.type= HTTP_REQUEST ,.raw= "GET /\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 0 ,.http_minor= 9 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define MSEARCH_REQ 20 , {.name= "m-search request" ,.type= HTTP_REQUEST ,.raw= "M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "MAN: \"ssdp:discover\"\r\n" "ST: \"ssdp:all\"\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_MSEARCH ,.query_string= "" ,.fragment= "" ,.request_path= "*" ,.request_url= "*" ,.num_headers= 3 ,.headers= { { "HOST", "239.255.255.250:1900" } , { "MAN", "\"ssdp:discover\"" } , { "ST", "\"ssdp:all\"" } } ,.body= "" } #define LINE_FOLDING_IN_HEADER 21 , {.name= "line folding in header value" ,.type= HTTP_REQUEST ,.raw= "GET / HTTP/1.1\r\n" "Line1: abc\r\n" "\tdef\r\n" " ghi\r\n" "\t\tjkl\r\n" " mno \r\n" "\t \tqrs\r\n" "Line2: \t line2\t\r\n" "Line3:\r\n" " line3\r\n" "Line4: \r\n" " \r\n" "Connection:\r\n" " close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 5 ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } , { "Line2", "line2\t" } , { "Line3", "line3" } , { "Line4", "" } , { "Connection", "close" }, } ,.body= "" } #define QUERY_TERMINATED_HOST 22 , {.name= "host terminated by a query string" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "hail=all" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org?hail=all" ,.host= "hypnotoad.org" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define QUERY_TERMINATED_HOSTPORT 23 , {.name= "host:port terminated by a query string" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "hail=all" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org:1234?hail=all" ,.host= "hypnotoad.org" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define SPACE_TERMINATED_HOSTPORT 24 , {.name= "host:port terminated by a space" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org:1234" ,.host= "hypnotoad.org" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define PATCH_REQ 25 , {.name = "PATCH request" ,.type= HTTP_REQUEST ,.raw= "PATCH /file.txt HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/example\r\n" "If-Match: \"e0023aa4e\"\r\n" "Content-Length: 10\r\n" "\r\n" "cccccccccc" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_PATCH ,.query_string= "" ,.fragment= "" ,.request_path= "/file.txt" ,.request_url= "/file.txt" ,.num_headers= 4 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/example" } , { "If-Match", "\"e0023aa4e\"" } , { "Content-Length", "10" } } ,.body= "cccccccccc" } #define CONNECT_CAPS_REQUEST 26 , {.name = "connect caps request" ,.type= HTTP_REQUEST ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "HOME0.NETSCAPE.COM:443" ,.num_headers= 2 ,.upgrade="" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #if !HTTP_PARSER_STRICT #define UTF8_PATH_REQ 27 , {.name= "utf-8 path request" ,.type= HTTP_REQUEST ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" "Host: github.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "q=1" ,.fragment= "narf" ,.request_path= "/δ¶/δt/pope" ,.request_url= "/δ¶/δt/pope?q=1#narf" ,.num_headers= 1 ,.headers= { {"Host", "github.com" } } ,.body= "" } #define HOSTNAME_UNDERSCORE 28 , {.name = "hostname underscore" ,.type= HTTP_REQUEST ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "home_0.netscape.com:443" ,.num_headers= 2 ,.upgrade="" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #endif /* !HTTP_PARSER_STRICT */ /* see https://github.com/ry/http-parser/issues/47 */ #define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29 , {.name = "eat CRLF between requests, no \"Connection: close\" header" ,.raw= "POST / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 4\r\n" "\r\n" "q=42\r\n" /* note the trailing CRLF */ ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 3 ,.upgrade= 0 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/x-www-form-urlencoded" } , { "Content-Length", "4" } } ,.body= "q=42" } /* see https://github.com/ry/http-parser/issues/47 */ #define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30 , {.name = "eat CRLF between requests even if \"Connection: close\" is set" ,.raw= "POST / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 4\r\n" "Connection: close\r\n" "\r\n" "q=42\r\n" /* note the trailing CRLF */ ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 4 ,.upgrade= 0 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/x-www-form-urlencoded" } , { "Content-Length", "4" } , { "Connection", "close" } } ,.body= "q=42" } #define PURGE_REQ 31 , {.name = "PURGE request" ,.type= HTTP_REQUEST ,.raw= "PURGE /file.txt HTTP/1.1\r\n" "Host: www.example.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_PURGE ,.query_string= "" ,.fragment= "" ,.request_path= "/file.txt" ,.request_url= "/file.txt" ,.num_headers= 1 ,.headers= { { "Host", "www.example.com" } } ,.body= "" } #define SEARCH_REQ 32 , {.name = "SEARCH request" ,.type= HTTP_REQUEST ,.raw= "SEARCH / HTTP/1.1\r\n" "Host: www.example.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_SEARCH ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 1 ,.headers= { { "Host", "www.example.com" } } ,.body= "" } #define PROXY_WITH_BASIC_AUTH 33 , {.name= "host:port and basic_auth" ,.type= HTTP_REQUEST ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.fragment= "" ,.request_path= "/toto" ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto" ,.host= "hypnotoad.org" ,.userinfo= "a%12:b!&*$" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define LINE_FOLDING_IN_HEADER_WITH_LF 34 , {.name= "line folding in header value" ,.type= HTTP_REQUEST ,.raw= "GET / HTTP/1.1\n" "Line1: abc\n" "\tdef\n" " ghi\n" "\t\tjkl\n" " mno \n" "\t \tqrs\n" "Line2: \t line2\t\n" "Line3:\n" " line3\n" "Line4: \n" " \n" "Connection:\n" " close\n" "\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 5 ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } , { "Line2", "line2\t" } , { "Line3", "line3" } , { "Line4", "" } , { "Connection", "close" }, } ,.body= "" } #define CONNECTION_MULTI 35 , {.name = "multiple connection header values with folding" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Something,\r\n" " Upgrade, ,Keep-Alive\r\n" "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" "Sec-WebSocket-Protocol: sample\r\n" "Upgrade: WebSocket\r\n" "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" "Origin: http://example.com\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 7 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Something, Upgrade, ,Keep-Alive" } , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } , { "Sec-WebSocket-Protocol", "sample" } , { "Upgrade", "WebSocket" } , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } , { "Origin", "http://example.com" } } ,.body= "" } #define CONNECTION_MULTI_LWS 36 , {.name = "multiple connection header values with folding and lws" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Connection: keep-alive, upgrade\r\n" "Upgrade: WebSocket\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 2 ,.upgrade="Hot diggity dogg" ,.headers= { { "Connection", "keep-alive, upgrade" } , { "Upgrade", "WebSocket" } } ,.body= "" } #define CONNECTION_MULTI_LWS_CRLF 37 , {.name = "multiple connection header values with folding and lws" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Connection: keep-alive, \r\n upgrade\r\n" "Upgrade: WebSocket\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 2 ,.upgrade="Hot diggity dogg" ,.headers= { { "Connection", "keep-alive, upgrade" } , { "Upgrade", "WebSocket" } } ,.body= "" } #define UPGRADE_POST_REQUEST 38 , {.name = "upgrade post request" ,.type= HTTP_REQUEST ,.raw= "POST /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Upgrade\r\n" "Upgrade: HTTP/2.0\r\n" "Content-Length: 15\r\n" "\r\n" "sweet post body" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 4 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Upgrade" } , { "Upgrade", "HTTP/2.0" } , { "Content-Length", "15" } } ,.body= "sweet post body" } #define CONNECT_WITH_BODY_REQUEST 39 , {.name = "connect with body request" ,.type= HTTP_REQUEST ,.raw= "CONNECT foo.bar.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "Content-Length: 10\r\n" "\r\n" "blarfcicle" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.request_url= "foo.bar.com:443" ,.num_headers= 3 ,.upgrade="blarfcicle" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } , { "Content-Length", "10" } } ,.body= "" } , {.name= NULL } /* sentinel */ }; /* * R E S P O N S E S * */ const struct message responses[] = #define GOOGLE_301 0 { {.name= "google 301" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301 Moved Permanently\r\n" "Location: http://www.google.com/\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n" "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n" "X-$PrototypeBI-Version: 1.6.0.3\r\n" /* $ char in header field */ "Cache-Control: public, max-age=2592000\r\n" "Server: gws\r\n" "Content-Length: 219 \r\n" "\r\n" "\n" "301 Moved\n" "

301 Moved

\n" "The document has moved\n" "here.\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "Moved Permanently" ,.num_headers= 8 ,.headers= { { "Location", "http://www.google.com/" } , { "Content-Type", "text/html; charset=UTF-8" } , { "Date", "Sun, 26 Apr 2009 11:11:49 GMT" } , { "Expires", "Tue, 26 May 2009 11:11:49 GMT" } , { "X-$PrototypeBI-Version", "1.6.0.3" } , { "Cache-Control", "public, max-age=2592000" } , { "Server", "gws" } , { "Content-Length", "219 " } } ,.body= "\n" "301 Moved\n" "

301 Moved

\n" "The document has moved\n" "here.\r\n" "\r\n" } #define NO_CONTENT_LENGTH_RESPONSE 1 /* The client should wait for the server's EOF. That is, when content-length * is not specified, and "Connection: close", the end of body is specified * by the EOF. * Compare with APACHEBENCH_GET */ , {.name= "no content-length response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n" "Server: Apache\r\n" "X-Powered-By: Servlet/2.5 JSP/2.1\r\n" "Content-Type: text/xml; charset=utf-8\r\n" "Connection: close\r\n" "\r\n" "\n" "\n" " \n" " \n" " SOAP-ENV:Client\n" " Client Error\n" " \n" " \n" "" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 5 ,.headers= { { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" } , { "Server", "Apache" } , { "X-Powered-By", "Servlet/2.5 JSP/2.1" } , { "Content-Type", "text/xml; charset=utf-8" } , { "Connection", "close" } } ,.body= "\n" "\n" " \n" " \n" " SOAP-ENV:Client\n" " Client Error\n" " \n" " \n" "" } #define NO_HEADERS_NO_BODY_404 2 , {.name= "404 no headers no body" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 404 ,.response_status= "Not Found" ,.num_headers= 0 ,.headers= {} ,.body_size= 0 ,.body= "" } #define NO_REASON_PHRASE 3 , {.name= "301 no response phrase" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301\r\n\r\n" ,.should_keep_alive = FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define TRAILING_SPACE_ON_CHUNKED_BODY 4 , {.name="200 trailing space on chunked body" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "25 \r\n" "This is the data in the first chunk\r\n" "\r\n" "1C\r\n" "and this is the second one\r\n" "\r\n" "0 \r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { {"Content-Type", "text/plain" } , {"Transfer-Encoding", "chunked" } } ,.body_size = 37+28 ,.body = "This is the data in the first chunk\r\n" "and this is the second one\r\n" ,.num_chunks_complete= 3 ,.chunk_lengths= { 0x25, 0x1c } } #define NO_CARRIAGE_RET 5 , {.name="no carriage ret" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\n" "Content-Type: text/html; charset=utf-8\n" "Connection: close\n" "\n" "these headers are from http://news.ycombinator.com/" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { {"Content-Type", "text/html; charset=utf-8" } , {"Connection", "close" } } ,.body= "these headers are from http://news.ycombinator.com/" } #define PROXY_CONNECTION 6 , {.name="proxy connection" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Content-Length: 11\r\n" "Proxy-Connection: close\r\n" "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n" "\r\n" "hello world" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 4 ,.headers= { {"Content-Type", "text/html; charset=UTF-8" } , {"Content-Length", "11" } , {"Proxy-Connection", "close" } , {"Date", "Thu, 31 Dec 2009 20:55:48 +0000"} } ,.body= "hello world" } #define UNDERSTORE_HEADER_KEY 7 // shown by // curl -o /dev/null -v "http://ad.doubleclick.net/pfadx/DARTSHELLCONFIGXML;dcmt=text/xml;" , {.name="underscore header key" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Server: DCLK-AdSvr\r\n" "Content-Type: text/xml\r\n" "Content-Length: 0\r\n" "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 4 ,.headers= { {"Server", "DCLK-AdSvr" } , {"Content-Type", "text/xml" } , {"Content-Length", "0" } , {"DCLK_imp", "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" } } ,.body= "" } #define BONJOUR_MADAME_FR 8 /* The client should not merge two headers fields when the first one doesn't * have a value. */ , {.name= "bonjourmadame.fr" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 301 Moved Permanently\r\n" "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n" "Server: Apache/2.2.3 (Red Hat)\r\n" "Cache-Control: public\r\n" "Pragma: \r\n" "Location: http://www.bonjourmadame.fr/\r\n" "Vary: Accept-Encoding\r\n" "Content-Length: 0\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 301 ,.response_status= "Moved Permanently" ,.num_headers= 9 ,.headers= { { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" } , { "Server", "Apache/2.2.3 (Red Hat)" } , { "Cache-Control", "public" } , { "Pragma", "" } , { "Location", "http://www.bonjourmadame.fr/" } , { "Vary", "Accept-Encoding" } , { "Content-Length", "0" } , { "Content-Type", "text/html; charset=UTF-8" } , { "Connection", "keep-alive" } } ,.body= "" } #define RES_FIELD_UNDERSCORE 9 /* Should handle spaces in header fields */ , {.name= "field underscore" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n" "Server: Apache\r\n" "Cache-Control: no-cache, must-revalidate\r\n" "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n" "Vary: Accept-Encoding\r\n" "_eep-Alive: timeout=45\r\n" /* semantic value ignored */ "_onnection: Keep-Alive\r\n" /* semantic value ignored */ "Transfer-Encoding: chunked\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n" "0\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 11 ,.headers= { { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" } , { "Server", "Apache" } , { "Cache-Control", "no-cache, must-revalidate" } , { "Expires", "Mon, 26 Jul 1997 05:00:00 GMT" } , { ".et-Cookie", "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" } , { "Vary", "Accept-Encoding" } , { "_eep-Alive", "timeout=45" } , { "_onnection", "Keep-Alive" } , { "Transfer-Encoding", "chunked" } , { "Content-Type", "text/html" } , { "Connection", "close" } } ,.body= "" ,.num_chunks_complete= 1 ,.chunk_lengths= {} } #define NON_ASCII_IN_STATUS_LINE 10 /* Should handle non-ASCII in status line */ , {.name= "non-ASCII in status line" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 500 Oriëntatieprobleem\r\n" "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n" "Content-Length: 0\r\n" "Connection: close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 500 ,.response_status= "Oriëntatieprobleem" ,.num_headers= 3 ,.headers= { { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" } , { "Content-Length", "0" } , { "Connection", "close" } } ,.body= "" } #define HTTP_VERSION_0_9 11 /* Should handle HTTP/0.9 */ , {.name= "http version 0.9" ,.type= HTTP_RESPONSE ,.raw= "HTTP/0.9 200 OK\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 0 ,.http_minor= 9 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12 /* The client should wait for the server's EOF. That is, when neither * content-length nor transfer-encoding is specified, the end of body * is specified by the EOF. */ , {.name= "neither content-length nor transfer-encoding response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "\r\n" "hello world" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Content-Type", "text/plain" } } ,.body= "hello world" } #define NO_BODY_HTTP10_KA_200 13 , {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 200 OK\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Connection", "keep-alive" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP10_KA_204 14 , {.name= "HTTP/1.0 with keep-alive and a 204 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 204 No content\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 1 ,.headers= { { "Connection", "keep-alive" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_200 15 , {.name= "HTTP/1.1 with an EOF-terminated 200 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 0 ,.headers={} ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_204 16 , {.name= "HTTP/1.1 with a 204 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 204 No content\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 0 ,.headers={} ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_NOKA_204 17 , {.name= "HTTP/1.1 with a 204 status and keep-alive disabled" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 204 No content\r\n" "Connection: close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 1 ,.headers= { { "Connection", "close" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_CHUNKED_200 18 , {.name= "HTTP/1.1 with chunked endocing and a 200 response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body_size= 0 ,.body= "" ,.num_chunks_complete= 1 } #if !HTTP_PARSER_STRICT #define SPACE_IN_FIELD_RES 19 /* Should handle spaces in header fields */ , {.name= "field space" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Server: Microsoft-IIS/6.0\r\n" "X-Powered-By: ASP.NET\r\n" "en-US Content-Type: text/xml\r\n" /* this is the problem */ "Content-Type: text/xml\r\n" "Content-Length: 16\r\n" "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n" "Connection: keep-alive\r\n" "\r\n" "hello" /* fake body */ ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 7 ,.headers= { { "Server", "Microsoft-IIS/6.0" } , { "X-Powered-By", "ASP.NET" } , { "en-US Content-Type", "text/xml" } , { "Content-Type", "text/xml" } , { "Content-Length", "16" } , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" } , { "Connection", "keep-alive" } } ,.body= "hello" } #endif /* !HTTP_PARSER_STRICT */ #define AMAZON_COM 20 , {.name= "amazon.com" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301 MovedPermanently\r\n" "Date: Wed, 15 May 2013 17:06:33 GMT\r\n" "Server: Server\r\n" "x-amz-id-1: 0GPHKXSJQ826RK7GZEB2\r\n" "p3p: policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"\r\n" "x-amz-id-2: STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD\r\n" "Location: http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846\r\n" "Vary: Accept-Encoding,User-Agent\r\n" "Content-Type: text/html; charset=ISO-8859-1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "1\r\n" "\n\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "MovedPermanently" ,.num_headers= 9 ,.headers= { { "Date", "Wed, 15 May 2013 17:06:33 GMT" } , { "Server", "Server" } , { "x-amz-id-1", "0GPHKXSJQ826RK7GZEB2" } , { "p3p", "policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"" } , { "x-amz-id-2", "STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD" } , { "Location", "http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846" } , { "Vary", "Accept-Encoding,User-Agent" } , { "Content-Type", "text/html; charset=ISO-8859-1" } , { "Transfer-Encoding", "chunked" } } ,.body= "\n" ,.num_chunks_complete= 2 ,.chunk_lengths= { 1 } } #define EMPTY_REASON_PHRASE_AFTER_SPACE 20 , {.name= "empty reason phrase after space" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 \r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "" ,.num_headers= 0 ,.headers= {} ,.body= "" } , {.name= NULL } /* sentinel */ }; /* strnlen() is a POSIX.2008 addition. Can't rely on it being available so * define it ourselves. */ size_t strnlen(const char *s, size_t maxlen) { const char *p; p = memchr(s, '\0', maxlen); if (p == NULL) return maxlen; return p - s; } size_t strlncat(char *dst, size_t len, const char *src, size_t n) { size_t slen; size_t dlen; size_t rlen; size_t ncpy; slen = strnlen(src, n); dlen = strnlen(dst, len); if (dlen < len) { rlen = len - dlen; ncpy = slen < rlen ? slen : (rlen - 1); memcpy(dst + dlen, src, ncpy); dst[dlen + ncpy] = '\0'; } assert(len > slen + dlen); return slen + dlen; } size_t strlcat(char *dst, const char *src, size_t len) { return strlncat(dst, len, src, (size_t) -1); } size_t strlncpy(char *dst, size_t len, const char *src, size_t n) { size_t slen; size_t ncpy; slen = strnlen(src, n); if (len > 0) { ncpy = slen < len ? slen : (len - 1); memcpy(dst, src, ncpy); dst[ncpy] = '\0'; } assert(len > slen); return slen; } size_t strlcpy(char *dst, const char *src, size_t len) { return strlncpy(dst, len, src, (size_t) -1); } int request_url_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].request_url, sizeof(messages[num_messages].request_url), buf, len); return 0; } int header_field_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); struct message *m = &messages[num_messages]; if (m->last_header_element != FIELD) m->num_headers++; strlncat(m->headers[m->num_headers-1][0], sizeof(m->headers[m->num_headers-1][0]), buf, len); m->last_header_element = FIELD; return 0; } int header_value_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); struct message *m = &messages[num_messages]; strlncat(m->headers[m->num_headers-1][1], sizeof(m->headers[m->num_headers-1][1]), buf, len); m->last_header_element = VALUE; return 0; } void check_body_is_final (const http_parser *p) { if (messages[num_messages].body_is_final) { fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " "on last on_body callback call " "but it doesn't! ***\n\n"); assert(0); abort(); } messages[num_messages].body_is_final = http_body_is_final(p); } int body_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].body, sizeof(messages[num_messages].body), buf, len); messages[num_messages].body_size += len; check_body_is_final(p); // printf("body_cb: '%s'\n", requests[num_messages].body); return 0; } int count_body_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); assert(buf); messages[num_messages].body_size += len; check_body_is_final(p); return 0; } int message_begin_cb (http_parser *p) { assert(p == parser); messages[num_messages].message_begin_cb_called = TRUE; return 0; } int headers_complete_cb (http_parser *p) { assert(p == parser); messages[num_messages].method = parser->method; messages[num_messages].status_code = parser->status_code; messages[num_messages].http_major = parser->http_major; messages[num_messages].http_minor = parser->http_minor; messages[num_messages].headers_complete_cb_called = TRUE; messages[num_messages].should_keep_alive = http_should_keep_alive(parser); return 0; } int message_complete_cb (http_parser *p) { assert(p == parser); if (messages[num_messages].should_keep_alive != http_should_keep_alive(parser)) { fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same " "value in both on_message_complete and on_headers_complete " "but it doesn't! ***\n\n"); assert(0); abort(); } if (messages[num_messages].body_size && http_body_is_final(p) && !messages[num_messages].body_is_final) { fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " "on last on_body callback call " "but it doesn't! ***\n\n"); assert(0); abort(); } messages[num_messages].message_complete_cb_called = TRUE; messages[num_messages].message_complete_on_eof = currently_parsing_eof; num_messages++; return 0; } int response_status_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].response_status, sizeof(messages[num_messages].response_status), buf, len); return 0; } int chunk_header_cb (http_parser *p) { assert(p == parser); int chunk_idx = messages[num_messages].num_chunks; messages[num_messages].num_chunks++; if (chunk_idx < MAX_CHUNKS) { messages[num_messages].chunk_lengths[chunk_idx] = p->content_length; } return 0; } int chunk_complete_cb (http_parser *p) { assert(p == parser); /* Here we want to verify that each chunk_header_cb is matched by a * chunk_complete_cb, so not only should the total number of calls to * both callbacks be the same, but they also should be interleaved * properly */ assert(messages[num_messages].num_chunks == messages[num_messages].num_chunks_complete + 1); messages[num_messages].num_chunks_complete++; return 0; } /* These dontcall_* callbacks exist so that we can verify that when we're * paused, no additional callbacks are invoked */ int dontcall_message_begin_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n"); abort(); } int dontcall_header_field_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n"); abort(); } int dontcall_header_value_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n"); abort(); } int dontcall_request_url_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n"); abort(); } int dontcall_body_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n"); abort(); } int dontcall_headers_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_headers_complete() called on paused " "parser ***\n\n"); abort(); } int dontcall_message_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_message_complete() called on paused " "parser ***\n\n"); abort(); } int dontcall_response_status_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_status() called on paused parser ***\n\n"); abort(); } int dontcall_chunk_header_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_chunk_header() called on paused parser ***\n\n"); exit(1); } int dontcall_chunk_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_chunk_complete() " "called on paused parser ***\n\n"); exit(1); } static http_parser_settings settings_dontcall = {.on_message_begin = dontcall_message_begin_cb ,.on_header_field = dontcall_header_field_cb ,.on_header_value = dontcall_header_value_cb ,.on_url = dontcall_request_url_cb ,.on_status = dontcall_response_status_cb ,.on_body = dontcall_body_cb ,.on_headers_complete = dontcall_headers_complete_cb ,.on_message_complete = dontcall_message_complete_cb ,.on_chunk_header = dontcall_chunk_header_cb ,.on_chunk_complete = dontcall_chunk_complete_cb }; /* These pause_* callbacks always pause the parser and just invoke the regular * callback that tracks content. Before returning, we overwrite the parser * settings to point to the _dontcall variety so that we can verify that * the pause actually did, you know, pause. */ int pause_message_begin_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return message_begin_cb(p); } int pause_header_field_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return header_field_cb(p, buf, len); } int pause_header_value_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return header_value_cb(p, buf, len); } int pause_request_url_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return request_url_cb(p, buf, len); } int pause_body_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return body_cb(p, buf, len); } int pause_headers_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return headers_complete_cb(p); } int pause_message_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return message_complete_cb(p); } int pause_response_status_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return response_status_cb(p, buf, len); } int pause_chunk_header_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return chunk_header_cb(p); } int pause_chunk_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return chunk_complete_cb(p); } static http_parser_settings settings_pause = {.on_message_begin = pause_message_begin_cb ,.on_header_field = pause_header_field_cb ,.on_header_value = pause_header_value_cb ,.on_url = pause_request_url_cb ,.on_status = pause_response_status_cb ,.on_body = pause_body_cb ,.on_headers_complete = pause_headers_complete_cb ,.on_message_complete = pause_message_complete_cb ,.on_chunk_header = pause_chunk_header_cb ,.on_chunk_complete = pause_chunk_complete_cb }; static http_parser_settings settings = {.on_message_begin = message_begin_cb ,.on_header_field = header_field_cb ,.on_header_value = header_value_cb ,.on_url = request_url_cb ,.on_status = response_status_cb ,.on_body = body_cb ,.on_headers_complete = headers_complete_cb ,.on_message_complete = message_complete_cb ,.on_chunk_header = chunk_header_cb ,.on_chunk_complete = chunk_complete_cb }; static http_parser_settings settings_count_body = {.on_message_begin = message_begin_cb ,.on_header_field = header_field_cb ,.on_header_value = header_value_cb ,.on_url = request_url_cb ,.on_status = response_status_cb ,.on_body = count_body_cb ,.on_headers_complete = headers_complete_cb ,.on_message_complete = message_complete_cb ,.on_chunk_header = chunk_header_cb ,.on_chunk_complete = chunk_complete_cb }; static http_parser_settings settings_null = {.on_message_begin = 0 ,.on_header_field = 0 ,.on_header_value = 0 ,.on_url = 0 ,.on_status = 0 ,.on_body = 0 ,.on_headers_complete = 0 ,.on_message_complete = 0 ,.on_chunk_header = 0 ,.on_chunk_complete = 0 }; void parser_init (enum http_parser_type type) { num_messages = 0; assert(parser == NULL); parser = malloc(sizeof(http_parser)); http_parser_init(parser, type); memset(&messages, 0, sizeof messages); } void parser_free () { assert(parser); free(parser); parser = NULL; } size_t parse (const char *buf, size_t len) { size_t nparsed; currently_parsing_eof = (len == 0); nparsed = http_parser_execute(parser, &settings, buf, len); return nparsed; } size_t parse_count_body (const char *buf, size_t len) { size_t nparsed; currently_parsing_eof = (len == 0); nparsed = http_parser_execute(parser, &settings_count_body, buf, len); return nparsed; } size_t parse_pause (const char *buf, size_t len) { size_t nparsed; http_parser_settings s = settings_pause; currently_parsing_eof = (len == 0); current_pause_parser = &s; nparsed = http_parser_execute(parser, current_pause_parser, buf, len); return nparsed; } static inline int check_str_eq (const struct message *m, const char *prop, const char *expected, const char *found) { if ((expected == NULL) != (found == NULL)) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected %s\n", (expected == NULL) ? "NULL" : expected); printf(" found %s\n", (found == NULL) ? "NULL" : found); return 0; } if (expected != NULL && 0 != strcmp(expected, found)) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected '%s'\n", expected); printf(" found '%s'\n", found); return 0; } return 1; } static inline int check_num_eq (const struct message *m, const char *prop, int expected, int found) { if (expected != found) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected %d\n", expected); printf(" found %d\n", found); return 0; } return 1; } #define MESSAGE_CHECK_STR_EQ(expected, found, prop) \ if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0 #define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \ if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0 #define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \ do { \ char ubuf[256]; \ \ if ((u)->field_set & (1 << (fn))) { \ memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \ (u)->field_data[(fn)].len); \ ubuf[(u)->field_data[(fn)].len] = '\0'; \ } else { \ ubuf[0] = '\0'; \ } \ \ check_str_eq(expected, #prop, expected->prop, ubuf); \ } while(0) int message_eq (int index, const struct message *expected) { int i; struct message *m = &messages[index]; MESSAGE_CHECK_NUM_EQ(expected, m, http_major); MESSAGE_CHECK_NUM_EQ(expected, m, http_minor); if (expected->type == HTTP_REQUEST) { MESSAGE_CHECK_NUM_EQ(expected, m, method); } else { MESSAGE_CHECK_NUM_EQ(expected, m, status_code); MESSAGE_CHECK_STR_EQ(expected, m, response_status); } MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive); MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof); assert(m->message_begin_cb_called); assert(m->headers_complete_cb_called); assert(m->message_complete_cb_called); MESSAGE_CHECK_STR_EQ(expected, m, request_url); /* Check URL components; we can't do this w/ CONNECT since it doesn't * send us a well-formed URL. */ if (*m->request_url && m->method != HTTP_CONNECT) { struct http_parser_url u; if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) { fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n", m->request_url); abort(); } if (expected->host) { MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST); } if (expected->userinfo) { MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO); } m->port = (u.field_set & (1 << UF_PORT)) ? u.port : 0; MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY); MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT); MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH); MESSAGE_CHECK_NUM_EQ(expected, m, port); } if (expected->body_size) { MESSAGE_CHECK_NUM_EQ(expected, m, body_size); } else { MESSAGE_CHECK_STR_EQ(expected, m, body); } assert(m->num_chunks == m->num_chunks_complete); MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete); for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) { MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]); } MESSAGE_CHECK_NUM_EQ(expected, m, num_headers); int r; for (i = 0; i < m->num_headers; i++) { r = check_str_eq(expected, "header field", expected->headers[i][0], m->headers[i][0]); if (!r) return 0; r = check_str_eq(expected, "header value", expected->headers[i][1], m->headers[i][1]); if (!r) return 0; } MESSAGE_CHECK_STR_EQ(expected, m, upgrade); return 1; } /* Given a sequence of varargs messages, return the number of them that the * parser should successfully parse, taking into account that upgraded * messages prevent all subsequent messages from being parsed. */ size_t count_parsed_messages(const size_t nmsgs, ...) { size_t i; va_list ap; va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) { struct message *m = va_arg(ap, struct message *); if (m->upgrade) { va_end(ap); return i + 1; } } va_end(ap); return nmsgs; } /* Given a sequence of bytes and the number of these that we were able to * parse, verify that upgrade bodies are correct. */ void upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { va_list ap; size_t i; size_t off = 0; va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) { struct message *m = va_arg(ap, struct message *); off += strlen(m->raw); if (m->upgrade) { off -= strlen(m->upgrade); /* Check the portion of the response after its specified upgrade */ if (!check_str_eq(m, "upgrade", body + off, body + nread)) { abort(); } /* Fix up the response so that message_eq() will verify the beginning * of the upgrade */ *(body + nread + strlen(m->upgrade)) = '\0'; messages[num_messages -1 ].upgrade = body + nread; va_end(ap); return; } } va_end(ap); printf("\n\n*** Error: expected a message with upgrade ***\n"); abort(); } static void print_error (const char *raw, size_t error_location) { fprintf(stderr, "\n*** %s ***\n\n", http_errno_description(HTTP_PARSER_ERRNO(parser))); int this_line = 0, char_len = 0; size_t i, j, len = strlen(raw), error_location_line = 0; for (i = 0; i < len; i++) { if (i == error_location) this_line = 1; switch (raw[i]) { case '\r': char_len = 2; fprintf(stderr, "\\r"); break; case '\n': fprintf(stderr, "\\n\n"); if (this_line) goto print; error_location_line = 0; continue; default: char_len = 1; fputc(raw[i], stderr); break; } if (!this_line) error_location_line += char_len; } fprintf(stderr, "[eof]\n"); print: for (j = 0; j < error_location_line; j++) { fputc(' ', stderr); } fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location); } void test_preserve_data (void) { char my_data[] = "application-specific data"; http_parser parser; parser.data = my_data; http_parser_init(&parser, HTTP_REQUEST); if (parser.data != my_data) { printf("\n*** parser.data not preserved accross http_parser_init ***\n\n"); abort(); } } struct url_test { const char *name; const char *url; int is_connect; struct http_parser_url u; int rv; }; const struct url_test url_tests[] = { {.name="proxy request" ,.url="http://hostname/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 7, 8 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 15, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="proxy request with port" ,.url="http://hostname:444/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) ,.port=444 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 7, 8 } /* UF_HOST */ ,{ 16, 3 } /* UF_PORT */ ,{ 19, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT request" ,.url="hostname:443" ,.is_connect=1 ,.u= {.field_set=(1 << UF_HOST) | (1 << UF_PORT) ,.port=443 ,.field_data= {{ 0, 0 } /* UF_SCHEMA */ ,{ 0, 8 } /* UF_HOST */ ,{ 9, 3 } /* UF_PORT */ ,{ 0, 0 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT request but not connect" ,.url="hostname:443" ,.is_connect=0 ,.rv=1 } , {.name="proxy ipv6 request" ,.url="http://[1:2::3:4]/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 8 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 17, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="proxy ipv6 request with port" ,.url="http://[1:2::3:4]:67/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) ,.port=67 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 8 } /* UF_HOST */ ,{ 18, 2 } /* UF_PORT */ ,{ 20, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT ipv6 address" ,.url="[1:2::3:4]:443" ,.is_connect=1 ,.u= {.field_set=(1 << UF_HOST) | (1 << UF_PORT) ,.port=443 ,.field_data= {{ 0, 0 } /* UF_SCHEMA */ ,{ 1, 8 } /* UF_HOST */ ,{ 11, 3 } /* UF_PORT */ ,{ 0, 0 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="ipv4 in ipv6 address" ,.url="http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 37 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 46, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="extra ? in query string" ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css," "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css," "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css" ,.is_connect=0 ,.u= {.field_set=(1<field_set, u->port); for (i = 0; i < UF_MAX; i++) { if ((u->field_set & (1 << i)) == 0) { printf("\tfield_data[%u]: unset\n", i); continue; } printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"", i, u->field_data[i].off, u->field_data[i].len, u->field_data[i].len, url + u->field_data[i].off); } } void test_parse_url (void) { struct http_parser_url u; const struct url_test *test; unsigned int i; int rv; for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) { test = &url_tests[i]; memset(&u, 0, sizeof(u)); rv = http_parser_parse_url(test->url, strlen(test->url), test->is_connect, &u); if (test->rv == 0) { if (rv != 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " "unexpected rv %d ***\n\n", test->url, test->name, rv); abort(); } if (memcmp(&u, &test->u, sizeof(u)) != 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n", test->url, test->name); printf("target http_parser_url:\n"); dump_url(test->url, &test->u); printf("result http_parser_url:\n"); dump_url(test->url, &u); abort(); } } else { /* test->rv != 0 */ if (rv == 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " "unexpected rv %d ***\n\n", test->url, test->name, rv); abort(); } } } } void test_method_str (void) { assert(0 == strcmp("GET", http_method_str(HTTP_GET))); assert(0 == strcmp("", http_method_str(1337))); } void test_message (const struct message *message) { size_t raw_len = strlen(message->raw); size_t msg1len; for (msg1len = 0; msg1len < raw_len; msg1len++) { parser_init(message->type); size_t read; const char *msg1 = message->raw; const char *msg2 = msg1 + msg1len; size_t msg2len = raw_len - msg1len; if (msg1len) { read = parse(msg1, msg1len); if (message->upgrade && parser->upgrade && num_messages > 0) { messages[num_messages - 1].upgrade = msg1 + read; goto test; } if (read != msg1len) { print_error(msg1, read); abort(); } } read = parse(msg2, msg2len); if (message->upgrade && parser->upgrade) { messages[num_messages - 1].upgrade = msg2 + read; goto test; } if (read != msg2len) { print_error(msg2, read); abort(); } read = parse(NULL, 0); if (read != 0) { print_error(message->raw, read); abort(); } test: if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); abort(); } if(!message_eq(0, message)) abort(); parser_free(); } } void test_message_count_body (const struct message *message) { parser_init(message->type); size_t read; size_t l = strlen(message->raw); size_t i, toread; size_t chunk = 4024; for (i = 0; i < l; i+= chunk) { toread = MIN(l-i, chunk); read = parse_count_body(message->raw + i, toread); if (read != toread) { print_error(message->raw, read); abort(); } } read = parse_count_body(NULL, 0); if (read != 0) { print_error(message->raw, read); abort(); } if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); abort(); } if(!message_eq(0, message)) abort(); parser_free(); } void test_simple (const char *buf, enum http_errno err_expected) { parser_init(HTTP_REQUEST); enum http_errno err; parse(buf, strlen(buf)); err = HTTP_PARSER_ERRNO(parser); parse(NULL, 0); parser_free(); /* In strict mode, allow us to pass with an unexpected HPE_STRICT as * long as the caller isn't expecting success. */ #if HTTP_PARSER_STRICT if (err_expected != err && err_expected != HPE_OK && err != HPE_STRICT) { #else if (err_expected != err) { #endif fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n", http_errno_name(err_expected), http_errno_name(err), buf); abort(); } } void test_header_overflow_error (int req) { http_parser parser; http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); size_t parsed; const char *buf; buf = req ? "GET / HTTP/1.1\r\n" : "HTTP/1.0 200 OK\r\n"; parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); assert(parsed == strlen(buf)); buf = "header-key: header-value\r\n"; size_t buflen = strlen(buf); int i; for (i = 0; i < 10000; i++) { parsed = http_parser_execute(&parser, &settings_null, buf, buflen); if (parsed != buflen) { //fprintf(stderr, "error found on iter %d\n", i); assert(HTTP_PARSER_ERRNO(&parser) == HPE_HEADER_OVERFLOW); return; } } fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n"); abort(); } void test_header_nread_value () { http_parser parser; http_parser_init(&parser, HTTP_REQUEST); size_t parsed; const char *buf; buf = "GET / HTTP/1.1\r\nheader: value\nhdr: value\r\n"; parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); assert(parsed == strlen(buf)); assert(parser.nread == strlen(buf)); } static void test_content_length_overflow (const char *buf, size_t buflen, int expect_ok) { http_parser parser; http_parser_init(&parser, HTTP_RESPONSE); http_parser_execute(&parser, &settings_null, buf, buflen); if (expect_ok) assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK); else assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH); } void test_header_content_length_overflow_error (void) { #define X(size) \ "HTTP/1.1 200 OK\r\n" \ "Content-Length: " #size "\r\n" \ "\r\n" const char a[] = X(1844674407370955160); /* 2^64 / 10 - 1 */ const char b[] = X(18446744073709551615); /* 2^64-1 */ const char c[] = X(18446744073709551616); /* 2^64 */ #undef X test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ } void test_chunk_content_length_overflow_error (void) { #define X(size) \ "HTTP/1.1 200 OK\r\n" \ "Transfer-Encoding: chunked\r\n" \ "\r\n" \ #size "\r\n" \ "..." const char a[] = X(FFFFFFFFFFFFFFE); /* 2^64 / 16 - 1 */ const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */ const char c[] = X(10000000000000000); /* 2^64 */ #undef X test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ } void test_no_overflow_long_body (int req, size_t length) { http_parser parser; http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); size_t parsed; size_t i; char buf1[3000]; size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n", req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length); parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); if (parsed != buf1len) goto err; for (i = 0; i < length; i++) { char foo = 'a'; parsed = http_parser_execute(&parser, &settings_null, &foo, 1); if (parsed != 1) goto err; } parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); if (parsed != buf1len) goto err; return; err: fprintf(stderr, "\n*** error in test_no_overflow_long_body %s of length %lu ***\n", req ? "REQUEST" : "RESPONSE", (unsigned long)length); abort(); } void test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3) { int message_count = count_parsed_messages(3, r1, r2, r3); char total[ strlen(r1->raw) + strlen(r2->raw) + strlen(r3->raw) + 1 ]; total[0] = '\0'; strcat(total, r1->raw); strcat(total, r2->raw); strcat(total, r3->raw); parser_init(r1->type); size_t read; read = parse(total, strlen(total)); if (parser->upgrade) { upgrade_message_fix(total, read, 3, r1, r2, r3); goto test; } if (read != strlen(total)) { print_error(total, read); abort(); } read = parse(NULL, 0); if (read != 0) { print_error(total, read); abort(); } test: if (message_count != num_messages) { fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages); abort(); } if (!message_eq(0, r1)) abort(); if (message_count > 1 && !message_eq(1, r2)) abort(); if (message_count > 2 && !message_eq(2, r3)) abort(); parser_free(); } /* SCAN through every possible breaking to make sure the * parser can handle getting the content in any chunks that * might come from the socket */ void test_scan (const struct message *r1, const struct message *r2, const struct message *r3) { char total[80*1024] = "\0"; char buf1[80*1024] = "\0"; char buf2[80*1024] = "\0"; char buf3[80*1024] = "\0"; strcat(total, r1->raw); strcat(total, r2->raw); strcat(total, r3->raw); size_t read; int total_len = strlen(total); int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2; int ops = 0 ; size_t buf1_len, buf2_len, buf3_len; int message_count = count_parsed_messages(3, r1, r2, r3); int i,j,type_both; for (type_both = 0; type_both < 2; type_both ++ ) { for (j = 2; j < total_len; j ++ ) { for (i = 1; i < j; i ++ ) { if (ops % 1000 == 0) { printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); fflush(stdout); } ops += 1; parser_init(type_both ? HTTP_BOTH : r1->type); buf1_len = i; strlncpy(buf1, sizeof(buf1), total, buf1_len); buf1[buf1_len] = 0; buf2_len = j - i; strlncpy(buf2, sizeof(buf1), total+i, buf2_len); buf2[buf2_len] = 0; buf3_len = total_len - j; strlncpy(buf3, sizeof(buf1), total+j, buf3_len); buf3[buf3_len] = 0; read = parse(buf1, buf1_len); if (parser->upgrade) goto test; if (read != buf1_len) { print_error(buf1, read); goto error; } read += parse(buf2, buf2_len); if (parser->upgrade) goto test; if (read != buf1_len + buf2_len) { print_error(buf2, read); goto error; } read += parse(buf3, buf3_len); if (parser->upgrade) goto test; if (read != buf1_len + buf2_len + buf3_len) { print_error(buf3, read); goto error; } parse(NULL, 0); test: if (parser->upgrade) { upgrade_message_fix(total, read, 3, r1, r2, r3); } if (message_count != num_messages) { fprintf(stderr, "\n\nParser didn't see %d messages only %d\n", message_count, num_messages); goto error; } if (!message_eq(0, r1)) { fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n"); goto error; } if (message_count > 1 && !message_eq(1, r2)) { fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n"); goto error; } if (message_count > 2 && !message_eq(2, r3)) { fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n"); goto error; } parser_free(); } } } puts("\b\b\b\b100%"); return; error: fprintf(stderr, "i=%d j=%d\n", i, j); fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1); fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2); fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3); abort(); } // user required to free the result // string terminated by \0 char * create_large_chunked_message (int body_size_in_kb, const char* headers) { int i; size_t wrote = 0; size_t headers_len = strlen(headers); size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6; char * buf = malloc(bufsize); memcpy(buf, headers, headers_len); wrote += headers_len; for (i = 0; i < body_size_in_kb; i++) { // write 1kb chunk into the body. memcpy(buf + wrote, "400\r\n", 5); wrote += 5; memset(buf + wrote, 'C', 1024); wrote += 1024; strcpy(buf + wrote, "\r\n"); wrote += 2; } memcpy(buf + wrote, "0\r\n\r\n", 6); wrote += 6; assert(wrote == bufsize); return buf; } /* Verify that we can pause parsing at any of the bytes in the * message and still get the result that we're expecting. */ void test_message_pause (const struct message *msg) { char *buf = (char*) msg->raw; size_t buflen = strlen(msg->raw); size_t nread; parser_init(msg->type); do { nread = parse_pause(buf, buflen); // We can only set the upgrade buffer once we've gotten our message // completion callback. if (messages[0].message_complete_cb_called && msg->upgrade && parser->upgrade) { messages[0].upgrade = buf + nread; goto test; } if (nread < buflen) { // Not much do to if we failed a strict-mode check if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) { parser_free(); return; } assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED); } buf += nread; buflen -= nread; http_parser_pause(parser, 0); } while (buflen > 0); nread = parse_pause(NULL, 0); assert (nread == 0); test: if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name); abort(); } if(!message_eq(0, msg)) abort(); parser_free(); } int main (void) { parser = NULL; int i, j, k; int request_count; int response_count; unsigned long version; unsigned major; unsigned minor; unsigned patch; version = http_parser_version(); major = (version >> 16) & 255; minor = (version >> 8) & 255; patch = version & 255; printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version); printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser)); for (request_count = 0; requests[request_count].name; request_count++); for (response_count = 0; responses[response_count].name; response_count++); //// API test_preserve_data(); test_parse_url(); test_method_str(); //// NREAD test_header_nread_value(); //// OVERFLOW CONDITIONS test_header_overflow_error(HTTP_REQUEST); test_no_overflow_long_body(HTTP_REQUEST, 1000); test_no_overflow_long_body(HTTP_REQUEST, 100000); test_header_overflow_error(HTTP_RESPONSE); test_no_overflow_long_body(HTTP_RESPONSE, 1000); test_no_overflow_long_body(HTTP_RESPONSE, 100000); test_header_content_length_overflow_error(); test_chunk_content_length_overflow_error(); //// RESPONSES for (i = 0; i < response_count; i++) { test_message(&responses[i]); } for (i = 0; i < response_count; i++) { test_message_pause(&responses[i]); } for (i = 0; i < response_count; i++) { if (!responses[i].should_keep_alive) continue; for (j = 0; j < response_count; j++) { if (!responses[j].should_keep_alive) continue; for (k = 0; k < response_count; k++) { test_multiple3(&responses[i], &responses[j], &responses[k]); } } } test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]); test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]); // test very large chunked response { char * msg = create_large_chunked_message(31337, "HTTP/1.0 200 OK\r\n" "Transfer-Encoding: chunked\r\n" "Content-Type: text/plain\r\n" "\r\n"); struct message large_chunked = {.name= "large chunked" ,.type= HTTP_RESPONSE ,.raw= msg ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { { "Transfer-Encoding", "chunked" } , { "Content-Type", "text/plain" } } ,.body_size= 31337*1024 ,.num_chunks_complete= 31338 }; for (i = 0; i < MAX_CHUNKS; i++) { large_chunked.chunk_lengths[i] = 1024; } test_message_count_body(&large_chunked); free(msg); } printf("response scan 1/2 "); test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] , &responses[NO_BODY_HTTP10_KA_204] , &responses[NO_REASON_PHRASE] ); printf("response scan 2/2 "); test_scan( &responses[BONJOUR_MADAME_FR] , &responses[UNDERSTORE_HEADER_KEY] , &responses[NO_CARRIAGE_RET] ); puts("responses okay"); /// REQUESTS test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); // Well-formed but incomplete test_simple("GET / HTTP/1.1\r\n" "Content-Type: text/plain\r\n" "Content-Length: 6\r\n" "\r\n" "fooba", HPE_OK); static const char *all_methods[] = { "DELETE", "GET", "HEAD", "POST", "PUT", //"CONNECT", //CONNECT can't be tested like other methods, it's a tunnel "OPTIONS", "TRACE", "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK", "REPORT", "MKACTIVITY", "CHECKOUT", "MERGE", "M-SEARCH", "NOTIFY", "SUBSCRIBE", "UNSUBSCRIBE", "PATCH", 0 }; const char **this_method; for (this_method = all_methods; *this_method; this_method++) { char buf[200]; sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); test_simple(buf, HPE_OK); } static const char *bad_methods[] = { "ASDF", "C******", "COLA", "GEM", "GETA", "M****", "MKCOLA", "PROPPATCHA", "PUN", "PX", "SA", "hello world", 0 }; for (this_method = bad_methods; *this_method; this_method++) { char buf[200]; sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); test_simple(buf, HPE_INVALID_METHOD); } // illegal header field name line folding test_simple("GET / HTTP/1.1\r\n" "name\r\n" " : value\r\n" "\r\n", HPE_INVALID_HEADER_TOKEN); const char *dumbfuck2 = "GET / HTTP/1.1\r\n" "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n" "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n" "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n" "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n" "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n" "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n" "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n" "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n" "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n" "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n" "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n" "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n" "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n" "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n" "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n" "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n" "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n" "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n" "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n" "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n" "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n" "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n" "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n" "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n" "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n" "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n" "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n" "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n" "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n" "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n" "\tRA==\r\n" "\t-----END CERTIFICATE-----\r\n" "\r\n"; test_simple(dumbfuck2, HPE_OK); const char *corrupted_connection = "GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Connection\r\033\065\325eep-Alive\r\n" "Accept-Encoding: gzip\r\n" "\r\n"; test_simple(corrupted_connection, HPE_INVALID_HEADER_TOKEN); const char *corrupted_header_name = "GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" "X-Some-Header\r\033\065\325eep-Alive\r\n" "Accept-Encoding: gzip\r\n" "\r\n"; test_simple(corrupted_header_name, HPE_INVALID_HEADER_TOKEN); #if 0 // NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body // until EOF. // // no content-length // error if there is a body without content length const char *bad_get_no_headers_no_body = "GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n" "Accept: */*\r\n" "\r\n" "HELLO"; test_simple(bad_get_no_headers_no_body, 0); #endif /* TODO sending junk and large headers gets rejected */ /* check to make sure our predefined requests are okay */ for (i = 0; requests[i].name; i++) { test_message(&requests[i]); } for (i = 0; i < request_count; i++) { test_message_pause(&requests[i]); } for (i = 0; i < request_count; i++) { if (!requests[i].should_keep_alive) continue; for (j = 0; j < request_count; j++) { if (!requests[j].should_keep_alive) continue; for (k = 0; k < request_count; k++) { test_multiple3(&requests[i], &requests[j], &requests[k]); } } } printf("request scan 1/4 "); test_scan( &requests[GET_NO_HEADERS_NO_BODY] , &requests[GET_ONE_HEADER_NO_BODY] , &requests[GET_NO_HEADERS_NO_BODY] ); printf("request scan 2/4 "); test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE] , &requests[POST_IDENTITY_BODY_WORLD] , &requests[GET_FUNKY_CONTENT_LENGTH] ); printf("request scan 3/4 "); test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END] , &requests[CHUNKED_W_TRAILING_HEADERS] , &requests[CHUNKED_W_BULLSHIT_AFTER_LENGTH] ); printf("request scan 4/4 "); test_scan( &requests[QUERY_URL_WITH_QUESTION_MARK_GET] , &requests[PREFIX_NEWLINE_GET ] , &requests[CONNECT_REQUEST] ); puts("requests okay"); return 0; } node-v4.2.6/deps/http_parser/contrib/parsertrace.c000644 000766 000024 00000010400 12650222322 022342 0ustar00iojsstaff000000 000000 /* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev * * Additional changes are licensed under the same terms as NGINX and * 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. */ /* Dump what the parser finds to stdout as it happen */ #include "http_parser.h" #include #include #include int on_message_begin(http_parser* _) { (void)_; printf("\n***MESSAGE BEGIN***\n\n"); return 0; } int on_headers_complete(http_parser* _) { (void)_; printf("\n***HEADERS COMPLETE***\n\n"); return 0; } int on_message_complete(http_parser* _) { (void)_; printf("\n***MESSAGE COMPLETE***\n\n"); return 0; } int on_url(http_parser* _, const char* at, size_t length) { (void)_; printf("Url: %.*s\n", (int)length, at); return 0; } int on_header_field(http_parser* _, const char* at, size_t length) { (void)_; printf("Header field: %.*s\n", (int)length, at); return 0; } int on_header_value(http_parser* _, const char* at, size_t length) { (void)_; printf("Header value: %.*s\n", (int)length, at); return 0; } int on_body(http_parser* _, const char* at, size_t length) { (void)_; printf("Body: %.*s\n", (int)length, at); return 0; } void usage(const char* name) { fprintf(stderr, "Usage: %s $type $filename\n" " type: -x, where x is one of {r,b,q}\n" " parses file as a Response, reQuest, or Both\n", name); exit(EXIT_FAILURE); } int main(int argc, char* argv[]) { enum http_parser_type file_type; if (argc != 3) { usage(argv[0]); } char* type = argv[1]; if (type[0] != '-') { usage(argv[0]); } switch (type[1]) { /* in the case of "-", type[1] will be NUL */ case 'r': file_type = HTTP_RESPONSE; break; case 'q': file_type = HTTP_REQUEST; break; case 'b': file_type = HTTP_BOTH; break; default: usage(argv[0]); } char* filename = argv[2]; FILE* file = fopen(filename, "r"); if (file == NULL) { perror("fopen"); goto fail; } fseek(file, 0, SEEK_END); long file_length = ftell(file); if (file_length == -1) { perror("ftell"); goto fail; } fseek(file, 0, SEEK_SET); char* data = malloc(file_length); if (fread(data, 1, file_length, file) != (size_t)file_length) { fprintf(stderr, "couldn't read entire file\n"); free(data); goto fail; } http_parser_settings settings; memset(&settings, 0, sizeof(settings)); settings.on_message_begin = on_message_begin; settings.on_url = on_url; settings.on_header_field = on_header_field; settings.on_header_value = on_header_value; settings.on_headers_complete = on_headers_complete; settings.on_body = on_body; settings.on_message_complete = on_message_complete; http_parser parser; http_parser_init(&parser, file_type); size_t nparsed = http_parser_execute(&parser, &settings, data, file_length); free(data); if (nparsed != (size_t)file_length) { fprintf(stderr, "Error: %s (%s)\n", http_errno_description(HTTP_PARSER_ERRNO(&parser)), http_errno_name(HTTP_PARSER_ERRNO(&parser))); goto fail; } return EXIT_SUCCESS; fail: fclose(file); return EXIT_FAILURE; } node-v4.2.6/deps/http_parser/contrib/url_parser.c000644 000766 000024 00000002142 12650222322 022211 0ustar00iojsstaff000000 000000 #include "http_parser.h" #include #include void dump_url (const char *url, const struct http_parser_url *u) { unsigned int i; printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port); for (i = 0; i < UF_MAX; i++) { if ((u->field_set & (1 << i)) == 0) { printf("\tfield_data[%u]: unset\n", i); continue; } printf("\tfield_data[%u]: off: %u, len: %u, part: %.*s\n", i, u->field_data[i].off, u->field_data[i].len, u->field_data[i].len, url + u->field_data[i].off); } } int main(int argc, char ** argv) { struct http_parser_url u; int len, connect, result; if (argc != 3) { printf("Syntax : %s connect|get url\n", argv[0]); return 1; } len = strlen(argv[2]); connect = strcmp("connect", argv[1]) == 0 ? 1 : 0; printf("Parsing %s, connect %d\n", argv[2], connect); result = http_parser_parse_url(argv[2], len, connect, &u); if (result != 0) { printf("Parse error : %d\n", result); return result; } printf("Parse ok, result : \n"); dump_url(argv[2], &u); return 0; }node-v4.2.6/deps/gtest/gtest.gyp000644 000766 000024 00000001116 12650222322 016671 0ustar00iojsstaff000000 000000 { 'targets': [ { 'target_name': 'gtest', 'type': 'static_library', 'cflags': ['-Wno-missing-field-initializers'], 'direct_dependent_settings': { 'include_dirs': ['include'], }, 'include_dirs': ['.', 'include'], 'sources': [ 'src/gtest-death-test.cc', 'src/gtest-filepath.cc', 'src/gtest-internal-inl.h', 'src/gtest-port.cc', 'src/gtest-printers.cc', 'src/gtest-test-part.cc', 'src/gtest-typed-test.cc', 'src/gtest.cc', 'src/gtest_main.cc', ], } ], } node-v4.2.6/deps/gtest/include/000755 000766 000024 00000000000 12650222322 016446 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/gtest/LICENSE000644 000766 000024 00000002703 12650222322 016032 0ustar00iojsstaff000000 000000 Copyright 2008, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. node-v4.2.6/deps/gtest/src/000755 000766 000024 00000000000 12650222322 015612 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/gtest/src/gtest-death-test.cc000644 000766 000024 00000143561 12650222322 021321 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) // // This file implements death tests. #include "gtest/gtest-death-test.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_DEATH_TEST # if GTEST_OS_MAC # include # endif // GTEST_OS_MAC # include # include # include # if GTEST_OS_LINUX # include # endif // GTEST_OS_LINUX # include # if GTEST_OS_WINDOWS # include # else # include # include # endif // GTEST_OS_WINDOWS # if GTEST_OS_QNX # include # endif // GTEST_OS_QNX #endif // GTEST_HAS_DEATH_TEST #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick exists to // prevent the accidental inclusion of gtest-internal-inl.h in the // user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { // Constants. // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; GTEST_DEFINE_string_( death_test_style, internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), "Indicates how to run a death test in a forked child process: " "\"threadsafe\" (child process re-executes the test binary " "from the beginning, running only the specific death test) or " "\"fast\" (child process runs the death test immediately " "after forking)."); GTEST_DEFINE_bool_( death_test_use_fork, internal::BoolFromGTestEnv("death_test_use_fork", false), "Instructs to use fork()/_exit() instead of clone() in death tests. " "Ignored and always uses fork() on POSIX systems where clone() is not " "implemented. Useful when running under valgrind or similar tools if " "those do not support clone(). Valgrind 3.3.1 will just fail if " "it sees an unsupported combination of clone() flags. " "It is not recommended to use this flag w/o valgrind though it will " "work in 99% of the cases. Once valgrind is fixed, this flag will " "most likely be removed."); namespace internal { GTEST_DEFINE_string_( internal_run_death_test, "", "Indicates the file, line number, temporal index of " "the single death test to run, and a file descriptor to " "which a success code may be sent, all separated by " "the '|' characters. This flag is specified if and only if the current " "process is a sub-process launched for running a thread-safe " "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST namespace internal { // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. static bool g_in_fast_death_test_child = false; // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. bool InDeathTestChild() { # if GTEST_OS_WINDOWS // On Windows, death tests are thread-safe regardless of the value of the // death_test_style flag. return !GTEST_FLAG(internal_run_death_test).empty(); # else if (GTEST_FLAG(death_test_style) == "threadsafe") return !GTEST_FLAG(internal_run_death_test).empty(); else return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { } // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { # if GTEST_OS_WINDOWS return exit_status == exit_code_; # else return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; # endif // GTEST_OS_WINDOWS } # if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS namespace internal { // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). static std::string ExitSummary(int exit_code) { Message m; # if GTEST_OS_WINDOWS m << "Exited with exit status " << exit_code; # else if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } # ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } # endif # endif // GTEST_OS_WINDOWS return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } # if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. static std::string DeathTestThreadWarning(size_t thread_count) { Message msg; msg << "Death tests use fork(), which is unsafe particularly" << " in a threaded context. For this test, " << GTEST_NAME_ << " "; if (thread_count == 0) msg << "couldn't detect the number of threads."; else msg << "detected " << thread_count << " threads."; return msg.GetString(); } # endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; // An enumeration describing all of the possible ways that a death test can // conclude. DIED means that the process died while executing the test // code; LIVED means that process lived beyond the end of the test code; // RETURNED means that the test statement attempted to execute a return // statement, which is not allowed; THREW means that the test statement // returned control by throwing an exception. IN_PROGRESS means the test // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. void DeathTestAbort(const std::string& message) { // On a POSIX system, this function may be called from a threadsafe-style // death test child process, which operates on a very small stack. Use // the heap for any additional non-minuscule memory requirements. const InternalRunDeathTestFlag* const flag = GetUnitTestImpl()->internal_run_death_test_flag(); if (flag != NULL) { FILE* parent = posix::FDOpen(flag->write_fd(), "w"); fputc(kDeathTestInternalError, parent); fprintf(parent, "%s", message.c_str()); fflush(parent); _exit(1); } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. # define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression); \ } \ } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return // -1 on failure, and set errno to EINTR when it is interrupted and // should be tried again. The macro expands to a loop that repeatedly // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. # define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ gtest_retval = (expression); \ } while (gtest_retval == -1 && errno == EINTR); \ if (gtest_retval == -1) { \ DeathTestAbort( \ ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + ::testing::internal::StreamableToString(__LINE__) + ": " \ + #expression + " != -1"); \ } \ } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. std::string GetLastErrnoDescription() { return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure // message from the death test child process and log it with the FATAL // severity. On Windows, the message is read from a pipe handle. On other // platforms, it is read from a file descriptor. static void FailFromInternalError(int fd) { Message error; char buffer[256]; int num_read; do { while ((num_read = posix::Read(fd, buffer, 255)) > 0) { buffer[num_read] = '\0'; error << buffer; } } while (num_read == -1 && errno == EINTR); if (num_read == 0) { GTEST_LOG_(FATAL) << error.GetString(); } else { const int last_error = errno; GTEST_LOG_(FATAL) << "Error while reading death test internal: " << GetLastErrnoDescription() << " [" << last_error << "]"; } } // Death test constructor. Increments the running death test count // for the current test. DeathTest::DeathTest() { TestInfo* const info = GetUnitTestImpl()->current_test_info(); if (info == NULL) { DeathTestAbort("Cannot run a death test outside of a TEST or " "TEST_F construct"); } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { return GetUnitTestImpl()->death_test_factory()->Create( statement, regex, file, line, test); } const char* DeathTest::LastMessage() { return last_death_test_message_.c_str(); } void DeathTest::set_last_death_test_message(const std::string& message) { last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. class DeathTestImpl : public DeathTest { protected: DeathTestImpl(const char* a_statement, const RE* a_regex) : statement_(a_statement), regex_(a_regex), spawned_(false), status_(-1), outcome_(IN_PROGRESS), read_fd_(-1), write_fd_(-1) {} // read_fd_ is expected to be closed and cleared by a derived class. ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } void Abort(AbortReason reason); virtual bool Passed(bool status_ok); const char* statement() const { return statement_; } const RE* regex() const { return regex_; } bool spawned() const { return spawned_; } void set_spawned(bool is_spawned) { spawned_ = is_spawned; } int status() const { return status_; } void set_status(int a_status) { status_ = a_status; } DeathTestOutcome outcome() const { return outcome_; } void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } int read_fd() const { return read_fd_; } void set_read_fd(int fd) { read_fd_ = fd; } int write_fd() const { return write_fd_; } void set_write_fd(int fd) { write_fd_ = fd; } // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void ReadAndInterpretStatusByte(); private: // The textual content of the code this object is testing. This class // doesn't own this string and should not attempt to delete it. const char* const statement_; // The regular expression which test output must match. DeathTestImpl // doesn't own this object and should not attempt to delete it. const RE* const regex_; // True if the death test child process has been successfully spawned. bool spawned_; // The exit status of the child process. int status_; // How the death test concluded. DeathTestOutcome outcome_; // Descriptor to the read end of the pipe to the child process. It is // always -1 in the child process. The child keeps its write end of the // pipe in write_fd_. int read_fd_; // Descriptor to the child's write end of the pipe to the parent process. // It is always -1 in the parent process. The parent keeps its end of the // pipe in read_fd_. int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. void DeathTestImpl::ReadAndInterpretStatusByte() { char flag; int bytes_read; // The read() here blocks until data is available (signifying the // failure of the death test) or until the pipe is closed (signifying // its success), so it's okay to call this in the parent before // the child process has exited. do { bytes_read = posix::Read(read_fd(), &flag, 1); } while (bytes_read == -1 && errno == EINTR); if (bytes_read == 0) { set_outcome(DIED); } else if (bytes_read == 1) { switch (flag) { case kDeathTestReturned: set_outcome(RETURNED); break; case kDeathTestThrew: set_outcome(THREW); break; case kDeathTestLived: set_outcome(LIVED); break; case kDeathTestInternalError: FailFromInternalError(read_fd()); // Does not return. break; default: GTEST_LOG_(FATAL) << "Death test child process reported " << "unexpected status byte (" << static_cast(flag) << ")"; } } else { GTEST_LOG_(FATAL) << "Read from death test child process failed: " << GetLastErrnoDescription(); } GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); set_read_fd(-1); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then // calls _exit(1). void DeathTestImpl::Abort(AbortReason reason) { // The parent process considers the death test to be a failure if // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. const char status_ch = reason == TEST_DID_NOT_DIE ? kDeathTestLived : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); // We are leaking the descriptor here because on some platforms (i.e., // when built as Windows DLL), destructors of global objects will still // run after calling _exit(). On such systems, write_fd_ will be // indirectly closed from the destructor of UnitTestImpl, causing double // close if it is also closed here. On debug configurations, double close // may assert. As there are no in-process buffers to flush here, we are // relying on the OS to close the descriptor after the process terminates // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. static ::std::string FormatDeathTestOutput(const ::std::string& output) { ::std::string ret; for (size_t at = 0; ; ) { const size_t line_end = output.find('\n', at); ret += "[ DEATH ] "; if (line_end == ::std::string::npos) { ret += output.substr(at); break; } ret += output.substr(at, line_end + 1 - at); at = line_end + 1; } return ret; } // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: // outcome: An enumeration describing how the death test // concluded: DIED, LIVED, THREW, or RETURNED. The death test // fails in the latter three cases. // status: The exit status of the child process. On *nix, it is in the // in the format specified by wait(2). On Windows, this is the // value supplied to the ExitProcess() API or a numeric code // of the exception that terminated the program. // regex: A regular expression object to be applied to // the test's captured standard error output; the death test // fails if it does not match. // // Argument: // status_ok: true if exit_status is acceptable in the context of // this particular death test, which fails if it is false // // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. bool DeathTestImpl::Passed(bool status_ok) { if (!spawned()) return false; const std::string error_message = GetCapturedStderr(); bool success = false; Message buffer; buffer << "Death test: " << statement() << "\n"; switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case THREW: buffer << " Result: threw an exception.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); if (matched) { success = true; } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" << " " << ExitSummary(status()) << "\n" << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: default: GTEST_LOG_(FATAL) << "DeathTest::Passed somehow called before conclusion of test"; } DeathTest::set_last_death_test_message(buffer.GetString()); return success; } # if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the // --gtest_death_test_style=fast setting to be equivalent to // --gtest_death_test_style=threadsafe there. // // A few implementation notes: Like the Linux version, the Windows // implementation uses pipes for child-to-parent communication. But due to // the specifics of pipes on Windows, some extra steps are required: // // 1. The parent creates a communication pipe and stores handles to both // ends of it. // 2. The parent starts the child and provides it with the information // necessary to acquire the handle to the write end of the pipe. // 3. The child acquires the write end of the pipe and signals the parent // using a Windows event. // 4. Now the parent can release the write end of the pipe on its side. If // this is done before step 3, the object's reference count goes down to // 0 and it is destroyed, preventing the child from acquiring it. The // parent now has to release it, or read operations on the read end of // the pipe will not return when the child terminates. // 5. The parent reads child's output through the pipe (outcome code and // any possible error messages) from the pipe, and its stderr and then // determines whether to fail the test. // // Note: to distinguish Win32 API calls from the local method and function // calls, the former are explicitly resolved in the global namespace. // class WindowsDeathTest : public DeathTestImpl { public: WindowsDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); virtual TestRole AssumeRole(); private: // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; // Handle to the write end of the pipe to the child process. AutoHandle write_handle_; // Child process handle. AutoHandle child_handle_; // Event the child process uses to signal the parent that it has // acquired the handle to the write end of the pipe. After seeing this // event the parent can release its own handles to make sure its // ReadFile() calls return when the child terminates. AutoHandle event_handle_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int WindowsDeathTest::Wait() { if (!spawned()) return 0; // Wait until the child either signals that it has acquired the write end // of the pipe or it dies. const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; switch (::WaitForMultipleObjects(2, wait_handles, FALSE, // Waits for any of the handles. INFINITE)) { case WAIT_OBJECT_0: case WAIT_OBJECT_0 + 1: break; default: GTEST_DEATH_TEST_CHECK_(false); // Should not get here. } // The child has acquired the write end of the pipe or exited. // We release the handle on our side and continue. write_handle_.Reset(); event_handle_.Reset(); ReadAndInterpretStatusByte(); // Waits for the child process to exit if it haven't already. This // returns immediately if the child has already exited, regardless of // whether previous calls to WaitForMultipleObjects synchronized on this // handle or not. GTEST_DEATH_TEST_CHECK_( WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); DWORD status_code; GTEST_DEATH_TEST_CHECK_( ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); set_status(static_cast(status_code)); return status(); } // The AssumeRole process for a Windows death test. It creates a child // process with the same executable as the current process to run the // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. DeathTest::TestRole WindowsDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { // ParseInternalRunDeathTestFlag() has performed all the necessary // processing. set_write_fd(flag->write_fd()); return EXECUTE_TEST; } // WindowsDeathTest uses an anonymous pipe to communicate results of // a death test. SECURITY_ATTRIBUTES handles_are_inheritable = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; HANDLE read_handle, write_handle; GTEST_DEATH_TEST_CHECK_( ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, 0) // Default buffer size. != FALSE); set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), O_RDONLY)); write_handle_.Reset(write_handle); event_handle_.Reset(::CreateEvent( &handles_are_inheritable, TRUE, // The event will automatically reset to non-signaled state. FALSE, // The initial state is non-signalled. NULL)); // The even is unnamed. GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(static_cast(::GetCurrentProcessId())) + // size_t has the same width as pointers on both 32-bit and 64-bit // Windows platforms. // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. "|" + StreamableToString(reinterpret_cast(write_handle)) + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); char executable_path[_MAX_PATH + 1]; // NOLINT GTEST_DEATH_TEST_CHECK_( _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, executable_path, _MAX_PATH)); std::string command_line = std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + internal_flag + "\""; DeathTest::set_last_death_test_message(""); CaptureStderr(); // Flush the log buffers since the log streams are shared with the child. FlushInfoLog(); // The child process will share the standard handles with the parent. STARTUPINFOA startup_info; memset(&startup_info, 0, sizeof(STARTUPINFO)); startup_info.dwFlags = STARTF_USESTDHANDLES; startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); PROCESS_INFORMATION process_info; GTEST_DEATH_TEST_CHECK_(::CreateProcessA( executable_path, const_cast(command_line.c_str()), NULL, // Retuned process handle is not inheritable. NULL, // Retuned thread handle is not inheritable. TRUE, // Child inherits all inheritable handles (for write_handle_). 0x0, // Default creation flags. NULL, // Inherit the parent's environment. UnitTest::GetInstance()->original_working_dir(), &startup_info, &process_info) != FALSE); child_handle_.Reset(process_info.hProcess); ::CloseHandle(process_info.hThread); set_spawned(true); return OVERSEE_TEST; } # else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. class ForkingDeathTest : public DeathTestImpl { public: ForkingDeathTest(const char* statement, const RE* regex); // All of these virtual functions are inherited from DeathTest. virtual int Wait(); protected: void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } private: // PID of child process during death test; 0 in the child process itself. pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) : DeathTestImpl(a_statement, a_regex), child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. int ForkingDeathTest::Wait() { if (!spawned()) return 0; ReadAndInterpretStatusByte(); int status_value; GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); set_status(status_value); return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. class NoExecDeathTest : public ForkingDeathTest { public: NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) { } virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. DeathTest::TestRole NoExecDeathTest::AssumeRole() { const size_t thread_count = GetThreadCount(); if (thread_count != 1) { GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); DeathTest::set_last_death_test_message(""); CaptureStderr(); // When we fork the process below, the log file buffers are copied, but the // file descriptors are shared. We flush all log files here so that closing // the file descriptors in the child process doesn't throw off the // synchronization between descriptors and buffers in the parent process. // This is as close to the fork as possible to avoid a race condition in case // there are multiple threads running before the death test, and another // thread writes to the log file. FlushInfoLog(); const pid_t child_pid = fork(); GTEST_DEATH_TEST_CHECK_(child_pid != -1); set_child_pid(child_pid); if (child_pid == 0) { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); set_write_fd(pipe_fd[1]); // Redirects all logging to stderr in the child process to prevent // concurrent writes to the log files. We capture stderr in the parent // process and append the child process' output to a log. LogToStderr(); // Event forwarding to the listeners of event listener API mush be shut // down in death test subprocesses. GetUnitTestImpl()->listeners()->SuppressEventForwarding(); g_in_fast_death_test_child = true; return EXECUTE_TEST; } else { GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. class ExecDeathTest : public ForkingDeathTest { public: ExecDeathTest(const char* a_statement, const RE* a_regex, const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } virtual TestRole AssumeRole(); private: static ::std::vector GetArgvsForDeathTestChildProcess() { ::std::vector args = GetInjectableArgvs(); return args; } // The name of the file in which the death test is located. const char* const file_; // The line number on which the death test is located. const int line_; }; // Utility class for accumulating command-line arguments. class Arguments { public: Arguments() { args_.push_back(NULL); } ~Arguments() { for (std::vector::iterator i = args_.begin(); i != args_.end(); ++i) { free(*i); } } void AddArgument(const char* argument) { args_.insert(args_.end() - 1, posix::StrDup(argument)); } template void AddArguments(const ::std::vector& arguments) { for (typename ::std::vector::const_iterator i = arguments.begin(); i != arguments.end(); ++i) { args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); } } char* const* Argv() { return &args_[0]; } private: std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. struct ExecDeathTestArgs { char* const* argv; // Command-line arguments for the child's call to exec int close_fd; // File descriptor to close; the read end of a pipe }; # if GTEST_OS_MAC inline char** GetEnviron() { // When Google Test is built as a framework on MacOS X, the environ variable // is unavailable. Apple's documentation (man environ) recommends using // _NSGetEnviron() instead. return *_NSGetEnviron(); } # else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } # endif // GTEST_OS_MAC # if !GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. static int ExecDeathTestChildMain(void* child_arg) { ExecDeathTestArgs* const args = static_cast(child_arg); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } // We can safely call execve() as it's a direct system call. We // cannot use execvp() as it's a libc function and thus potentially // unsafe. Since execve() doesn't search the PATH, the user must // invoke the test program via a valid path that contains at least // one path separator. execve(args->argv[0], args->argv, GetEnviron()); DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + original_dir + " failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } # endif // !GTEST_OS_QNX // Two utility routines that together determine the direction the stack // grows. // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. // // GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; void StackLowerThanAddress(const void* ptr, bool* result) { int dummy; *result = (&dummy < ptr); } // Make sure AddressSanitizer does not tamper with the stack here. GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ bool StackGrowsDown() { int dummy; bool result; StackLowerThanAddress(&dummy, &result); return result; } // Spawns a child process with the same executable as the current process in // a thread-safe manner and instructs it to run the death test. The // implementation uses fork(2) + exec. On systems where clone(2) is // available, it is used instead, being slightly more thread-safe. On QNX, // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; # if GTEST_OS_QNX // Obtains the current directory and sets it to be closed in the child // process. const int cwd_fd = open(".", O_RDONLY); GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); // We need to execute the test program in the same environment where // it was originally invoked. Therefore we change to the original // working directory first. const char* const original_dir = UnitTest::GetInstance()->original_working_dir(); // We can safely call chdir() as it's a direct system call. if (chdir(original_dir) != 0) { DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + GetLastErrnoDescription()); return EXIT_FAILURE; } int fd_flags; // Set close_fd to be closed after spawn. GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, fd_flags | FD_CLOEXEC)); struct inheritance inherit = {0}; // spawn is a system call. child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); // Restores the current working directory. GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); # else // GTEST_OS_QNX # if GTEST_OS_LINUX // When a SIGPROF signal is received while fork() or clone() are executing, // the process may hang. To avoid this, we ignore SIGPROF here and re-enable // it after the call to fork()/clone() is complete. struct sigaction saved_sigprof_action; struct sigaction ignore_sigprof_action; memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); sigemptyset(&ignore_sigprof_action.sa_mask); ignore_sigprof_action.sa_handler = SIG_IGN; GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); # endif // GTEST_OS_LINUX # if GTEST_HAS_CLONE const bool use_fork = GTEST_FLAG(death_test_use_fork); if (!use_fork) { static const bool stack_grows_down = StackGrowsDown(); const size_t stack_size = getpagesize(); // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); // Maximum stack alignment in bytes: For a downward-growing stack, this // amount is subtracted from size of the stack space to get an address // that is within the stack space and is aligned on all systems we care // about. As far as I know there is no ABI with stack alignment greater // than 64. We assume stack and stack_size already have alignment of // kMaxStackAlignment. const size_t kMaxStackAlignment = 64; void* const stack_top = static_cast(stack) + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && reinterpret_cast(stack_top) % kMaxStackAlignment == 0); child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } # else const bool use_fork = true; # endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { ExecDeathTestChildMain(&args); _exit(0); } # endif // GTEST_OS_QNX # if GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_SYSCALL_( sigaction(SIGPROF, &saved_sigprof_action, NULL)); # endif // GTEST_OS_LINUX GTEST_DEATH_TEST_CHECK_(child_pid != -1); return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. DeathTest::TestRole ExecDeathTest::AssumeRole() { const UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const TestInfo* const info = impl->current_test_info(); const int death_test_index = info->result()->death_test_count(); if (flag != NULL) { set_write_fd(flag->write_fd()); return EXECUTE_TEST; } int pipe_fd[2]; GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); // Clear the close-on-exec flag on the write end of the pipe, lest // it be closed when the child process does an exec: GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); const std::string internal_flag = std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); Arguments args; args.AddArguments(GetArgvsForDeathTestChildProcess()); args.AddArgument(filter_flag.c_str()); args.AddArgument(internal_flag.c_str()); DeathTest::set_last_death_test_message(""); CaptureStderr(); // See the comment in NoExecDeathTest::AssumeRole for why the next line // is necessary. FlushInfoLog(); const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); set_child_pid(child_pid); set_read_fd(pipe_fd[0]); set_spawned(true); return OVERSEE_TEST; } # endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to // by the "test" argument to its address. If the test should be // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) { UnitTestImpl* const impl = GetUnitTestImpl(); const InternalRunDeathTestFlag* const flag = impl->internal_run_death_test_flag(); const int death_test_index = impl->current_test_info() ->increment_death_test_count(); if (flag != NULL) { if (death_test_index > flag->index()) { DeathTest::set_last_death_test_message( "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); return false; } if (!(flag->file() == file && flag->line() == line && flag->index() == death_test_index)) { *test = NULL; return true; } } # if GTEST_OS_WINDOWS if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, regex, file, line); } # else if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } # endif // GTEST_OS_WINDOWS else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message( "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); return false; } return true; } // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. static void SplitString(const ::std::string& str, char delimiter, ::std::vector< ::std::string>* dest) { ::std::vector< ::std::string> parsed; ::std::string::size_type pos = 0; while (::testing::internal::AlwaysTrue()) { const ::std::string::size_type colon = str.find(delimiter, pos); if (colon == ::std::string::npos) { parsed.push_back(str.substr(pos)); break; } else { parsed.push_back(str.substr(pos, colon - pos)); pos = colon + 1; } } dest->swap(parsed); } # if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. int GetStatusFileDescriptor(unsigned int parent_process_id, size_t write_handle_as_size_t, size_t event_handle_as_size_t) { AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, // Non-inheritable. parent_process_id)); if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { DeathTestAbort("Unable to open parent process " + StreamableToString(parent_process_id)); } // TODO(vladl@google.com): Replace the following check with a // compile-time assertion when available. GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); const HANDLE write_handle = reinterpret_cast(write_handle_as_size_t); HANDLE dup_write_handle; // The newly initialized handle is accessible only in in the parent // process. To obtain one accessible within the child, we need to use // DuplicateHandle. if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, ::GetCurrentProcess(), &dup_write_handle, 0x0, // Requested privileges ignored since // DUPLICATE_SAME_ACCESS is used. FALSE, // Request non-inheritable handler. DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the pipe handle " + StreamableToString(write_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); HANDLE dup_event_handle; if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, ::GetCurrentProcess(), &dup_event_handle, 0x0, FALSE, DUPLICATE_SAME_ACCESS)) { DeathTestAbort("Unable to duplicate the event handle " + StreamableToString(event_handle_as_size_t) + " from the parent process " + StreamableToString(parent_process_id)); } const int write_fd = ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); if (write_fd == -1) { DeathTestAbort("Unable to convert pipe handle " + StreamableToString(write_handle_as_size_t) + " to a file descriptor"); } // Signals the parent that the write end of the pipe has been acquired // so the parent can release its own write end. ::SetEvent(dup_event_handle); return write_fd; } # endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { if (GTEST_FLAG(internal_run_death_test) == "") return NULL; // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we // can use it here. int line = -1; int index = -1; ::std::vector< ::std::string> fields; SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); int write_fd = -1; # if GTEST_OS_WINDOWS unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); # else if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) { DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); } # endif // GTEST_OS_WINDOWS return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal #endif // GTEST_HAS_DEATH_TEST } // namespace testing node-v4.2.6/deps/gtest/src/gtest-filepath.cc000644 000766 000024 00000034331 12650222322 021045 0ustar00iojsstaff000000 000000 // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: keith.ray@gmail.com (Keith Ray) #include "gtest/gtest-message.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-port.h" #include #if GTEST_OS_WINDOWS_MOBILE # include #elif GTEST_OS_WINDOWS # include # include #elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h # include #else # include # include // Some Linux distributions define PATH_MAX here. #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS # define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) # define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) # define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else # define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { #if GTEST_OS_WINDOWS // On Windows, '\\' is the standard path separator, but many tools and the // Windows API also accept '/' as an alternate path separator. Unless otherwise // noted, a file path can contain either kind of path separators, or a mixture // of them. const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kAlternatePathSeparatorString[] = "/"; # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; # else const char kCurrentDirectoryString[] = ".\\"; # endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS // Returns whether the given character is a valid path separator. static bool IsPathSeparator(char c) { #if GTEST_HAS_ALT_PATH_SEP_ return (c == kPathSeparator) || (c == kAlternatePathSeparator); #else return c == kPathSeparator; #endif } // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; char* result = getcwd(cwd, sizeof(cwd)); # if GTEST_OS_NACL // getcwd will likely fail in NaCl due to the sandbox, so return something // reasonable. The user may have provided a shim implementation for getcwd, // however, so fallback only when failure is detected. return FilePath(result == NULL ? kCurrentDirectoryString : cwd); # endif // GTEST_OS_NACL return FilePath(result == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath FilePath::RemoveExtension(const char* extension) const { const std::string dot_extension = std::string(".") + extension; if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { return FilePath(pathname_.substr( 0, pathname_.length() - dot_extension.length())); } return *this; } // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FilePath::FindLastPathSeparator() const { const char* const last_sep = strrchr(c_str(), kPathSeparator); #if GTEST_HAS_ALT_PATH_SEP_ const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); // Comparing two pointers of which only one is NULL is undefined. if (last_alt_sep != NULL && (last_sep == NULL || last_alt_sep > last_sep)) { return last_alt_sep; } #endif return last_sep; } // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveDirectoryName() const { const char* const last_sep = FindLastPathSeparator(); return last_sep ? FilePath(last_sep + 1) : *this; } // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath FilePath::RemoveFileName() const { const char* const last_sep = FindLastPathSeparator(); std::string dir; if (last_sep) { dir = std::string(c_str(), last_sep + 1 - c_str()); } else { dir = kCurrentDirectoryString; } return FilePath(dir); } // Helper functions for naming files in a directory for xml output. // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension) { std::string file; if (number == 0) { file = base_name.string() + "." + extension; } else { file = base_name.string() + "_" + StreamableToString(number) + "." + extension; } return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, const FilePath& relative_path) { if (directory.IsEmpty()) return relative_path; const FilePath dir(directory.RemoveTrailingPathSeparator()); return FilePath(dir.string() + kPathSeparator + relative_path.string()); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. bool FilePath::FileOrDirectoryExists() const { #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; return attributes != kInvalidFileAttributes; #else posix::StatStruct file_stat; return posix::Stat(pathname_.c_str(), &file_stat) == 0; #endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. bool FilePath::DirectoryExists() const { bool result = false; #if GTEST_OS_WINDOWS // Don't strip off trailing separator if path is a root directory on // Windows (like "C:\\"). const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); #else const FilePath& path(*this); #endif #if GTEST_OS_WINDOWS_MOBILE LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); const DWORD attributes = GetFileAttributes(unicode); delete [] unicode; if ((attributes != kInvalidFileAttributes) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { result = true; } #else posix::StatStruct file_stat; result = posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool FilePath::IsRootDirectory() const { #if GTEST_OS_WINDOWS // TODO(wan@google.com): on Windows a network share like // \\server\share can be a root directory, although it cannot be the // current directory. Handle this properly. return pathname_.length() == 3 && IsAbsolutePath(); #else return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } // Returns true if pathname describes an absolute path. bool FilePath::IsAbsolutePath() const { const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS return pathname_.length() >= 3 && ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z')) && name[1] == ':' && IsPathSeparator(name[2]); #else return IsPathSeparator(name[0]); #endif } // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension) { FilePath full_pathname; int number = 0; do { full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); } while (full_pathname.FileOrDirectoryExists()); return full_pathname; } // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool FilePath::IsDirectory() const { return !pathname_.empty() && IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create directories // for any reason. bool FilePath::CreateDirectoriesRecursively() const { if (!this->IsDirectory()) { return false; } if (pathname_.length() == 0 || this->DirectoryExists()) { return true; } const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); return parent.CreateDirectoriesRecursively() && this->CreateFolder(); } // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool FilePath::CreateFolder() const { #if GTEST_OS_WINDOWS_MOBILE FilePath removed_sep(this->RemoveTrailingPathSeparator()); LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); int result = CreateDirectory(unicode, NULL) ? 0 : -1; delete [] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); #else int result = mkdir(pathname_.c_str(), 0777); #endif // GTEST_OS_WINDOWS_MOBILE if (result == -1) { return this->DirectoryExists(); // An error is OK if the directory exists. } return true; // No error. } // If input name has a trailing separator character, remove it and return the // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath FilePath::RemoveTrailingPathSeparator() const { return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1)) : *this; } // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). void FilePath::Normalize() { if (pathname_.c_str() == NULL) { pathname_ = ""; return; } const char* src = pathname_.c_str(); char* const dest = new char[pathname_.length() + 1]; char* dest_ptr = dest; memset(dest_ptr, 0, pathname_.length() + 1); while (*src != '\0') { *dest_ptr = *src; if (!IsPathSeparator(*src)) { src++; } else { #if GTEST_HAS_ALT_PATH_SEP_ if (*dest_ptr == kAlternatePathSeparator) { *dest_ptr = kPathSeparator; } #endif while (IsPathSeparator(*src)) src++; } dest_ptr++; } *dest_ptr = '\0'; pathname_ = dest; delete[] dest; } } // namespace internal } // namespace testing node-v4.2.6/deps/gtest/src/gtest-internal-inl.h000644 000766 000024 00000131434 12650222322 021511 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Utility functions and classes used by the Google C++ testing framework. // // Author: wan@google.com (Zhanyong Wan) // // This file contains purely Google Test's internal implementation. Please // DO NOT #INCLUDE IT IN A USER PROGRAM. #ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ #define GTEST_SRC_GTEST_INTERNAL_INL_H_ // GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // If this file is included from the user's code, just say no. # error "gtest-internal-inl.h is part of Google Test's internal implementation." # error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE # include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. #include // For memmove. #include #include #include #include "gtest/internal/gtest-port.h" #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT #endif #if GTEST_OS_WINDOWS # include // NOLINT #endif // GTEST_OS_WINDOWS #include "gtest/gtest.h" // NOLINT #include "gtest/gtest-spi.h" namespace testing { // Declares the flags. // // We don't want the users to modify this flag in the code, but want // Google Test's own unit tests to be able to access it. Therefore we // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); namespace internal { // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; // Names of the flags (needed for parsing Google Test flags). const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; const char kPrintTimeFlag[] = "print_time"; const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. GTEST_API_ extern bool g_help_flag; // Returns the current time in milliseconds. GTEST_API_ TimeInMillis GetTimeInMillis(); // Returns true iff Google Test should use colors in the output. GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); // Formats the given time in milliseconds as seconds. GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); // Converts the given time in milliseconds to a date string in the ISO 8601 // format, without the timezone information. N.B.: due to the use the // non-reentrant localtime() function, this function is not thread safe. Do // not use it in any code that can be called from multiple threads. GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // Parses a string for an Int32 flag, in the form of "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) : static_cast(random_seed_flag); // Normalizes the actual seed to range [1, kMaxRandomSeed] such that // it's easy to type. const int normalized_seed = static_cast((raw_seed - 1U) % static_cast(kMaxRandomSeed)) + 1; return normalized_seed; } // Returns the first valid random seed after 'seed'. The behavior is // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is // considered to be 1. inline int GetNextRandomSeed(int seed) { GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) << "Invalid random seed " << seed << " - must be in [1, " << kMaxRandomSeed << "]."; const int next_seed = seed + 1; return (next_seed > kMaxRandomSeed) ? 1 : next_seed; } // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. class GTestFlagSaver { public: // The c'tor. GTestFlagSaver() { also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); break_on_failure_ = GTEST_FLAG(break_on_failure); catch_exceptions_ = GTEST_FLAG(catch_exceptions); color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); output_ = GTEST_FLAG(output); print_time_ = GTEST_FLAG(print_time); random_seed_ = GTEST_FLAG(random_seed); repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); stream_result_to_ = GTEST_FLAG(stream_result_to); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. ~GTestFlagSaver() { GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; GTEST_FLAG(break_on_failure) = break_on_failure_; GTEST_FLAG(catch_exceptions) = catch_exceptions_; GTEST_FLAG(color) = color_; GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; GTEST_FLAG(print_time) = print_time_; GTEST_FLAG(random_seed) = random_seed_; GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: // Fields for saving the original values of flags. bool also_run_disabled_tests_; bool break_on_failure_; bool catch_exceptions_; std::string color_; std::string death_test_style_; bool death_test_use_fork_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; std::string output_; bool print_time_; internal::Int32 random_seed_; internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded(); // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (e.g., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. GTEST_API_ bool ShouldShard(const char* total_shards_str, const char* shard_index_str, bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and // and aborts. GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. GTEST_API_ bool ShouldRunTestOnShard( int total_shards, int shard_index, int test_id); // STL container utilities. // Returns the number of elements in the given container that satisfy // the given predicate. template inline int CountIf(const Container& c, Predicate predicate) { // Implemented as an explicit loop since std::count_if() in libCstd on // Solaris has a non-standard signature. int count = 0; for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { if (predicate(*it)) ++count; } return count; } // Applies a function/functor to each element in the container. template void ForEach(const Container& c, Functor functor) { std::for_each(c.begin(), c.end(), functor); } // Returns the i-th element of the vector, or default_value if i is not // in range [0, v.size()). template inline E GetElementOr(const std::vector& v, int i, E default_value) { return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; } // Performs an in-place shuffle of a range of the vector's elements. // 'begin' and 'end' are element indices as an STL-style range; // i.e. [begin, end) are shuffled, where 'end' == size() means to // shuffle to the end of the vector. template void ShuffleRange(internal::Random* random, int begin, int end, std::vector* v) { const int size = static_cast(v->size()); GTEST_CHECK_(0 <= begin && begin <= size) << "Invalid shuffle range start " << begin << ": must be in range [0, " << size << "]."; GTEST_CHECK_(begin <= end && end <= size) << "Invalid shuffle range finish " << end << ": must be in range [" << begin << ", " << size << "]."; // Fisher-Yates shuffle, from // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle for (int range_width = end - begin; range_width >= 2; range_width--) { const int last_in_range = begin + range_width - 1; const int selected = begin + random->Generate(range_width); std::swap((*v)[selected], (*v)[last_in_range]); } } // Performs an in-place shuffle of the vector's elements. template inline void Shuffle(internal::Random* random, std::vector* v) { ShuffleRange(random, 0, static_cast(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template static void Delete(T* x) { delete x; } // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. class TestPropertyKeyIs { public: // Constructor. // // TestPropertyKeyIs has NO default constructor. explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} // Returns true iff the test name of test property matches on key_. bool operator()(const TestProperty& test_property) const { return test_property.key() == key_; } private: std::string key_; }; // Class UnitTestOptions. // // This class contains functions for processing options the user // specifies when running the tests. It has only static members. // // In most cases, the user can specify an option using either an // environment variable or a command line flag. E.g. you can set the // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. class GTEST_API_ UnitTestOptions { public: // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. static std::string GetOutputFormat(); // Returns the absolute path of the requested output file, or the // default (test_detail.xml in the original working directory) if // none was explicitly specified. static std::string GetAbsolutePathToOutputFile(); // Functions for processing the gtest_filter flag. // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. static bool PatternMatchesString(const char *pattern, const char *str); // Returns true iff the user-specified filter matches the test case // name and the test name. static bool FilterMatchesTest(const std::string &test_case_name, const std::string &test_name); #if GTEST_OS_WINDOWS // Function for supporting the gtest_catch_exception flag. // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. static int GTestShouldProcessSEH(DWORD exception_code); #endif // GTEST_OS_WINDOWS // Returns true if "name" matches the ':' separated list of glob-style // filters in "filter". static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { public: OsStackTraceGetterInterface() {} virtual ~OsStackTraceGetterInterface() {} // Returns the current OS stack trace as an std::string. Parameters: // // max_depth - the maximum number of stack frames to be included // in the trace. // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; // UponLeavingGTest() should be called immediately before Google Test calls // user code. It saves some information about the current stack that // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: OsStackTraceGetter() : caller_frame_(NULL) {} virtual string CurrentStackTrace(int max_depth, int skip_count) GTEST_LOCK_EXCLUDED_(mutex_); virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); // This string is inserted in place of stack frames that are part of // Google Test's implementation. static const char* const kElidedFramesMarker; private: Mutex mutex_; // protects all internal state // We save the stack frame below the frame that calls user code. // We do this because the address of the frame immediately below // the user code changes between the call to UponLeavingGTest() // and any calls to CurrentStackTrace() from within the user code. void* caller_frame_; GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. struct TraceInfo { const char* file; int line; std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. Reports the test part // result in the current test. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in // UnitTestImpl. This class should only be used by UnitTestImpl. class DefaultPerThreadTestPartResultReporter : public TestPartResultReporterInterface { public: explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); // Implements the TestPartResultReporterInterface. The implementation just // delegates to the current global test part result reporter of *unit_test_. virtual void ReportTestPartResult(const TestPartResult& result); private: UnitTestImpl* const unit_test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. class GTEST_API_ UnitTestImpl { public: explicit UnitTestImpl(UnitTest* parent); virtual ~UnitTestImpl(); // There are two different ways to register your own TestPartResultReporter. // You can register your own repoter to listen either only for test results // from the current thread or for results from all threads. // By default, each per-thread test result repoter just passes a new // TestPartResult to the global test result reporter, which registers the // test part result for the currently running test. // Returns the global test part result reporter. TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); // Sets the global test part result reporter. void SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter); // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); // Sets the test part result reporter for the current thread. void SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter); // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const { return start_timestamp_; } // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const { return !Failed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const { return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[i]; } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i) { const int index = GetElementOr(test_case_indices_, i, -1); return index < 0 ? NULL : test_cases_[index]; } // Provides access to the event listener list. TestEventListeners* listeners() { return &listeners_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* current_test_result(); // Returns the TestResult for the ad hoc test. const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter // are the same; otherwise, deletes the old getter and makes the // input the current getter. void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* os_stack_trace_getter(); // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Adds a TestInfo to the unit test. // // Arguments: // // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // test_info: the TestInfo object void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, TestInfo* test_info) { // In order to support thread-safe death tests, we need to // remember the original working directory when the test program // was first invoked. We cannot do this in RUN_ALL_TESTS(), as // the user may have changed the current directory before calling // RUN_ALL_TESTS(). Therefore we capture the current directory in // AddTestInfo(), which is called to register a TEST or TEST_F // before main() is reached. if (original_working_dir_.IsEmpty()) { original_working_dir_.Set(FilePath::GetCurrentDir()); GTEST_CHECK_(!original_working_dir_.IsEmpty()) << "Failed to get the current working directory."; } GetTestCase(test_info->test_case_name(), test_info->type_param(), set_up_tc, tear_down_tc)->AddTestInfo(test_info); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { return parameterized_test_registry_; } #endif // GTEST_HAS_PARAM_TEST // Sets the TestCase object for the test that's currently running. void set_current_test_case(TestCase* a_current_test_case) { current_test_case_ = a_current_test_case; } // Sets the TestInfo object for the test that's currently running. If // current_test_info is NULL, the assertion results will be stored in // ad_hoc_test_result_. void set_current_test_info(TestInfo* a_current_test_info) { current_test_info_ = a_current_test_info; } // Registers all parameterized tests defined using TEST_P and // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter // combination. This method can be called more then once; it has guards // protecting from registering the tests more then once. If // value-parameterized tests are disabled, RegisterParameterizedTests is // present but does nothing. void RegisterParameterizedTests(); // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, this test is considered to be failed, but // the rest of the tests will still be run. bool RunAllTests(); // Clears the results of all tests, except the ad hoc tests. void ClearNonAdHocTestResult() { ForEach(test_cases_, TestCase::ClearTestCaseResult); } // Clears the results of ad-hoc test assertions. void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test or a test case, or to the global property set. If the // result already contains a property with the same key, the value will be // updated. void RecordProperty(const TestProperty& test_property); enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL }; // Matches the full name of each test against the user-specified // filter to decide whether the test should run, then records the // result in each TestCase and TestInfo object. // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests // based on sharding variables in the environment. // Returns the number of tests that should run. int FilterTests(ReactionToSharding shard_tests); // Prints the names of the tests matching the user-specified filter flag. void ListTestsMatchingFilter(); const TestCase* current_test_case() const { return current_test_case_; } TestInfo* current_test_info() { return current_test_info_; } const TestInfo* current_test_info() const { return current_test_info_; } // Returns the vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector& environments() { return environments_; } // Getters for the per-thread Google Test trace stack. std::vector& gtest_trace_stack() { return *(gtest_trace_stack_.pointer()); } const std::vector& gtest_trace_stack() const { return gtest_trace_stack_.get(); } #if GTEST_HAS_DEATH_TEST void InitDeathTestSubprocessControlInfo() { internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); } // Returns a pointer to the parsed --gtest_internal_run_death_test // flag, or NULL if that flag was not specified. // This information is useful only in a death test child process. // Must not be called before a call to InitGoogleTest. const InternalRunDeathTestFlag* internal_run_death_test_flag() const { return internal_run_death_test_flag_.get(); } // Returns a pointer to the current death test factory. internal::DeathTestFactory* death_test_factory() { return death_test_factory_.get(); } void SuppressTestEventsIfInSubprocess(); friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST // Initializes the event listener performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Initializes the event listener for streaming test results to a socket. // Must not be called before InitGoogleTest. void ConfigureStreamingOutput(); #endif // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void PostFlagParsingInit(); // Gets the random seed used at the start of the current test iteration. int random_seed() const { return random_seed_; } // Gets the random number generator. internal::Random* random() { return &random_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void ShuffleTests(); // Restores the test cases and tests to their order before the first shuffle. void UnshuffleTests(); // Returns the value of GTEST_FLAG(catch_exceptions) at the moment // UnitTest::Run() starts. bool catch_exceptions() const { return catch_exceptions_; } private: friend class ::testing::UnitTest; // Used by UnitTest::Run() to capture the state of // GTEST_FLAG(catch_exceptions) at the moment it starts. void set_catch_exceptions(bool value) { catch_exceptions_ = value; } // The UnitTest object that owns this implementation object. UnitTest* const parent_; // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; DefaultPerThreadTestPartResultReporter default_per_thread_test_part_result_reporter_; // Points to (but doesn't own) the global test part result reporter. TestPartResultReporterInterface* global_test_part_result_repoter_; // Protects read and write access to global_test_part_result_reporter_. internal::Mutex global_test_part_result_reporter_mutex_; // Points to (but doesn't own) the per-thread test part result reporter. internal::ThreadLocal per_thread_test_part_result_reporter_; // The vector of environments that need to be set-up/torn-down // before/after the tests are run. std::vector environments_; // The vector of TestCases in their original order. It owns the // elements in the vector. std::vector test_cases_; // Provides a level of indirection for the test case list to allow // easy shuffling and restoring the test case order. The i-th // element of this vector is the index of the i-th test case in the // shuffled order. std::vector test_case_indices_; #if GTEST_HAS_PARAM_TEST // ParameterizedTestRegistry object used to register value-parameterized // tests. internal::ParameterizedTestCaseRegistry parameterized_test_registry_; // Indicates whether RegisterParameterizedTests() has been called already. bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST // Index of the last death test case registered. Initially -1. int last_death_test_case_; // This points to the TestCase for the currently running test. It // changes as Google Test goes through one test case after another. // When no test is running, this is set to NULL and Google Test // stores assertion results in ad_hoc_test_result_. Initially NULL. TestCase* current_test_case_; // This points to the TestInfo for the currently running test. It // changes as Google Test goes through one test after another. When // no test is running, this is set to NULL and Google Test stores // assertion results in ad_hoc_test_result_. Initially NULL. TestInfo* current_test_info_; // Normally, a user only writes assertions inside a TEST or TEST_F, // or inside a function called by a TEST or TEST_F. Since Google // Test keeps track of which test is current running, it can // associate such an assertion with the test it belongs to. // // If an assertion is encountered when no TEST or TEST_F is running, // Google Test attributes the assertion result to an imaginary "ad hoc" // test, and records the result in ad_hoc_test_result_. TestResult ad_hoc_test_result_; // The list of event listeners that can be used to track events inside // Google Test. TestEventListeners listeners_; // The OS stack trace getter. Will be deleted when the UnitTest // object is destructed. By default, an OsStackTraceGetter is used, // but the user can set this field to use a custom getter if that is // desired. OsStackTraceGetterInterface* os_stack_trace_getter_; // True iff PostFlagParsingInit() has been called. bool post_flag_parse_init_performed_; // The random number seed used at the beginning of the test run. int random_seed_; // Our random number generator. internal::Random random_; // The time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp_; // How long the test took to run, in milliseconds. TimeInMillis elapsed_time_; #if GTEST_HAS_DEATH_TEST // The decomposed components of the gtest_internal_run_death_test flag, // parsed when RUN_ALL_TESTS is called. internal::scoped_ptr internal_run_death_test_flag_; internal::scoped_ptr death_test_factory_; #endif // GTEST_HAS_DEATH_TEST // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal > gtest_trace_stack_; // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() // starts. bool catch_exceptions_; GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest // implementation object. inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } #if GTEST_USES_SIMPLE_RE // Internal helper functions for implementing the simple regular // expression matcher. GTEST_API_ bool IsInSet(char ch, const char* str); GTEST_API_ bool IsAsciiDigit(char ch); GTEST_API_ bool IsAsciiPunct(char ch); GTEST_API_ bool IsRepeat(char ch); GTEST_API_ bool IsAsciiWhiteSpace(char ch); GTEST_API_ bool IsAsciiWordChar(char ch); GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE // Parses the command line for Google Test flags, without initializing // other parts of Google Test. GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); #if GTEST_HAS_DEATH_TEST // Returns the message describing the last system error, regardless of the // platform. GTEST_API_ std::string GetLastErrnoDescription(); // Attempts to parse a string into a positive integer pointed to by the // number parameter. Returns true if that is possible. // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use // it here. template bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // Fail fast if the given string does not begin with a digit; // this bypasses strtoXXX's "optional leading whitespace and plus // or minus sign" semantics, which are undesirable here. if (str.empty() || !IsDigit(str[0])) { return false; } errno = 0; char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. # if GTEST_OS_WINDOWS && !defined(__GNUC__) // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); # else typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); # endif // GTEST_OS_WINDOWS && !defined(__GNUC__) const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is // available. GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); const Integer result = static_cast(parsed); if (parse_success && static_cast(result) == parsed) { *number = result; return true; } return false; } #endif // GTEST_HAS_DEATH_TEST // TestResult contains some private methods that should be hidden from // Google Test user but are required for testing. This class allow our tests // to access them. // // This class is supplied only for the purpose of testing Google Test's own // constructs. Do not use it in user tests, either directly or indirectly. class TestResultAccessor { public: static void RecordProperty(TestResult* test_result, const std::string& xml_element, const TestProperty& property) { test_result->RecordProperty(xml_element, property); } static void ClearTestPartResults(TestResult* test_result) { test_result->ClearTestPartResults(); } static const std::vector& test_part_results( const TestResult& test_result) { return test_result.test_part_results(); } }; #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. class StreamingListener : public EmptyTestEventListener { public: // Abstract base class for writing strings to a socket. class AbstractSocketWriter { public: virtual ~AbstractSocketWriter() {} // Sends a string to the socket. virtual void Send(const string& message) = 0; // Closes the socket. virtual void CloseConnection() {} // Sends a string and a newline to the socket. void SendLn(const string& message) { Send(message + "\n"); } }; // Concrete class for actually writing strings to a socket. class SocketWriter : public AbstractSocketWriter { public: SocketWriter(const string& host, const string& port) : sockfd_(-1), host_name_(host), port_num_(port) { MakeConnection(); } virtual ~SocketWriter() { if (sockfd_ != -1) CloseConnection(); } // Sends a string to the socket. virtual void Send(const string& message) { GTEST_CHECK_(sockfd_ != -1) << "Send() can be called only when there is a connection."; const int len = static_cast(message.length()); if (write(sockfd_, message.c_str(), len) != len) { GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to " << host_name_ << ":" << port_num_; } } private: // Creates a client socket and connects to the server. void MakeConnection(); // Closes the socket. void CloseConnection() { GTEST_CHECK_(sockfd_ != -1) << "CloseConnection() can be called only when there is a connection."; close(sockfd_); sockfd_ = -1; } int sockfd_; // socket file descriptor const string host_name_; const string port_num_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); }; // class SocketWriter // Escapes '=', '&', '%', and '\n' characters in str as "%xx". static string UrlEncode(const char* str); StreamingListener(const string& host, const string& port) : socket_writer_(new SocketWriter(host, port)) { Start(); } explicit StreamingListener(AbstractSocketWriter* socket_writer) : socket_writer_(socket_writer) { Start(); } void OnTestProgramStart(const UnitTest& /* unit_test */) { SendLn("event=TestProgramStart"); } void OnTestProgramEnd(const UnitTest& unit_test) { // Note that Google Test current only report elapsed time for each // test iteration, not for the entire test program. SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); // Notify the streaming server to stop. socket_writer_->CloseConnection(); } void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration)); } void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) + "&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) + "ms"); } void OnTestCaseStart(const TestCase& test_case) { SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); } void OnTestCaseEnd(const TestCase& test_case) { SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"); } void OnTestStart(const TestInfo& test_info) { SendLn(std::string("event=TestStart&name=") + test_info.name()); } void OnTestEnd(const TestInfo& test_info) { SendLn("event=TestEnd&passed=" + FormatBool((test_info.result())->Passed()) + "&elapsed_time=" + StreamableToString((test_info.result())->elapsed_time()) + "ms"); } void OnTestPartResult(const TestPartResult& test_part_result) { const char* file_name = test_part_result.file_name(); if (file_name == NULL) file_name = ""; SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + "&line=" + StreamableToString(test_part_result.line_number()) + "&message=" + UrlEncode(test_part_result.message())); } private: // Sends the given message and a newline to the socket. void SendLn(const string& message) { socket_writer_->SendLn(message); } // Called at the start of streaming to notify the receiver what // protocol we are using. void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } string FormatBool(bool value) { return value ? "1" : "0"; } const scoped_ptr socket_writer_; GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ } // namespace internal } // namespace testing #endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ node-v4.2.6/deps/gtest/src/gtest-port.cc000644 000766 000024 00000120254 12650222322 020235 0ustar00iojsstaff000000 000000 // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/internal/gtest-port.h" #include #include #include #include #if GTEST_OS_WINDOWS # include # include # include # include // Used in ThreadLocal. #else # include #endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC # include # include # include #endif // GTEST_OS_MAC #if GTEST_OS_QNX # include # include # include #endif // GTEST_OS_QNX #include "gtest/gtest-spi.h" #include "gtest/gtest-message.h" #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick exists to // prevent the accidental inclusion of gtest-internal-inl.h in the // user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { namespace internal { #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; const int kStdErrFileno = 2; #else const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER #if GTEST_OS_MAC // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const task_t task = mach_task_self(); mach_msg_type_number_t thread_count; thread_act_array_t thread_list; const kern_return_t status = task_threads(task, &thread_list, &thread_count); if (status == KERN_SUCCESS) { // task_threads allocates resources in thread_list and we need to free them // to avoid leaks. vm_deallocate(task, reinterpret_cast(thread_list), sizeof(thread_t) * thread_count); return static_cast(thread_count); } else { return 0; } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. size_t GetThreadCount() { const int fd = open("/proc/self/as", O_RDONLY); if (fd < 0) { return 0; } procfs_info process_info; const int status = devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); close(fd); if (status == EOK) { return static_cast(process_info.num_threads); } else { return 0; } } #else size_t GetThreadCount() { // There's no portable way to detect the number of threads, so we just // return 0 to indicate that we cannot detect it. return 0; } #endif // GTEST_OS_MAC #if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS void SleepMilliseconds(int n) { ::Sleep(n); } AutoHandle::AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} AutoHandle::AutoHandle(Handle handle) : handle_(handle) {} AutoHandle::~AutoHandle() { Reset(); } AutoHandle::Handle AutoHandle::Get() const { return handle_; } void AutoHandle::Reset() { Reset(INVALID_HANDLE_VALUE); } void AutoHandle::Reset(HANDLE handle) { // Resetting with the same handle we already own is invalid. if (handle_ != handle) { if (IsCloseable()) { ::CloseHandle(handle_); } handle_ = handle; } else { GTEST_CHECK_(!IsCloseable()) << "Resetting a valid handle to itself is likely a programmer error " "and thus not allowed."; } } bool AutoHandle::IsCloseable() const { // Different Windows APIs may use either of these values to represent an // invalid handle. return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; } Notification::Notification() : event_(::CreateEvent(NULL, // Default security attributes. TRUE, // Do not reset automatically. FALSE, // Initially unset. NULL)) { // Anonymous event. GTEST_CHECK_(event_.Get() != NULL); } void Notification::Notify() { GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); } void Notification::WaitForNotification() { GTEST_CHECK_( ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); } Mutex::Mutex() : type_(kDynamic), owner_thread_id_(0), critical_section_init_phase_(0), critical_section_(new CRITICAL_SECTION) { ::InitializeCriticalSection(critical_section_); } Mutex::~Mutex() { // Static mutexes are leaked intentionally. It is not thread-safe to try // to clean them up. // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires // nothing to clean it up but is available only on Vista and later. // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx if (type_ == kDynamic) { ::DeleteCriticalSection(critical_section_); delete critical_section_; critical_section_ = NULL; } } void Mutex::Lock() { ThreadSafeLazyInit(); ::EnterCriticalSection(critical_section_); owner_thread_id_ = ::GetCurrentThreadId(); } void Mutex::Unlock() { ThreadSafeLazyInit(); // We don't protect writing to owner_thread_id_ here, as it's the // caller's responsibility to ensure that the current thread holds the // mutex when this is called. owner_thread_id_ = 0; ::LeaveCriticalSection(critical_section_); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void Mutex::AssertHeld() { ThreadSafeLazyInit(); GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) << "The current thread is not holding the mutex @" << this; } // Initializes owner_thread_id_ and critical_section_ in static mutexes. void Mutex::ThreadSafeLazyInit() { // Dynamic mutexes are initialized in the constructor. if (type_ == kStatic) { switch ( ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { case 0: // If critical_section_init_phase_ was 0 before the exchange, we // are the first to test it and need to perform the initialization. owner_thread_id_ = 0; critical_section_ = new CRITICAL_SECTION; ::InitializeCriticalSection(critical_section_); // Updates the critical_section_init_phase_ to 2 to signal // initialization complete. GTEST_CHECK_(::InterlockedCompareExchange( &critical_section_init_phase_, 2L, 1L) == 1L); break; case 1: // Somebody else is already initializing the mutex; spin until they // are done. while (::InterlockedCompareExchange(&critical_section_init_phase_, 2L, 2L) != 2L) { // Possibly yields the rest of the thread's time slice to other // threads. ::Sleep(0); } break; case 2: break; // The mutex is already initialized and ready for use. default: GTEST_CHECK_(false) << "Unexpected value of critical_section_init_phase_ " << "while initializing a static mutex."; } } } namespace { class ThreadWithParamSupport : public ThreadWithParamBase { public: static HANDLE CreateThread(Runnable* runnable, Notification* thread_can_start) { ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); DWORD thread_id; // TODO(yukawa): Consider to use _beginthreadex instead. HANDLE thread_handle = ::CreateThread( NULL, // Default security. 0, // Default stack size. &ThreadWithParamSupport::ThreadMain, param, // Parameter to ThreadMainStatic 0x0, // Default creation flags. &thread_id); // Need a valid pointer for the call to work under Win98. GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " << ::GetLastError() << "."; if (thread_handle == NULL) { delete param; } return thread_handle; } private: struct ThreadMainParam { ThreadMainParam(Runnable* runnable, Notification* thread_can_start) : runnable_(runnable), thread_can_start_(thread_can_start) { } scoped_ptr runnable_; // Does not own. Notification* thread_can_start_; }; static DWORD WINAPI ThreadMain(void* ptr) { // Transfers ownership. scoped_ptr param(static_cast(ptr)); if (param->thread_can_start_ != NULL) param->thread_can_start_->WaitForNotification(); param->runnable_->Run(); return 0; } // Prohibit instantiation. ThreadWithParamSupport(); GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); }; } // namespace ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start) : thread_(ThreadWithParamSupport::CreateThread(runnable, thread_can_start)) { } ThreadWithParamBase::~ThreadWithParamBase() { Join(); } void ThreadWithParamBase::Join() { GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) << "Failed to join the thread with error " << ::GetLastError() << "."; } // Maps a thread to a set of ThreadIdToThreadLocals that have values // instantiated on that thread and notifies them when the thread exits. A // ThreadLocal instance is expected to persist until all threads it has // values on have terminated. class ThreadLocalRegistryImpl { public: // Registers thread_local_instance as having value on the current thread. // Returns a value that can be used to identify the thread from other threads. static ThreadLocalValueHolderBase* GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance) { DWORD current_thread = ::GetCurrentThreadId(); MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = thread_to_thread_locals->find(current_thread); if (thread_local_pos == thread_to_thread_locals->end()) { thread_local_pos = thread_to_thread_locals->insert( std::make_pair(current_thread, ThreadLocalValues())).first; StartWatcherThreadFor(current_thread); } ThreadLocalValues& thread_local_values = thread_local_pos->second; ThreadLocalValues::iterator value_pos = thread_local_values.find(thread_local_instance); if (value_pos == thread_local_values.end()) { value_pos = thread_local_values .insert(std::make_pair( thread_local_instance, linked_ptr( thread_local_instance->NewValueForCurrentThread()))) .first; } return value_pos->second.get(); } static void OnThreadLocalDestroyed( const ThreadLocalBase* thread_local_instance) { std::vector > value_holders; // Clean up the ThreadLocalValues data structure while holding the lock, but // defer the destruction of the ThreadLocalValueHolderBases. { MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); for (ThreadIdToThreadLocals::iterator it = thread_to_thread_locals->begin(); it != thread_to_thread_locals->end(); ++it) { ThreadLocalValues& thread_local_values = it->second; ThreadLocalValues::iterator value_pos = thread_local_values.find(thread_local_instance); if (value_pos != thread_local_values.end()) { value_holders.push_back(value_pos->second); thread_local_values.erase(value_pos); // This 'if' can only be successful at most once, so theoretically we // could break out of the loop here, but we don't bother doing so. } } } // Outside the lock, let the destructor for 'value_holders' deallocate the // ThreadLocalValueHolderBases. } static void OnThreadExit(DWORD thread_id) { GTEST_CHECK_(thread_id != 0) << ::GetLastError(); std::vector > value_holders; // Clean up the ThreadIdToThreadLocals data structure while holding the // lock, but defer the destruction of the ThreadLocalValueHolderBases. { MutexLock lock(&mutex_); ThreadIdToThreadLocals* const thread_to_thread_locals = GetThreadLocalsMapLocked(); ThreadIdToThreadLocals::iterator thread_local_pos = thread_to_thread_locals->find(thread_id); if (thread_local_pos != thread_to_thread_locals->end()) { ThreadLocalValues& thread_local_values = thread_local_pos->second; for (ThreadLocalValues::iterator value_pos = thread_local_values.begin(); value_pos != thread_local_values.end(); ++value_pos) { value_holders.push_back(value_pos->second); } thread_to_thread_locals->erase(thread_local_pos); } } // Outside the lock, let the destructor for 'value_holders' deallocate the // ThreadLocalValueHolderBases. } private: // In a particular thread, maps a ThreadLocal object to its value. typedef std::map > ThreadLocalValues; // Stores all ThreadIdToThreadLocals having values in a thread, indexed by // thread's ID. typedef std::map ThreadIdToThreadLocals; // Holds the thread id and thread handle that we pass from // StartWatcherThreadFor to WatcherThreadFunc. typedef std::pair ThreadIdAndHandle; static void StartWatcherThreadFor(DWORD thread_id) { // The returned handle will be kept in thread_map and closed by // watcher_thread in WatcherThreadFunc. HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE, thread_id); GTEST_CHECK_(thread != NULL); // We need to to pass a valid thread ID pointer into CreateThread for it // to work correctly under Win98. DWORD watcher_thread_id; HANDLE watcher_thread = ::CreateThread( NULL, // Default security. 0, // Default stack size &ThreadLocalRegistryImpl::WatcherThreadFunc, reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), CREATE_SUSPENDED, &watcher_thread_id); GTEST_CHECK_(watcher_thread != NULL); // Give the watcher thread the same priority as ours to avoid being // blocked by it. ::SetThreadPriority(watcher_thread, ::GetThreadPriority(::GetCurrentThread())); ::ResumeThread(watcher_thread); ::CloseHandle(watcher_thread); } // Monitors exit from a given thread and notifies those // ThreadIdToThreadLocals about thread termination. static DWORD WINAPI WatcherThreadFunc(LPVOID param) { const ThreadIdAndHandle* tah = reinterpret_cast(param); GTEST_CHECK_( ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); OnThreadExit(tah->first); ::CloseHandle(tah->second); delete tah; return 0; } // Returns map of thread local instances. static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { mutex_.AssertHeld(); static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; return map; } // Protects access to GetThreadLocalsMapLocked() and its return value. static Mutex mutex_; // Protects access to GetThreadMapLocked() and its return value. static Mutex thread_map_mutex_; }; Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance) { return ThreadLocalRegistryImpl::GetValueOnCurrentThread( thread_local_instance); } void ThreadLocalRegistry::OnThreadLocalDestroyed( const ThreadLocalBase* thread_local_instance) { ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); } #endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_USES_POSIX_RE // Implements RE. Currently only needed for death tests. RE::~RE() { if (is_valid_) { // regfree'ing an invalid regex might crash because the content // of the regex is undefined. Since the regex's are essentially // the same, one cannot be valid (or invalid) without the other // being so too. regfree(&partial_regex_); regfree(&full_regex_); } free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { if (!re.is_valid_) return false; regmatch_t match; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = posix::StrDup(regex); // Reserves enough bytes to hold the regular expression used for a // full match. const size_t full_regex_len = strlen(regex) + 10; char* const full_pattern = new char[full_regex_len]; snprintf(full_pattern, full_regex_len, "^(%s)$", regex); is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; // We want to call regcomp(&partial_regex_, ...) even if the // previous expression returns false. Otherwise partial_regex_ may // not be properly initialized can may cause trouble when it's // freed. // // Some implementation of POSIX regex (e.g. on at least some // versions of Cygwin) doesn't accept the empty string as a valid // regex. We change it to an equivalent form "()" to be safe. if (is_valid_) { const char* const partial_regex = (*regex == '\0') ? "()" : regex; is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; } EXPECT_TRUE(is_valid_) << "Regular expression \"" << regex << "\" is not a valid POSIX Extended regular expression."; delete[] full_pattern; } #elif GTEST_USES_SIMPLE_RE // Returns true iff ch appears anywhere in str (excluding the // terminating '\0' character). bool IsInSet(char ch, const char* str) { return ch != '\0' && strchr(str, ch) != NULL; } // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. bool IsValidEscape(char c) { return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) // matches ch. The result is undefined if the atom is invalid. bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { case 'd': return IsAsciiDigit(ch); case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; case 's': return IsAsciiWhiteSpace(ch); case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; case 'w': return IsAsciiWordChar(ch); case 'W': return !IsAsciiWordChar(ch); } return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. std::string FormatRegexSyntaxError(const char* regex, int index) { return (Message() << "Syntax error at index " << index << " in simple regular expression \"" << regex << "\": ").GetString(); } // Generates non-fatal failures and returns false if regex is invalid; // otherwise returns true. bool ValidateRegex(const char* regex) { if (regex == NULL) { // TODO(wan@google.com): fix the source file location in the // assertion failures to match where the regex is used in user // code. ADD_FAILURE() << "NULL is not a valid simple regular expression."; return false; } bool is_valid = true; // True iff ?, *, or + can follow the previous atom. bool prev_repeatable = false; for (int i = 0; regex[i]; i++) { if (regex[i] == '\\') { // An escape sequence i++; if (regex[i] == '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "'\\' cannot appear at the end."; return false; } if (!IsValidEscape(regex[i])) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) << "invalid escape sequence \"\\" << regex[i] << "\"."; is_valid = false; } prev_repeatable = true; } else { // Not an escape sequence. const char ch = regex[i]; if (ch == '^' && i > 0) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'^' can only appear at the beginning."; is_valid = false; } else if (ch == '$' && regex[i + 1] != '\0') { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'$' can only appear at the end."; is_valid = false; } else if (IsInSet(ch, "()[]{}|")) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' is unsupported."; is_valid = false; } else if (IsRepeat(ch) && !prev_repeatable) { ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch << "' can only follow a repeatable token."; is_valid = false; } prev_repeatable = !IsInSet(ch, "^$?*+"); } } return is_valid; } // Matches a repeated regex atom followed by a valid simple regular // expression. The regex atom is defined as c if escaped is false, // or \c otherwise. repeat is the repetition meta character (?, *, // or +). The behavior is undefined if str contains too many // characters to be indexable by size_t, in which case the test will // probably time out anyway. We are fine with this limitation as // std::string has it too. bool MatchRepetitionAndRegexAtHead( bool escaped, char c, char repeat, const char* regex, const char* str) { const size_t min_count = (repeat == '+') ? 1 : 0; const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; // We cannot call numeric_limits::max() as it conflicts with the // max() macro on Windows. for (size_t i = 0; i <= max_count; ++i) { // We know that the atom matches each of the first i characters in str. if (i >= min_count && MatchRegexAtHead(regex, str + i)) { // We have enough matches at the head, and the tail matches too. // Since we only care about *whether* the pattern matches str // (as opposed to *how* it matches), there is no need to find a // greedy match. return true; } if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false; } return false; } // Returns true iff regex matches a prefix of str. regex must be a // valid simple regular expression and not start with "^", or the // result is undefined. bool MatchRegexAtHead(const char* regex, const char* str) { if (*regex == '\0') // An empty regex matches a prefix of anything. return true; // "$" only matches the end of a string. Note that regex being // valid guarantees that there's nothing after "$" in it. if (*regex == '$') return *str == '\0'; // Is the first thing in regex an escape sequence? const bool escaped = *regex == '\\'; if (escaped) ++regex; if (IsRepeat(regex[1])) { // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so // here's an indirect recursion. It terminates as the regex gets // shorter in each recursion. return MatchRepetitionAndRegexAtHead( escaped, regex[0], regex[1], regex + 2, str); } else { // regex isn't empty, isn't "$", and doesn't start with a // repetition. We match the first atom of regex with the first // character of str and recurse. return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && MatchRegexAtHead(regex + 1, str + 1); } } // Returns true iff regex matches any substring of str. regex must be // a valid simple regular expression, or the result is undefined. // // The algorithm is recursive, but the recursion depth doesn't exceed // the regex length, so we won't need to worry about running out of // stack space normally. In rare cases the time complexity can be // exponential with respect to the regex length + the string length, // but usually it's must faster (often close to linear). bool MatchRegexAnywhere(const char* regex, const char* str) { if (regex == NULL || str == NULL) return false; if (*regex == '^') return MatchRegexAtHead(regex + 1, str); // A successful match can be anywhere in str. do { if (MatchRegexAtHead(regex, str)) return true; } while (*str++ != '\0'); return false; } // Implements the RE class. RE::~RE() { free(const_cast(pattern_)); free(const_cast(full_pattern_)); } // Returns true iff regular expression re matches the entire str. bool RE::FullMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); } // Returns true iff regular expression re matches a substring of str // (including str itself). bool RE::PartialMatch(const char* str, const RE& re) { return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); } // Initializes an RE from its string representation. void RE::Init(const char* regex) { pattern_ = full_pattern_ = NULL; if (regex != NULL) { pattern_ = posix::StrDup(regex); } is_valid_ = ValidateRegex(regex); if (!is_valid_) { // No need to calculate the full pattern when the regex is invalid. return; } const size_t len = strlen(regex); // Reserves enough bytes to hold the regular expression used for a // full match: we need space to prepend a '^', append a '$', and // terminate the string with '\0'. char* buffer = static_cast(malloc(len + 3)); full_pattern_ = buffer; if (*regex != '^') *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. // We don't use snprintf or strncpy, as they trigger a warning when // compiled with VC++ 8.0. memcpy(buffer, regex, len); buffer += len; if (len == 0 || regex[len - 1] != '$') *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. *buffer = '\0'; } #endif // GTEST_USES_POSIX_RE const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) { return file_name + ":"; } #ifdef _MSC_VER return file_name + "(" + StreamableToString(line) + "):"; #else return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( const char* file, int line) { const std::string file_name(file == NULL ? kUnknownFile : file); if (line < 0) return file_name; else return file_name + ":" + StreamableToString(line); } GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; GetStream() << ::std::endl << marker << " " << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. GTestLog::~GTestLog() { GetStream() << ::std::endl; if (severity_ == GTEST_FATAL) { fflush(stderr); posix::Abort(); } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { # if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); const UINT success = ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, // Generate unique file name. temp_file_path); GTEST_CHECK_(success != 0) << "Unable to create a temporary file in " << temp_dir_path; const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; # else // There's no guarantee that a test has write access to the current // directory, so we create the temporary file in the /tmp directory // instead. We use /tmp on most systems, and /sdcard on Android. // That's because Android doesn't have /tmp. # if GTEST_OS_LINUX_ANDROID // Note: Android applications are expected to call the framework's // Context.getExternalStorageDirectory() method through JNI to get // the location of the world-writable SD Card directory. However, // this requires a Context handle, which cannot be retrieved // globally from native code. Doing so also precludes running the // code as part of a regular standalone executable, which doesn't // run in a Dalvik process (e.g. when running it through 'adb shell'). // // The location /sdcard is directly accessible from native code // and is the only location (unofficially) supported by the Android // team. It's generally a symlink to the real SD Card mount point // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or // other OEM-customized locations. Never rely on these, and always // use /sdcard. char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; # else char name_template[] = "/tmp/captured_stream.XXXXXX"; # endif // GTEST_OS_LINUX_ANDROID const int captured_fd = mkstemp(name_template); filename_ = name_template; # endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); } ~CapturedStream() { remove(filename_.c_str()); } std::string GetCapturedString() { if (uncaptured_fd_ != -1) { // Restores the original stream. fflush(NULL); dup2(uncaptured_fd_, fd_); close(uncaptured_fd_); uncaptured_fd_ = -1; } FILE* const file = posix::FOpen(filename_.c_str(), "r"); const std::string content = ReadEntireFile(file); posix::FClose(file); return content; } private: // Reads the entire content of a file as an std::string. static std::string ReadEntireFile(FILE* file); // Returns the size (in bytes) of a file. static size_t GetFileSize(FILE* file); const int fd_; // A stream to capture. int uncaptured_fd_; // Name of the temporary file holding the stderr output. ::std::string filename_; GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; // Returns the size (in bytes) of a file. size_t CapturedStream::GetFileSize(FILE* file) { fseek(file, 0, SEEK_END); return static_cast(ftell(file)); } // Reads the entire content of a file as a string. std::string CapturedStream::ReadEntireFile(FILE* file) { const size_t file_size = GetFileSize(file); char* const buffer = new char[file_size]; size_t bytes_last_read = 0; // # of bytes read in the last fread() size_t bytes_read = 0; // # of bytes read so far fseek(file, 0, SEEK_SET); // Keeps reading the file until we cannot read further or the // pre-determined file size is reached. do { bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); bytes_read += bytes_last_read; } while (bytes_last_read > 0 && bytes_read < file_size); const std::string content(buffer, bytes_read); delete[] buffer; return content; } GTEST_DISABLE_MSC_WARNINGS_POP_() static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { if (*stream != NULL) { GTEST_LOG_(FATAL) << "Only one " << stream_name << " capturer can exist at a time."; } *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. std::string GetCapturedStream(CapturedStream** captured_stream) { const std::string content = (*captured_stream)->GetCapturedString(); delete *captured_stream; *captured_stream = NULL; return content; } // Starts capturing stdout. void CaptureStdout() { CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. void CaptureStderr() { CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. std::string GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. std::string GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). ::std::vector g_argvs; static const ::std::vector* g_injected_test_argvs = NULL; // Owned. void SetInjectableArgvs(const ::std::vector* argvs) { if (g_injected_test_argvs != argvs) delete g_injected_test_argvs; g_injected_test_argvs = argvs; } const ::std::vector& GetInjectableArgvs() { if (g_injected_test_argvs != NULL) { return *g_injected_test_argvs; } return g_argvs; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE namespace posix { void Abort() { DebugBreak(); TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. static std::string FlagToEnvVar(const char* flag) { const std::string full_flag = (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); } // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. bool ParseInt32(const Message& src_text, const char* str, Int32* value) { // Parses the environment variable as a decimal integer. char* end = NULL; const long long_value = strtol(str, &end, 10); // NOLINT // Has strtol() consumed all characters in the string? if (*end != '\0') { // No - an invalid character was encountered. Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value \"" << str << "\".\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } // Is the parsed value in the range of an Int32? const Int32 result = static_cast(long_value); if (long_value == LONG_MAX || long_value == LONG_MIN || // The parsed value overflows as a long. (strtol() returns // LONG_MAX or LONG_MIN when the input overflows.) result != long_value // The parsed value overflows as an Int32. ) { Message msg; msg << "WARNING: " << src_text << " is expected to be a 32-bit integer, but actually" << " has value " << str << ", which overflows.\n"; printf("%s", msg.GetString().c_str()); fflush(stdout); return false; } *value = result; return true; } // Reads and returns the Boolean environment variable corresponding to // the given flag; if it's not set, returns default_value. // // The value is considered true iff it's not "0". bool BoolFromGTestEnv(const char* flag, bool default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const string_value = posix::GetEnv(env_var.c_str()); if (string_value == NULL) { // The environment variable is not set. return default_value; } Int32 result = default_value; if (!ParseInt32(Message() << "Environment variable " << env_var, string_value, &result)) { printf("The default value %s is used.\n", (Message() << default_value).GetString().c_str()); fflush(stdout); return default_value; } return result; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. const char* StringFromGTestEnv(const char* flag, const char* default_value) { const std::string env_var = FlagToEnvVar(flag); const char* const value = posix::GetEnv(env_var.c_str()); return value == NULL ? default_value : value; } } // namespace internal } // namespace testing node-v4.2.6/deps/gtest/src/gtest-printers.cc000644 000766 000024 00000030521 12650222322 021114 0ustar00iojsstaff000000 000000 // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // It uses the << operator when possible, and prints the bytes in the // object otherwise. A user can override its behavior for a class // type Foo by defining either operator<<(::std::ostream&, const Foo&) // or void PrintTo(const Foo&, ::std::ostream*) in the namespace that // defines Foo. #include "gtest/gtest-printers.h" #include #include #include #include // NOLINT #include #include "gtest/internal/gtest-port.h" namespace testing { namespace { using ::std::ostream; // Prints a segment of bytes in the given object. GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; for (size_t i = 0; i != count; i++) { const size_t j = start + i; if (i != 0) { // Organizes the bytes into groups of 2 for easy parsing by // human. if ((j % 2) == 0) *os << ' '; else *os << '-'; } GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); *os << text; } } // Prints the bytes in the given value to the given ostream. void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, ostream* os) { // Tells the user how big the object is. *os << count << "-byte object <"; const size_t kThreshold = 132; const size_t kChunkSize = 64; // If the object size is bigger than kThreshold, we'll have to omit // some details by printing only the first and the last kChunkSize // bytes. // TODO(wan): let the user control the threshold using a flag. if (count < kThreshold) { PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); } else { PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); *os << " ... "; // Rounds up to 2-byte boundary. const size_t resume_pos = (count - kChunkSize + 1)/2*2; PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); } *os << ">"; } } // namespace namespace internal2 { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which // uses the << operator and thus is easier done outside of the // ::testing::internal namespace, which contains a << operator that // sometimes conflicts with the one in STL. void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ostream* os) { PrintBytesInObjectToImpl(obj_bytes, count, os); } } // namespace internal2 namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, kHexEscape, kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. inline bool IsPrintableAscii(wchar_t c) { return 0x20 <= c && c <= 0x7E; } // Prints a wide or narrow char c as a character literal without the // quotes, escaping it when necessary; returns how c was formatted. // The template argument UnsignedChar is the unsigned version of Char, // which is the type of c. template static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { switch (static_cast(c)) { case L'\0': *os << "\\0"; break; case L'\'': *os << "\\'"; break; case L'\\': *os << "\\\\"; break; case L'\a': *os << "\\a"; break; case L'\b': *os << "\\b"; break; case L'\f': *os << "\\f"; break; case L'\n': *os << "\\n"; break; case L'\r': *os << "\\r"; break; case L'\t': *os << "\\t"; break; case L'\v': *os << "\\v"; break; default: if (IsPrintableAscii(c)) { *os << static_cast(c); return kAsIs; } else { *os << "\\x" + String::FormatHexInt(static_cast(c)); return kHexEscape; } } return kSpecialEscape; } // Prints a wchar_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { switch (c) { case L'\'': *os << "'"; return kAsIs; case L'"': *os << "\\\""; return kSpecialEscape; default: return PrintAsCharLiteralTo(c, os); } } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { return PrintAsStringLiteralTo( static_cast(static_cast(c)), os); } // Prints a wide or narrow character c and its code. '\0' is printed // as "'\\0'", other unprintable characters are also properly escaped // using the standard C++ escape sequence. The template argument // UnsignedChar is the unsigned version of Char, which is the type of c. template void PrintCharAndCodeTo(Char c, ostream* os) { // First, print c as a literal in the most readable form we can find. *os << ((sizeof(c) > 1) ? "L'" : "'"); const CharFormat format = PrintAsCharLiteralTo(c, os); *os << "'"; // To aid user debugging, we also print c's code in decimal, unless // it's 0 (in which case c was printed as '\\0', making the code // obvious). if (c == 0) return; *os << " (" << static_cast(c); // For more convenience, we print c's code again in hexidecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { // Do nothing. } else { *os << ", 0x" << String::FormatHexInt(static_cast(c)); } *os << ")"; } void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } // Prints the given array of characters to the ostream. CharType must be either // char or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; *os << kQuoteBegin; bool is_previous_hex = false; for (size_t index = 0; index < len; ++index) { const CharType cur = begin[index]; if (is_previous_hex && IsXDigit(cur)) { // Previous character is of '\x..' form and this character can be // interpreted as another hexadecimal digit in its number. Break string to // disambiguate. *os << "\" " << kQuoteBegin; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; } *os << "\""; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code // const char kFoo[] = "foo"; // generates an array of 4, not 3, elements, with the last one being '\0'. // // Therefore when printing a char array, we don't print the last element if // it's '\0', such that the output matches the string literal as it's // written in the source code. if (len > 0 && begin[len - 1] == '\0') { PrintCharsAsStringTo(begin, len - 1, os); return; } // If, however, the last element in the array is not '\0', e.g. // const char kFoo[] = { 'f', 'o', 'o' }; // we must print the entire array. We also print a message to indicate // that the array is not NUL-terminated. PrintCharsAsStringTo(begin, len, os); *os << " (no terminating NUL)"; } // Prints a (const) char array of 'len' elements, starting at address 'begin'. void UniversalPrintArray(const char* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } // Prints the given C string to the ostream. void PrintTo(const char* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, strlen(s), os); } } // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, // possibly accessing more memory than intended and causing invalid // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. void PrintTo(const wchar_t* s, ostream* os) { if (s == NULL) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; PrintCharsAsStringTo(s, std::wcslen(s), os); } } #endif // wchar_t is native // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_STRING void PrintStringTo(const ::std::string& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } // Prints a ::wstring object. #if GTEST_HAS_GLOBAL_WSTRING void PrintWideStringTo(const ::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING void PrintWideStringTo(const ::std::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_STD_WSTRING } // namespace internal } // namespace testing node-v4.2.6/deps/gtest/src/gtest-test-part.cc000644 000766 000024 00000010103 12650222322 021163 0ustar00iojsstaff000000 000000 // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest-test-part.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick exists to // prevent the accidental inclusion of gtest-internal-inl.h in the // user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ namespace testing { using internal::GetUnitTestImpl; // Gets the summary of the failure message by omitting the stack trace // in it. std::string TestPartResult::ExtractSummary(const char* message) { const char* const stack_trace = strstr(message, internal::kStackTraceMarker); return stack_trace == NULL ? message : std::string(message, stack_trace); } // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { return os << result.file_name() << ":" << result.line_number() << ": " << (result.type() == TestPartResult::kSuccess ? "Success" : result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : "Non-fatal failure") << ":\n" << result.message() << std::endl; } // Appends a TestPartResult to the array. void TestPartResultArray::Append(const TestPartResult& result) { array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { if (index < 0 || index >= size()) { printf("\nInvalid index (%d) into TestPartResultArray.\n", index); internal::posix::Abort(); } return array_[index]; } // Returns the number of TestPartResult objects in the array. int TestPartResultArray::size() const { return static_cast(array_.size()); } namespace internal { HasNewFatalFailureHelper::HasNewFatalFailureHelper() : has_new_fatal_failure_(false), original_reporter_(GetUnitTestImpl()-> GetTestPartResultReporterForCurrentThread()) { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( original_reporter_); } void HasNewFatalFailureHelper::ReportTestPartResult( const TestPartResult& result) { if (result.fatally_failed()) has_new_fatal_failure_ = true; original_reporter_->ReportTestPartResult(result); } } // namespace internal } // namespace testing node-v4.2.6/deps/gtest/src/gtest-typed-test.cc000644 000766 000024 00000007554 12650222322 021362 0ustar00iojsstaff000000 000000 // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #include "gtest/gtest-typed-test.h" #include "gtest/gtest.h" namespace testing { namespace internal { #if GTEST_HAS_TYPED_TEST_P // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { while (IsSpace(*str)) str++; return str; } static std::vector SplitIntoTestNames(const char* src) { std::vector name_vec; src = SkipSpaces(src); for (; src != NULL; src = SkipComma(src)) { name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); } return name_vec; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestCasePState::VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests) { typedef ::std::set::const_iterator DefinedTestIter; registered_ = true; std::vector name_vec = SplitIntoTestNames(registered_tests); Message errors; std::set tests; for (std::vector::const_iterator name_it = name_vec.begin(); name_it != name_vec.end(); ++name_it) { const std::string& name = *name_it; if (tests.count(name) != 0) { errors << "Test " << name << " is listed more than once.\n"; continue; } bool found = false; for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (name == *it) { found = true; break; } } if (found) { tests.insert(name); } else { errors << "No test named " << name << " can be found in this test case.\n"; } } for (DefinedTestIter it = defined_test_names_.begin(); it != defined_test_names_.end(); ++it) { if (tests.count(*it) == 0) { errors << "You forgot to list test " << *it << ".\n"; } } const std::string& errors_str = errors.GetString(); if (errors_str != "") { fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors_str.c_str()); fflush(stderr); posix::Abort(); } return registered_tests; } #endif // GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing node-v4.2.6/deps/gtest/src/gtest.cc000644 000766 000024 00000570356 12650222322 017267 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) #include "gtest/gtest.h" #include "gtest/gtest-spi.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // NOLINT #include #include #if GTEST_OS_LINUX // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # include // NOLINT # include // NOLINT // Declares vsnprintf(). This header is not available on Windows. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # include #elif GTEST_OS_SYMBIAN # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT #elif GTEST_OS_ZOS # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. # include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include // NOLINT # undef min #elif GTEST_OS_WINDOWS // We are on Windows proper. # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT # if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. # define GTEST_HAS_GETTIMEOFDAY_ 1 # include // NOLINT # endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT # undef min #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). # define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT # include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT # include // NOLINT # include // NOLINT #endif // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is // included, or there will be a compiler error. This trick is to // prevent a user from accidentally including gtest-internal-inl.h in // his code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS # define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { using internal::CountIf; using internal::ForEach; using internal::GetElementOr; using internal::Shuffle; // Constants. // A test whose test case name or test name matches this filter is // disabled and not run. static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; // A test case whose name matches this filter is considered a death // test case and will be run before test cases whose name doesn't // match this filter. static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; // A test filter that matches everything. static const char kUniversalFilter[] = "*"; // The default output file for XML output. static const char kDefaultOutputFile[] = "test_detail.xml"; // The environment variable name for the test shard index. static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; // The environment variable name for the total number of test shards. static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; namespace internal { // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; // g_help_flag is true iff the --help flag or an equivalent form is // specified on the command line. bool g_help_flag = false; } // namespace internal static const char* GetDefaultFilter() { return kUniversalFilter; } GTEST_DEFINE_bool_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false), "True iff a failed assertion should be a debugger break-point."); GTEST_DEFINE_bool_( catch_exceptions, internal::BoolFromGTestEnv("catch_exceptions", true), "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( color, internal::StringFromGTestEnv("color", "auto"), "Whether to use colors in the output. Valid values: yes, no, " "and auto. 'auto' means to use colors if the output is " "being sent to a terminal and the TERM environment variable " "is set to a terminal type that supports colors."); GTEST_DEFINE_string_( filter, internal::StringFromGTestEnv("filter", GetDefaultFilter()), "A colon-separated list of glob (not regex) patterns " "for filtering the tests to run, optionally followed by a " "'-' and a : separated list of negative patterns (tests to " "exclude). A test is run if it matches one of the positive " "patterns and does not match any of the negative patterns."); GTEST_DEFINE_bool_(list_tests, false, "List all tests without running them."); GTEST_DEFINE_string_( output, internal::StringFromGTestEnv("output", ""), "A format (currently must be \"xml\"), optionally followed " "by a colon and an output file name or directory. A directory " "is indicated by a trailing pathname separator. " "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " "If a directory is specified, output files will be created " "within that directory, with file-names based on the test " "executable's name and, if necessary, made unique by adding " "digits."); GTEST_DEFINE_bool_( print_time, internal::BoolFromGTestEnv("print_time", true), "True iff " GTEST_NAME_ " should display elapsed time in text output."); GTEST_DEFINE_int32_( random_seed, internal::Int32FromGTestEnv("random_seed", 0), "Random number seed to use when shuffling test orders. Must be in range " "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( repeat, internal::Int32FromGTestEnv("repeat", 1), "How many times to repeat each test. Specify a negative number " "for repeating forever. Useful for shaking out flaky tests."); GTEST_DEFINE_bool_( show_internal_stack_frames, false, "True iff " GTEST_NAME_ " should include internal stack frames when " "printing test failure stack traces."); GTEST_DEFINE_bool_( shuffle, internal::BoolFromGTestEnv("shuffle", false), "True iff " GTEST_NAME_ " should randomize tests' order on every run."); GTEST_DEFINE_int32_( stack_trace_depth, internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( stream_result_to, internal::StringFromGTestEnv("stream_result_to", ""), "This flag specifies the host name and the port number on which to stream " "test results. Example: \"localhost:555\". The flag is effective only on " "Linux."); GTEST_DEFINE_bool_( throw_on_failure, internal::BoolFromGTestEnv("throw_on_failure", false), "When this flag is specified, a failed assertion will throw an exception " "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); namespace internal { // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. UInt32 Random::Generate(UInt32 range) { // These constants are the same as are used in glibc's rand(3). state_ = (1103515245U*state_ + 12345U) % kMaxRange; GTEST_CHECK_(range > 0) << "Cannot generate a number in the range [0, 0)."; GTEST_CHECK_(range <= kMaxRange) << "Generation of a number in [0, " << range << ") was requested, " << "but this can only generate numbers in [0, " << kMaxRange << ")."; // Converting via modulus introduces a bit of downward bias, but // it's simple, and a linear congruential generator isn't too good // to begin with. return state_ % range; } // GTestIsInitialized() returns true iff the user has initialized // Google Test. Useful for catching the user mistake of not initializing // Google Test before calling RUN_ALL_TESTS(). // // A user must call testing::InitGoogleTest() to initialize Google // Test. g_init_gtest_count is set to the number of times // InitGoogleTest() has been called. We don't protect this variable // under a mutex as it is only accessed in the main thread. GTEST_API_ int g_init_gtest_count = 0; static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // Iterates over a vector of TestCases, keeping a running sum of the // results of calling a given int-returning method on each. // Returns the sum. static int SumOverTestCaseList(const std::vector& case_list, int (TestCase::*method)() const) { int sum = 0; for (size_t i = 0; i < case_list.size(); i++) { sum += (case_list[i]->*method)(); } return sum; } // Returns true iff the test case passed. static bool TestCasePassed(const TestCase* test_case) { return test_case->should_run() && test_case->Passed(); } // Returns true iff the test case failed. static bool TestCaseFailed(const TestCase* test_case) { return test_case->should_run() && test_case->Failed(); } // Returns true iff test_case contains at least one test that should // run. static bool ShouldRunTestCase(const TestCase* test_case) { return test_case->should_run(); } // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message) : data_(new AssertHelperData(type, file, line, message)) { } AssertHelper::~AssertHelper() { delete data_; } // Message assignment, for assertion streaming support. void AssertHelper::operator=(const Message& message) const { UnitTest::GetInstance()-> AddTestPartResult(data_->type, data_->file, data_->line, AppendUserMessage(data_->message, message), UnitTest::GetInstance()->impl() ->CurrentOsStackTraceExceptTop(1) // Skips the stack frame for this function itself. ); // NOLINT } // Mutex for linked pointers. GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); // Application pathname gotten in InitGoogleTest. std::string g_executable_path; // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { FilePath result; #if GTEST_OS_WINDOWS result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else result.Set(FilePath(g_executable_path)); #endif // GTEST_OS_WINDOWS return result.RemoveDirectoryName(); } // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. std::string UnitTestOptions::GetOutputFormat() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return std::string(""); const char* const colon = strchr(gtest_output_flag, ':'); return (colon == NULL) ? std::string(gtest_output_flag) : std::string(gtest_output_flag, colon - gtest_output_flag); } // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); if (gtest_output_flag == NULL) return ""; const char* const colon = strchr(gtest_output_flag, ':'); if (colon == NULL) return internal::FilePath::ConcatPaths( internal::FilePath( UnitTest::GetInstance()->original_working_dir()), internal::FilePath(kDefaultOutputFile)).string(); internal::FilePath output_name(colon + 1); if (!output_name.IsAbsolutePath()) // TODO(wan@google.com): on Windows \some\path is not an absolute // path (as its meaning depends on the current drive), yet the // following logic for turning it into an absolute path is wrong. // Fix it. output_name = internal::FilePath::ConcatPaths( internal::FilePath(UnitTest::GetInstance()->original_working_dir()), internal::FilePath(colon + 1)); if (!output_name.IsDirectory()) return output_name.string(); internal::FilePath result(internal::FilePath::GenerateUniqueFileName( output_name, internal::GetCurrentExecutableName(), GetOutputFormat().c_str())); return result.string(); } // Returns true iff the wildcard pattern matches the string. The // first ':' or '\0' character in pattern marks the end of it. // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. bool UnitTestOptions::PatternMatchesString(const char *pattern, const char *str) { switch (*pattern) { case '\0': case ':': // Either ':' or '\0' marks the end of the pattern. return *str == '\0'; case '?': // Matches any single character. return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); case '*': // Matches any string (possibly empty) of characters. return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || PatternMatchesString(pattern + 1, str); default: // Non-special character. Matches itself. return *pattern == *str && PatternMatchesString(pattern + 1, str + 1); } } bool UnitTestOptions::MatchesFilter( const std::string& name, const char* filter) { const char *cur_pattern = filter; for (;;) { if (PatternMatchesString(cur_pattern, name.c_str())) { return true; } // Finds the next pattern in the filter. cur_pattern = strchr(cur_pattern, ':'); // Returns if no more pattern can be found. if (cur_pattern == NULL) { return false; } // Skips the pattern separater (the ':' character). cur_pattern++; } } // Returns true iff the user-specified filter matches the test case // name and the test name. bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, const std::string &test_name) { const std::string& full_name = test_case_name + "." + test_name.c_str(); // Split --gtest_filter at '-', if there is one, to separate into // positive filter and negative filter portions const char* const p = GTEST_FLAG(filter).c_str(); const char* const dash = strchr(p, '-'); std::string positive; std::string negative; if (dash == NULL) { positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter negative = ""; } else { positive = std::string(p, dash); // Everything up to the dash negative = std::string(dash + 1); // Everything after the dash if (positive.empty()) { // Treat '-test1' as the same as '*-test1' positive = kUniversalFilter; } } // A filter is a colon-separated list of patterns. It matches a // test if any pattern in it matches the test. return (MatchesFilter(full_name, positive.c_str()) && !MatchesFilter(full_name, negative.c_str())); } #if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // Google Test should handle a SEH exception if: // 1. the user wants it to, AND // 2. this is not a breakpoint exception, AND // 3. this is not a C++ exception (VC++ implements them via SEH, // apparently). // // SEH exception code for C++ exceptions. // (see http://support.microsoft.com/kb/185294 for more information). const DWORD kCxxExceptionCode = 0xe06d7363; bool should_handle = true; if (!GTEST_FLAG(catch_exceptions)) should_handle = false; else if (exception_code == EXCEPTION_BREAKPOINT) should_handle = false; else if (exception_code == kCxxExceptionCode) should_handle = false; return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } #endif // GTEST_HAS_SEH } // namespace internal // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( TestPartResultArray* result) : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), result_(result) { Init(); } // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( InterceptMode intercept_mode, TestPartResultArray* result) : intercept_mode_(intercept_mode), result_(result) { Init(); } void ScopedFakeTestPartResultReporter::Init() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { old_reporter_ = impl->GetGlobalTestPartResultReporter(); impl->SetGlobalTestPartResultReporter(this); } else { old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); impl->SetTestPartResultReporterForCurrentThread(this); } } // The d'tor restores the test part result reporter used by Google Test // before. ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); if (intercept_mode_ == INTERCEPT_ALL_THREADS) { impl->SetGlobalTestPartResultReporter(old_reporter_); } else { impl->SetTestPartResultReporterForCurrentThread(old_reporter_); } } // Increments the test part result count and remembers the result. // This method is from the TestPartResultReporterInterface interface. void ScopedFakeTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { result_->Append(result); } namespace internal { // Returns the type ID of ::testing::Test. We should always call this // instead of GetTypeId< ::testing::Test>() to get the type ID of // testing::Test. This is to work around a suspected linker bug when // using Google Test as a framework on Mac OS X. The bug causes // GetTypeId< ::testing::Test>() to return different values depending // on whether the call is from the Google Test framework itself or // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. TypeId GetTestTypeId() { return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); // This predicate-formatter checks that 'results' contains a test part // failure of the given type and that the failure message contains the // given substring. AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* type_expr */, const char* /* substr_expr */, const TestPartResultArray& results, TestPartResult::Type type, const string& substr) { const std::string expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); Message msg; if (results.size() != 1) { msg << "Expected: " << expected << "\n" << " Actual: " << results.size() << " failures"; for (int i = 0; i < results.size(); i++) { msg << "\n" << results.GetTestPartResult(i); } return AssertionFailure() << msg; } const TestPartResult& r = results.GetTestPartResult(0); if (r.type() != type) { return AssertionFailure() << "Expected: " << expected << "\n" << " Actual:\n" << r; } if (strstr(r.message(), substr.c_str()) == NULL) { return AssertionFailure() << "Expected: " << expected << " containing \"" << substr << "\"\n" << " Actual:\n" << r; } return AssertionSuccess(); } // The constructor of SingleFailureChecker remembers where to look up // test part results, what type of failure we expect, and what // substring the failure message should contain. SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, TestPartResult::Type type, const string& substr) : results_(results), type_(type), substr_(substr) {} // The destructor of SingleFailureChecker verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. SingleFailureChecker::~SingleFailureChecker() { EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->current_test_result()->AddTestPartResult(result); unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( const TestPartResult& result) { unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); } // Returns the global test part result reporter. TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); return global_test_part_result_repoter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); global_test_part_result_repoter_ = reporter; } // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* UnitTestImpl::GetTestPartResultReporterForCurrentThread() { return per_thread_test_part_result_reporter_.get(); } // Sets the test part result reporter for the current thread. void UnitTestImpl::SetTestPartResultReporterForCurrentThread( TestPartResultReporterInterface* reporter) { per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. int UnitTestImpl::successful_test_case_count() const { return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. int UnitTestImpl::failed_test_case_count() const { return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. int UnitTestImpl::total_test_case_count() const { return static_cast(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTestImpl::test_case_to_run_count() const { return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. int UnitTestImpl::successful_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); } // Gets the number of failed tests. int UnitTestImpl::failed_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTestImpl::reportable_disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_disabled_test_count); } // Gets the number of disabled tests. int UnitTestImpl::disabled_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); } // Gets the number of tests to be printed in the XML report. int UnitTestImpl::reportable_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); } // Gets the number of all tests. int UnitTestImpl::total_test_count() const { return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); } // Gets the number of tests that should run. int UnitTestImpl::test_to_run_count() const { return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { (void)skip_count; return ""; } // Returns the current time in milliseconds. TimeInMillis GetTimeInMillis() { #if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) // Difference between 1970-01-01 and 1601-01-01 in milliseconds. // http://analogous.blogspot.com/2005/04/epoch.html const TimeInMillis kJavaEpochToWinFileTimeDelta = static_cast(116444736UL) * 100000UL; const DWORD kTenthMicrosInMilliSecond = 10000; SYSTEMTIME now_systime; FILETIME now_filetime; ULARGE_INTEGER now_int64; // TODO(kenton@google.com): Shouldn't this just use // GetSystemTimeAsFileTime()? GetSystemTime(&now_systime); if (SystemTimeToFileTime(&now_systime, &now_filetime)) { now_int64.LowPart = now_filetime.dwLowDateTime; now_int64.HighPart = now_filetime.dwHighDateTime; now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - kJavaEpochToWinFileTimeDelta; return now_int64.QuadPart; } return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 // (deprecated function) there. // TODO(kenton@google.com): Use GetTickCount()? Or use // SystemTimeToFileTime() GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) _ftime64(&now); GTEST_DISABLE_MSC_WARNINGS_POP_() return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; #else # error "Don't know how to get the current time on your system." #endif } // Utilities // class String. #if GTEST_OS_WINDOWS_MOBILE // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. LPCWSTR String::AnsiToUtf16(const char* ansi) { if (!ansi) return NULL; const int length = strlen(ansi); const int unicode_length = MultiByteToWideChar(CP_ACP, 0, ansi, length, NULL, 0); WCHAR* unicode = new WCHAR[unicode_length + 1]; MultiByteToWideChar(CP_ACP, 0, ansi, length, unicode, unicode_length); unicode[unicode_length] = 0; return unicode; } // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { if (!utf16_str) return NULL; const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, NULL, 0, NULL, NULL); char* ansi = new char[ansi_length + 1]; WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, NULL, NULL); ansi[ansi_length] = 0; return ansi; } #endif // GTEST_OS_WINDOWS_MOBILE // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::CStringEquals(const char * lhs, const char * rhs) { if ( lhs == NULL ) return rhs == NULL; if ( rhs == NULL ) return false; return strcmp(lhs, rhs) == 0; } #if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, Message* msg) { for (size_t i = 0; i != length; ) { // NOLINT if (wstr[i] != L'\0') { *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); while (i != length && wstr[i] != L'\0') i++; } else { *msg << '\0'; i++; } } } #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING } // namespace internal // Constructs an empty Message. // We allocate the stringstream separately because otherwise each use of // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. Message::Message() : ss_(new ::std::stringstream) { // By default, we want there to be enough precision when printing // a double to a Message. *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& Message::operator <<(const wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } Message& Message::operator <<(wchar_t* wide_c_str) { return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::std::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& Message::operator <<(const ::wstring& wstr) { internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); return *this; } #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". std::string Message::GetString() const { return internal::StringStreamToString(ss_.get()); } // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) : success_(other.success_), message_(other.message_.get() != NULL ? new ::std::string(*other.message_) : static_cast< ::std::string*>(NULL)) { } // Swaps two AssertionResults. void AssertionResult::swap(AssertionResult& other) { using std::swap; swap(success_, other.success_); swap(message_, other.message_); } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); if (message_.get() != NULL) negation << *message_; return negation; } // Makes a successful assertion result. AssertionResult AssertionSuccess() { return AssertionResult(true); } // Makes a failed assertion result. AssertionResult AssertionFailure() { return AssertionResult(false); } // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << message. AssertionResult AssertionFailure(const Message& message) { return AssertionFailure() << message; } namespace internal { namespace edit_distance { std::vector CalculateOptimalEdits(const std::vector& left, const std::vector& right) { std::vector > costs( left.size() + 1, std::vector(right.size() + 1)); std::vector > best_move( left.size() + 1, std::vector(right.size() + 1)); // Populate for empty right. for (size_t l_i = 0; l_i < costs.size(); ++l_i) { costs[l_i][0] = static_cast(l_i); best_move[l_i][0] = kRemove; } // Populate for empty left. for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { costs[0][r_i] = static_cast(r_i); best_move[0][r_i] = kAdd; } for (size_t l_i = 0; l_i < left.size(); ++l_i) { for (size_t r_i = 0; r_i < right.size(); ++r_i) { if (left[l_i] == right[r_i]) { // Found a match. Consume it. costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; best_move[l_i + 1][r_i + 1] = kMatch; continue; } const double add = costs[l_i + 1][r_i]; const double remove = costs[l_i][r_i + 1]; const double replace = costs[l_i][r_i]; if (add < remove && add < replace) { costs[l_i + 1][r_i + 1] = add + 1; best_move[l_i + 1][r_i + 1] = kAdd; } else if (remove < add && remove < replace) { costs[l_i + 1][r_i + 1] = remove + 1; best_move[l_i + 1][r_i + 1] = kRemove; } else { // We make replace a little more expensive than add/remove to lower // their priority. costs[l_i + 1][r_i + 1] = replace + 1.00001; best_move[l_i + 1][r_i + 1] = kReplace; } } } // Reconstruct the best path. We do it in reverse order. std::vector best_path; for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { EditType move = best_move[l_i][r_i]; best_path.push_back(move); l_i -= move != kAdd; r_i -= move != kRemove; } std::reverse(best_path.begin(), best_path.end()); return best_path; } namespace { // Helper class to convert string into ids with deduplication. class InternalStrings { public: size_t GetId(const std::string& str) { IdMap::iterator it = ids_.find(str); if (it != ids_.end()) return it->second; size_t id = ids_.size(); return ids_[str] = id; } private: typedef std::map IdMap; IdMap ids_; }; } // namespace std::vector CalculateOptimalEdits( const std::vector& left, const std::vector& right) { std::vector left_ids, right_ids; { InternalStrings intern_table; for (size_t i = 0; i < left.size(); ++i) { left_ids.push_back(intern_table.GetId(left[i])); } for (size_t i = 0; i < right.size(); ++i) { right_ids.push_back(intern_table.GetId(right[i])); } } return CalculateOptimalEdits(left_ids, right_ids); } namespace { // Helper class that holds the state for one hunk and prints it out to the // stream. // It reorders adds/removes when possible to group all removes before all // adds. It also adds the hunk header before printint into the stream. class Hunk { public: Hunk(size_t left_start, size_t right_start) : left_start_(left_start), right_start_(right_start), adds_(), removes_(), common_() {} void PushLine(char edit, const char* line) { switch (edit) { case ' ': ++common_; FlushEdits(); hunk_.push_back(std::make_pair(' ', line)); break; case '-': ++removes_; hunk_removes_.push_back(std::make_pair('-', line)); break; case '+': ++adds_; hunk_adds_.push_back(std::make_pair('+', line)); break; } } void PrintTo(std::ostream* os) { PrintHeader(os); FlushEdits(); for (std::list >::const_iterator it = hunk_.begin(); it != hunk_.end(); ++it) { *os << it->first << it->second << "\n"; } } bool has_edits() const { return adds_ || removes_; } private: void FlushEdits() { hunk_.splice(hunk_.end(), hunk_removes_); hunk_.splice(hunk_.end(), hunk_adds_); } // Print a unified diff header for one hunk. // The format is // "@@ -, +, @@" // where the left/right parts are ommitted if unnecessary. void PrintHeader(std::ostream* ss) const { *ss << "@@ "; if (removes_) { *ss << "-" << left_start_ << "," << (removes_ + common_); } if (removes_ && adds_) { *ss << " "; } if (adds_) { *ss << "+" << right_start_ << "," << (adds_ + common_); } *ss << " @@\n"; } size_t left_start_, right_start_; size_t adds_, removes_, common_; std::list > hunk_, hunk_adds_, hunk_removes_; }; } // namespace // Create a list of diff hunks in Unified diff format. // Each hunk has a header generated by PrintHeader above plus a body with // lines prefixed with ' ' for no change, '-' for deletion and '+' for // addition. // 'context' represents the desired unchanged prefix/suffix around the diff. // If two hunks are close enough that their contexts overlap, then they are // joined into one hunk. std::string CreateUnifiedDiff(const std::vector& left, const std::vector& right, size_t context) { const std::vector edits = CalculateOptimalEdits(left, right); size_t l_i = 0, r_i = 0, edit_i = 0; std::stringstream ss; while (edit_i < edits.size()) { // Find first edit. while (edit_i < edits.size() && edits[edit_i] == kMatch) { ++l_i; ++r_i; ++edit_i; } // Find the first line to include in the hunk. const size_t prefix_context = std::min(l_i, context); Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); for (size_t i = prefix_context; i > 0; --i) { hunk.PushLine(' ', left[l_i - i].c_str()); } // Iterate the edits until we found enough suffix for the hunk or the input // is over. size_t n_suffix = 0; for (; edit_i < edits.size(); ++edit_i) { if (n_suffix >= context) { // Continue only if the next hunk is very close. std::vector::const_iterator it = edits.begin() + edit_i; while (it != edits.end() && *it == kMatch) ++it; if (it == edits.end() || (it - edits.begin()) - edit_i >= context) { // There is no next edit or it is too far away. break; } } EditType edit = edits[edit_i]; // Reset count when a non match is found. n_suffix = edit == kMatch ? n_suffix + 1 : 0; if (edit == kMatch || edit == kRemove || edit == kReplace) { hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); } if (edit == kAdd || edit == kReplace) { hunk.PushLine('+', right[r_i].c_str()); } // Advance indices, depending on edit type. l_i += edit != kAdd; r_i += edit != kRemove; } if (!hunk.has_edits()) { // We are done. We don't want this hunk. break; } hunk.PrintTo(&ss); } return ss.str(); } } // namespace edit_distance namespace { // The string representation of the values received in EqFailure() are already // escaped. Split them on escaped '\n' boundaries. Leave all other escaped // characters the same. std::vector SplitEscapedString(const std::string& str) { std::vector lines; size_t start = 0, end = str.size(); if (end > 2 && str[0] == '"' && str[end - 1] == '"') { ++start; --end; } bool escaped = false; for (size_t i = start; i + 1 < end; ++i) { if (escaped) { escaped = false; if (str[i] == 'n') { lines.push_back(str.substr(start, i - start - 1)); start = i + 1; } } else { escaped = str[i] == '\\'; } } lines.push_back(str.substr(start, end - start)); return lines; } } // namespace // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case) { Message msg; msg << "Value of: " << actual_expression; if (actual_value != actual_expression) { msg << "\n Actual: " << actual_value; } msg << "\nExpected: " << expected_expression; if (ignoring_case) { msg << " (ignoring case)"; } if (expected_value != expected_expression) { msg << "\nWhich is: " << expected_value; } if (!expected_value.empty() && !actual_value.empty()) { const std::vector expected_lines = SplitEscapedString(expected_value); const std::vector actual_lines = SplitEscapedString(actual_value); if (expected_lines.size() > 1 || actual_lines.size() > 1) { msg << "\nWith diff:\n" << edit_distance::CreateUnifiedDiff(expected_lines, actual_lines); } } return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value) { const char* actual_message = assertion_result.message(); Message msg; msg << "Value of: " << expression_text << "\n Actual: " << actual_predicate_value; if (actual_message[0] != '\0') msg << " (" << actual_message << ")"; msg << "\nExpected: " << expected_predicate_value; return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error) { const double diff = fabs(val1 - val2); if (diff <= abs_error) return AssertionSuccess(); // TODO(wan): do not print the value of an expression if it's // already a literal. return AssertionFailure() << "The difference between " << expr1 << " and " << expr2 << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" << expr1 << " evaluates to " << val1 << ",\n" << expr2 << " evaluates to " << val2 << ", and\n" << abs_error_expr << " evaluates to " << abs_error << "."; } // Helper template for implementing FloatLE() and DoubleLE(). template AssertionResult FloatingPointLE(const char* expr1, const char* expr2, RawType val1, RawType val2) { // Returns success if val1 is less than val2, if (val1 < val2) { return AssertionSuccess(); } // or if val1 is almost equal to val2. const FloatingPoint lhs(val1), rhs(val2); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } // Note that the above two checks will both fail if either val1 or // val2 is NaN, as the IEEE floating-point standard requires that // any predicate involving a NaN must return false. ::std::stringstream val1_ss; val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val1; ::std::stringstream val2_ss; val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val2; return AssertionFailure() << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" << " Actual: " << StringStreamToString(&val1_ss) << " vs " << StringStreamToString(&val2_ss); } } // namespace internal // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2) { return internal::FloatingPointLE(expr1, expr2, val1, val2); } namespace internal { // The helper function for {ASSERT|EXPECT}_EQ with int or enum // arguments. AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { if (expected == actual) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ BiggestInt val1, BiggestInt val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return AssertionFailure() \ << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ }\ } // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(NE, !=) // Implements the helper function for {ASSERT|EXPECT}_LE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(LT, < ) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GT, > ) #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual) { if (String::CaseInsensitiveCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2) { if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; } } } // namespace internal namespace { // Helper functions for implementing IsSubString() and IsNotSubstring(). // This group of overloaded functions return true iff needle is a // substring of haystack. NULL is considered a substring of itself // only. bool IsSubstringPred(const char* needle, const char* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return strstr(haystack, needle) != NULL; } bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { if (needle == NULL || haystack == NULL) return needle == haystack; return wcsstr(haystack, needle) != NULL; } // StringType here can be either ::std::string or ::std::wstring. template bool IsSubstringPred(const StringType& needle, const StringType& haystack) { return haystack.find(needle) != StringType::npos; } // This function implements either IsSubstring() or IsNotSubstring(), // depending on the value of the expected_to_be_substring parameter. // StringType here can be const char*, const wchar_t*, ::std::string, // or ::std::wstring. template AssertionResult IsSubstringImpl( bool expected_to_be_substring, const char* needle_expr, const char* haystack_expr, const StringType& needle, const StringType& haystack) { if (IsSubstringPred(needle, haystack) == expected_to_be_substring) return AssertionSuccess(); const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; return AssertionFailure() << "Value of: " << needle_expr << "\n" << " Actual: " << begin_string_quote << needle << "\"\n" << "Expected: " << (expected_to_be_substring ? "" : "not ") << "a substring of " << haystack_expr << "\n" << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace // IsSubstring() and IsNotSubstring() check whether needle is a // substring of haystack (NULL is considered a substring of itself // only), and return an appropriate error message when they fail. AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack) { return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING namespace internal { #if GTEST_OS_WINDOWS namespace { // Helper function for IsHRESULT{SuccessFailure} predicates AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT # if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't support FormatMessage. const char error_text[] = ""; # else // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; const DWORD kBufSize = 4096; // Gets the system's human readable message string for this HRESULT. char error_text[kBufSize] = { '\0' }; DWORD message_length = ::FormatMessageA(kFlags, 0, // no source, we're asking system hr, // the error 0, // no line width restrictions error_text, // output buffer kBufSize, // buf size NULL); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing CR-LF) for (; message_length && IsSpace(error_text[message_length - 1]); --message_length) { error_text[message_length - 1] = '\0'; } # endif // GTEST_OS_WINDOWS_MOBILE const std::string error_hex("0x" + String::FormatHexInt(hr)); return ::testing::AssertionFailure() << "Expected: " << expr << " " << expected << ".\n" << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT if (SUCCEEDED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "succeeds", hr); } AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT if (FAILED(hr)) { return AssertionSuccess(); } return HRESULTFailureHelper(expr, "fails", hr); } #endif // GTEST_OS_WINDOWS // Utility functions for encoding Unicode text (wide strings) in // UTF-8. // A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 // like this: // // Code-point length Encoding // 0 - 7 bits 0xxxxxxx // 8 - 11 bits 110xxxxx 10xxxxxx // 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. inline UInt32 ChopLowBits(UInt32* bits, int n) { const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); *bits >>= n; return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be // wide enough to contain a code point. // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". std::string CodePointToUtf8(UInt32 code_point) { if (code_point > kMaxCodePoint4) { return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; } char str[5]; // Big enough for the largest valid code point. if (code_point <= kMaxCodePoint1) { str[1] = '\0'; str[0] = static_cast(code_point); // 0xxxxxxx } else if (code_point <= kMaxCodePoint2) { str[2] = '\0'; str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xC0 | code_point); // 110xxxxx } else if (code_point <= kMaxCodePoint3) { str[3] = '\0'; str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xE0 | code_point); // 1110xxxx } else { // code_point <= kMaxCodePoint4 str[4] = '\0'; str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx str[0] = static_cast(0xF0 | code_point); // 11110xxx } return str; } // The following two functions only make sense if the the system // uses UTF-16 for wide string encoding. All supported systems // with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. // Determines if the arguments constitute UTF-16 surrogate pair // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { return sizeof(wchar_t) == 2 && (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second) { const UInt32 mask = (1 << 10) - 1; return (sizeof(wchar_t) == 2) ? (((first & mask) << 10) | (second & mask)) + 0x10000 : // This function should not be called when the condition is // false, but we provide a sensible default in case it is. static_cast(first); } // Converts a wide string to a narrow string in UTF-8 encoding. // The wide string is assumed to have the following encoding: // UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) // UTF-32 if sizeof(wchar_t) == 4 (on Linux) // Parameter str points to a null-terminated wide string. // Parameter num_chars may additionally limit the number // of wchar_t characters processed. -1 is used when the entire string // should be processed. // If the string contains code points that are not valid Unicode code points // (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. std::string WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) num_chars = static_cast(wcslen(str)); ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { UInt32 unicode_code_point; if (str[i] == L'\0') { break; } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], str[i + 1]); i++; } else { unicode_code_point = static_cast(str[i]); } stream << CodePointToUtf8(unicode_code_point); } return StringStreamToString(&stream); } // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". std::string String::ShowWideCString(const wchar_t * wide_c_str) { if (wide_c_str == NULL) return "(null)"; return internal::WideStringToUtf8(wide_c_str, -1); } // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return wcscmp(lhs, rhs) == 0; } // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual) { if (String::WideCStringEquals(expected, actual)) { return AssertionSuccess(); } return EqFailure(expected_expression, actual_expression, PrintToString(expected), PrintToString(actual), false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2) { if (!String::WideCStringEquals(s1, s2)) { return AssertionSuccess(); } return AssertionFailure() << "Expected: (" << s1_expression << ") != (" << s2_expression << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true iff they have // the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; return posix::StrCaseCmp(lhs, rhs) == 0; } // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { if (lhs == NULL) return rhs == NULL; if (rhs == NULL) return false; #if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; #elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID return wcscasecmp(lhs, rhs) == 0; #else // Android, Mac OS X and Cygwin don't define wcscasecmp. // Other unknown OSes may not define it either. wint_t left, right; do { left = towlower(*lhs++); right = towlower(*rhs++); } while (left && left == right); return left == right; #endif // OS selector } // Returns true iff str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. bool String::EndsWithCaseInsensitive( const std::string& str, const std::string& suffix) { const size_t str_len = str.length(); const size_t suffix_len = suffix.length(); return (str_len >= suffix_len) && CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, suffix.c_str()); } // Formats an int value as "%02d". std::string String::FormatIntWidth2(int value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << value; return ss.str(); } // Formats an int value as "%X". std::string String::FormatHexInt(int value) { std::stringstream ss; ss << std::hex << std::uppercase << value; return ss.str(); } // Formats a byte as "%02X". std::string String::FormatByte(unsigned char value) { std::stringstream ss; ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << static_cast(value); return ss.str(); } // Converts the buffer in a stringstream to an std::string, converting NUL // bytes to "\\0" along the way. std::string StringStreamToString(::std::stringstream* ss) { const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); std::string result; result.reserve(2 * (end - start)); for (const char* ch = start; ch != end; ++ch) { if (*ch == '\0') { result += "\\0"; // Replaces NUL with "\\0"; } else { result += *ch; } } return result; } // Appends the user-supplied message to the Google-Test-generated message. std::string AppendUserMessage(const std::string& gtest_msg, const Message& user_msg) { // Appends the user message if it's non-empty. const std::string user_msg_string = user_msg.GetString(); if (user_msg_string.empty()) { return gtest_msg; } return gtest_msg + "\n" + user_msg_string; } } // namespace internal // class TestResult // Creates an empty TestResult. TestResult::TestResult() : death_test_count_(0), elapsed_time_(0) { } // D'tor. TestResult::~TestResult() { } // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. const TestPartResult& TestResult::GetTestPartResult(int i) const { if (i < 0 || i >= total_part_count()) internal::posix::Abort(); return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& TestResult::GetTestProperty(int i) const { if (i < 0 || i >= test_property_count()) internal::posix::Abort(); return test_properties_.at(i); } // Clears the test part results. void TestResult::ClearTestPartResults() { test_part_results_.clear(); } // Adds a test part result to the list. void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the // supplied property is already represented, the value of this test_property // replaces the old value for that key. void TestResult::RecordProperty(const std::string& xml_element, const TestProperty& test_property) { if (!ValidateTestProperty(xml_element, test_property)) { return; } internal::MutexLock lock(&test_properites_mutex_); const std::vector::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); if (property_with_matching_key == test_properties_.end()) { test_properties_.push_back(test_property); return; } property_with_matching_key->SetValue(test_property.value()); } // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { "disabled", "errors", "failures", "name", "random_seed", "tests", "time", "timestamp" }; // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuiteAttributes[] = { "disabled", "errors", "failures", "name", "tests", "time" }; // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param" }; template std::vector ArrayAsVector(const char* const (&array)[kSize]) { return std::vector(array, array + kSize); } static std::vector GetReservedAttributesForElement( const std::string& xml_element) { if (xml_element == "testsuites") { return ArrayAsVector(kReservedTestSuitesAttributes); } else if (xml_element == "testsuite") { return ArrayAsVector(kReservedTestSuiteAttributes); } else if (xml_element == "testcase") { return ArrayAsVector(kReservedTestCaseAttributes); } else { GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; } // This code is unreachable but some compilers may not realizes that. return std::vector(); } static std::string FormatWordList(const std::vector& words) { Message word_list; for (size_t i = 0; i < words.size(); ++i) { if (i > 0 && words.size() > 2) { word_list << ", "; } if (i == words.size() - 1) { word_list << "and "; } word_list << "'" << words[i] << "'"; } return word_list.GetString(); } bool ValidateTestPropertyName(const std::string& property_name, const std::vector& reserved_names) { if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != reserved_names.end()) { ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name << " (" << FormatWordList(reserved_names) << " are reserved by " << GTEST_NAME_ << ")"; return false; } return true; } // Adds a failure if the key is a reserved attribute of the element named // xml_element. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property) { return ValidateTestPropertyName(test_property.key(), GetReservedAttributesForElement(xml_element)); } // Clears the object. void TestResult::Clear() { test_part_results_.clear(); test_properties_.clear(); death_test_count_ = 0; elapsed_time_ = 0; } // Returns true iff the test failed. bool TestResult::Failed() const { for (int i = 0; i < total_part_count(); ++i) { if (GetTestPartResult(i).failed()) return true; } return false; } // Returns true iff the test part fatally failed. static bool TestPartFatallyFailed(const TestPartResult& result) { return result.fatally_failed(); } // Returns true iff the test fatally failed. bool TestResult::HasFatalFailure() const { return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. static bool TestPartNonfatallyFailed(const TestPartResult& result) { return result.nonfatally_failed(); } // Returns true iff the test has a non-fatal failure. bool TestResult::HasNonfatalFailure() const { return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int TestResult::total_part_count() const { return static_cast(test_part_results_.size()); } // Returns the number of the test properties. int TestResult::test_property_count() const { return static_cast(test_properties_.size()); } // class Test // Creates a Test object. // The c'tor saves the values of all Google Test flags. Test::Test() : gtest_flag_saver_(new internal::GTestFlagSaver) { } // The d'tor restores the values of all Google Test flags. Test::~Test() { delete gtest_flag_saver_; } // Sets up the test fixture. // // A sub-class may override this. void Test::SetUp() { } // Tears down the test fixture. // // A sub-class may override this. void Test::TearDown() { } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, const std::string& value) { UnitTest::GetInstance()->RecordProperty(key, value); } // Allows user supplied key value pairs to be recorded for later output. void Test::RecordProperty(const std::string& key, int value) { Message value_message; value_message << value; RecordProperty(key, value_message.GetString().c_str()); } namespace internal { void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message) { // This function is a friend of UnitTest and as such has access to // AddTestPartResult. UnitTest::GetInstance()->AddTestPartResult( result_type, NULL, // No info about the source file where the exception occurred. -1, // We have no info on which line caused the exception. message, ""); // No stack trace, either. } } // namespace internal // Google Test requires all tests in the same test case to use the same test // fixture class. This function checks if the current test has the // same fixture class as the first test in the current test case. If // yes, it returns true; otherwise it generates a Google Test failure and // returns false. bool Test::HasSameFixtureClass() { internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); const TestCase* const test_case = impl->current_test_case(); // Info about the first test in the current test case. const TestInfo* const first_test_info = test_case->test_info_list()[0]; const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; const char* const first_test_name = first_test_info->name(); // Info about the current test. const TestInfo* const this_test_info = impl->current_test_info(); const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; const char* const this_test_name = this_test_info->name(); if (this_fixture_id != first_fixture_id) { // Is the first test defined using TEST? const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); // Is this test defined using TEST? const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); if (first_is_TEST || this_is_TEST) { // Both TEST and TEST_F appear in same test case, which is incorrect. // Tell the user how to fix this. // Gets the name of the TEST and the name of the TEST_F. Note // that first_is_TEST and this_is_TEST cannot both be true, as // the fixture IDs are different for the two tests. const char* const TEST_name = first_is_TEST ? first_test_name : this_test_name; const char* const TEST_F_name = first_is_TEST ? this_test_name : first_test_name; ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class, so mixing TEST_F and TEST in the same test case is\n" << "illegal. In test case " << this_test_info->test_case_name() << ",\n" << "test " << TEST_F_name << " is defined using TEST_F but\n" << "test " << TEST_name << " is defined using TEST. You probably\n" << "want to change the TEST to TEST_F or move it to another test\n" << "case."; } else { // Two fixture classes with the same name appear in two different // namespaces, which is not allowed. Tell the user how to fix this. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << this_test_info->test_case_name() << ",\n" << "you defined test " << first_test_name << " and test " << this_test_name << "\n" << "using two different test fixture classes. This can happen if\n" << "the two classes are from different namespaces or translation\n" << "units and have the same name. You should probably rename one\n" << "of the classes to put the tests into different test cases."; } return false; } return true; } #if GTEST_HAS_SEH // Adds an "exception thrown" fatal failure to the current test. This // function returns its result via an output parameter pointer because VC++ // prohibits creation of objects with destructors on stack in functions // using __try (see error C2712). static std::string* FormatSehExceptionMessage(DWORD exception_code, const char* location) { Message message; message << "SEH exception with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " thrown in " << location << "."; return new std::string(message.GetString()); } #endif // GTEST_HAS_SEH namespace internal { #if GTEST_HAS_EXCEPTIONS // Adds an "exception thrown" fatal failure to the current test. static std::string FormatCxxExceptionMessage(const char* description, const char* location) { Message message; if (description != NULL) { message << "C++ exception with description \"" << description << "\""; } else { message << "Unknown C++ exception"; } message << " thrown in " << location << "."; return message.GetString(); } static std::string PrintTestPartResultToString( const TestPartResult& test_part_result); GoogleTestFailureException::GoogleTestFailureException( const TestPartResult& failure) : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} #endif // GTEST_HAS_EXCEPTIONS // We put these helper functions in the internal namespace as IBM's xlC // compiler rejects the code if they were declared static. // Runs the given method and handles SEH exceptions it throws, when // SEH is supported; returns the 0-value for type Result in case of an // SEH exception. (Microsoft compilers cannot handle SEH and C++ // exceptions in the same function. Therefore, we provide a separate // wrapper function for handling SEH exceptions.) template Result HandleSehExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { #if GTEST_HAS_SEH __try { return (object->*method)(); } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT GetExceptionCode())) { // We create the exception message on the heap because VC++ prohibits // creation of objects with destructors on stack in functions using __try // (see error C2712). std::string* exception_message = FormatSehExceptionMessage( GetExceptionCode(), location); internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, *exception_message); delete exception_message; return static_cast(0); } #else (void)location; return (object->*method)(); #endif // GTEST_HAS_SEH } // Runs the given method and catches and reports C++ and/or SEH-style // exceptions, if they are supported; returns the 0-value for type // Result in case of an SEH exception. template Result HandleExceptionsInMethodIfSupported( T* object, Result (T::*method)(), const char* location) { // NOTE: The user code can affect the way in which Google Test handles // exceptions by setting GTEST_FLAG(catch_exceptions), but only before // RUN_ALL_TESTS() starts. It is technically possible to check the flag // after the exception is caught and either report or re-throw the // exception based on the flag's value: // // try { // // Perform the test method. // } catch (...) { // if (GTEST_FLAG(catch_exceptions)) // // Report the exception as failure. // else // throw; // Re-throws the original exception. // } // // However, the purpose of this flag is to allow the program to drop into // the debugger when the exception is thrown. On most platforms, once the // control enters the catch block, the exception origin information is // lost and the debugger will stop the program at the point of the // re-throw in this function -- instead of at the point of the original // throw statement in the code under test. For this reason, we perform // the check early, sacrificing the ability to affect Google Test's // exception handling in the method where the exception is thrown. if (internal::GetUnitTestImpl()->catch_exceptions()) { #if GTEST_HAS_EXCEPTIONS try { return HandleSehExceptionsInMethodIfSupported(object, method, location); } catch (const internal::GoogleTestFailureException&) { // NOLINT // This exception type can only be thrown by a failed Google // Test assertion with the intention of letting another testing // framework catch it. Therefore we just re-throw it. throw; } catch (const std::exception& e) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(e.what(), location)); } catch (...) { // NOLINT internal::ReportFailureInUnknownLocation( TestPartResult::kFatalFailure, FormatCxxExceptionMessage(NULL, location)); } return static_cast(0); #else return HandleSehExceptionsInMethodIfSupported(object, method, location); #endif // GTEST_HAS_EXCEPTIONS } else { return (object->*method)(); } } } // namespace internal // Runs the test and updates the test result. void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); // We will run the test only if SetUp() was successful. if (!HasFatalFailure()) { impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TestBody, "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &Test::TearDown, "TearDown()"); } // Returns true iff the current test has a fatal failure. bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } // Returns true iff the current test has a non-fatal failure. bool Test::HasNonfatalFailure() { return internal::GetUnitTestImpl()->current_test_result()-> HasNonfatalFailure(); } // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory // object. TestInfo::TestInfo(const std::string& a_test_case_name, const std::string& a_name, const char* a_type_param, const char* a_value_param, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_case_name_(a_test_case_name), name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), value_param_(a_value_param ? new std::string(a_value_param) : NULL), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), matches_filter_(false), factory_(factory), result_() {} // Destructs a TestInfo object. TestInfo::~TestInfo() { delete factory_; } namespace internal { // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param: the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param: text representation of the test's value parameter, // or NULL if this is not a value-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = new TestInfo(test_case_name, name, type_param, value_param, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " << test_case_name << ", you tried\n" << "to define a test using a fixture class different from the one\n" << "used earlier. This can happen if the two fixture classes are\n" << "from different namespaces and have the same name. You should\n" << "probably rename one of the classes to put the tests into different\n" << "test cases."; fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST } // namespace internal namespace { // A predicate that checks the test name of a TestInfo against a known // value. // // This is used for implementation of the TestCase class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestNameIs is copyable. class TestNameIs { public: // Constructor. // // TestNameIs has NO default constructor. explicit TestNameIs(const char* name) : name_(name) {} // Returns true iff the test name of test_info matches name_. bool operator()(const TestInfo * test_info) const { return test_info && test_info->name() == name_; } private: std::string name_; }; } // namespace namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. void UnitTestImpl::RegisterParameterizedTests() { #if GTEST_HAS_PARAM_TEST if (!parameterized_tests_registered_) { parameterized_test_registry_.RegisterTests(); parameterized_tests_registered_ = true; } #endif } } // namespace internal // Creates the test object, runs it, records its result, and then // deletes it. void TestInfo::Run() { if (!should_run_) return; // Tells UnitTest where to store test result. internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); // Notifies the unit test event listeners that a test is about to start. repeater->OnTestStart(*this); const TimeInMillis start = internal::GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); // Creates the test object. Test* const test = internal::HandleExceptionsInMethodIfSupported( factory_, &internal::TestFactoryBase::CreateTest, "the test fixture's constructor"); // Runs the test only if the test object was created and its // constructor didn't generate a fatal failure. if ((test != NULL) && !Test::HasFatalFailure()) { // This doesn't throw as all user code that can throw are wrapped into // exception handling code. test->Run(); } // Deletes the test object. impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( test, &Test::DeleteSelf_, "the test fixture's destructor"); result_.set_elapsed_time(internal::GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. repeater->OnTestEnd(*this); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } // class TestCase // Gets the number of successful tests in this test case. int TestCase::successful_test_count() const { return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. int TestCase::failed_test_count() const { return CountIf(test_info_list_, TestFailed); } // Gets the number of disabled tests that will be reported in the XML report. int TestCase::reportable_disabled_test_count() const { return CountIf(test_info_list_, TestReportableDisabled); } // Gets the number of disabled tests in this test case. int TestCase::disabled_test_count() const { return CountIf(test_info_list_, TestDisabled); } // Gets the number of tests to be printed in the XML report. int TestCase::reportable_test_count() const { return CountIf(test_info_list_, TestReportable); } // Get the number of tests in this test case that should run. int TestCase::test_to_run_count() const { return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. int TestCase::total_test_count() const { return static_cast(test_info_list_.size()); } // Creates a TestCase with the given name. // // Arguments: // // name: name of the test case // a_type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase::TestCase(const char* a_name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) : name_(a_name), type_param_(a_type_param ? new std::string(a_type_param) : NULL), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), elapsed_time_(0) { } // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. ForEach(test_info_list_, internal::Delete); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* TestCase::GetTestInfo(int i) const { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* TestCase::GetMutableTestInfo(int i) { const int index = GetElementOr(test_indices_, i, -1); return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. void TestCase::AddTestInfo(TestInfo * test_info) { test_info_list_.push_back(test_info); test_indices_.push_back(static_cast(test_indices_.size())); } // Runs every test in this TestCase. void TestCase::Run() { if (!should_run_) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); impl->set_current_test_case(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); const internal::TimeInMillis start = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { GetMutableTestInfo(i)->Run(); } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); internal::HandleExceptionsInMethodIfSupported( this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { ad_hoc_test_result_.Clear(); ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. void TestCase::ShuffleTests(internal::Random* random) { Shuffle(random, &test_indices_); } // Restores the test order to before the first shuffle. void TestCase::UnshuffleTests() { for (size_t i = 0; i < test_indices_.size(); i++) { test_indices_[i] = static_cast(i); } } // Formats a countable noun. Depending on its quantity, either the // singular form or the plural form is used. e.g. // // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". static std::string FormatCountableNoun(int count, const char * singular_form, const char * plural_form) { return internal::StreamableToString(count) + " " + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. static std::string FormatTestCount(int test_count) { return FormatCountableNoun(test_count, "test", "tests"); } // Formats the count of test cases. static std::string FormatTestCaseCount(int test_case_count) { return FormatCountableNoun(test_case_count, "test case", "test cases"); } // Converts a TestPartResult::Type enum to human-friendly string // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. static const char * TestPartResultTypeToString(TestPartResult::Type type) { switch (type) { case TestPartResult::kSuccess: return "Success"; case TestPartResult::kNonFatalFailure: case TestPartResult::kFatalFailure: #ifdef _MSC_VER return "error: "; #else return "Failure\n"; #endif default: return "Unknown result type"; } } namespace internal { // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( const TestPartResult& test_part_result) { return (Message() << internal::FormatFileLocation(test_part_result.file_name(), test_part_result.line_number()) << " " << TestPartResultTypeToString(test_part_result.type()) << test_part_result.message()).GetString(); } // Prints a TestPartResult. static void PrintTestPartResult(const TestPartResult& test_part_result) { const std::string& result = PrintTestPartResultToString(test_part_result); printf("%s\n", result.c_str()); fflush(stdout); // If the test program runs in Visual Studio or a debugger, the // following statements add the test part result message to the Output // window such that the user can double-click on it to jump to the // corresponding source code location; otherwise they do nothing. #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // We don't call OutputDebugString*() on Windows Mobile, as printing // to stdout is done by OutputDebugString() there already - we don't // want the same message printed twice. ::OutputDebugStringA(result.c_str()); ::OutputDebugStringA("\n"); #endif } // class PrettyUnitTestResultPrinter enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { switch (color) { case COLOR_RED: return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN; case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } #else // Returns the ANSI color code for the given color. COLOR_DEFAULT is // an invalid input. const char* GetAnsiColorCode(GTestColor color) { switch (color) { case COLOR_RED: return "1"; case COLOR_GREEN: return "2"; case COLOR_YELLOW: return "3"; default: return NULL; }; } #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. bool ShouldUseColor(bool stdout_is_tty) { const char* const gtest_color = GTEST_FLAG(color).c_str(); if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { #if GTEST_OS_WINDOWS // On Windows the TERM variable is usually not set, but the // console there does support colors. return stdout_is_tty; #else // On non-Windows platforms, we rely on the TERM variable. const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS } return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || String::CaseInsensitiveCStringEquals(gtest_color, "true") || String::CaseInsensitiveCStringEquals(gtest_color, "t") || String::CStringEquals(gtest_color, "1"); // We take "yes", "true", "t", and "1" as meaning "yes". If the // value is neither one of these nor "auto", we treat it as "no" to // be conservative. } // Helpers for printing colored strings to stdout. Note that on Windows, we // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \ GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT const bool use_color = AlwaysFalse(); #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); const bool use_color = in_color_mode && (color != COLOR_DEFAULT); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS // The '!= 0' comparison is necessary to satisfy MSVC 7.1. if (!use_color) { vprintf(fmt, args); va_end(args); return; } #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. CONSOLE_SCREEN_BUFFER_INFO buffer_info; GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); const WORD old_color_attrs = buffer_info.wAttributes; // We need to flush the stream buffers into the console before each // SetConsoleTextAttribute call lest it affect the text that is already // printed but has not yet reached the console. fflush(stdout); SetConsoleTextAttribute(stdout_handle, GetColorAttribute(color) | FOREGROUND_INTENSITY); vprintf(fmt, args); fflush(stdout); // Restores the text color. SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else printf("\033[0;3%sm", GetAnsiColorCode(color)); vprintf(fmt, args); printf("\033[m"); // Resets the terminal to default. #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE va_end(args); } // Text printed in Google Test's text output and --gunit_list_tests // output to label the type parameter and value parameter for a test. static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; void PrintFullTestCommentIfPresent(const TestInfo& test_info) { const char* const type_param = test_info.type_param(); const char* const value_param = test_info.value_param(); if (type_param != NULL || value_param != NULL) { printf(", where "); if (type_param != NULL) { printf("%s = %s", kTypeParamLabel, type_param); if (value_param != NULL) printf(" and "); } if (value_param != NULL) { printf("%s = %s", kValueParamLabel, value_param); } } } // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. class PrettyUnitTestResultPrinter : public TestEventListener { public: PrettyUnitTestResultPrinter() {} static void PrintTestName(const char * test_case, const char * test) { printf("%s.%s", test_case, test); } // The following methods override what's in the TestEventListener class. virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} private: static void PrintFailedTests(const UnitTest& unit_test); }; // Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( const UnitTest& unit_test, int iteration) { if (GTEST_FLAG(repeat) != 1) printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); const char* const filter = GTEST_FLAG(filter).c_str(); // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { ColoredPrintf(COLOR_YELLOW, "Note: %s filter = %s\n", GTEST_NAME_, filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); ColoredPrintf(COLOR_YELLOW, "Note: This is test shard %d of %s.\n", static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { ColoredPrintf(COLOR_YELLOW, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } ColoredPrintf(COLOR_GREEN, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == NULL) { printf("\n"); } else { printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_info.test_case_name(), test_info.name()); printf("\n"); fflush(stdout); } // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( const TestPartResult& result) { // If the test part succeeded, we don't need to do anything. if (result.type() == TestPartResult::kSuccess) return; // Print failure message from the assertion (e.g. expected this and got that). PrintTestPartResult(result); fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { ColoredPrintf(COLOR_GREEN, "[ OK ] "); } else { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } PrintTestName(test_info.test_case_name(), test_info.name()); if (test_info.result()->Failed()) PrintFullTestCommentIfPresent(test_info); if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( test_info.result()->elapsed_time()).c_str()); } else { printf("\n"); } fflush(stdout); } void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { if (!GTEST_FLAG(print_time)) return; const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { ColoredPrintf(COLOR_GREEN, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); if (failed_test_count == 0) { return; } for (int i = 0; i < unit_test.total_test_case_count(); ++i) { const TestCase& test_case = *unit_test.GetTestCase(i); if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { continue; } for (int j = 0; j < test_case.total_test_count(); ++j) { const TestInfo& test_info = *test_case.GetTestInfo(j); if (!test_info.should_run() || test_info.result()->Passed()) { continue; } ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s.%s", test_case.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); } } } void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); if (GTEST_FLAG(print_time)) { printf(" (%s ms total)", internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); int num_failures = unit_test.failed_test_count(); if (!unit_test.Passed()) { const int failed_test_count = unit_test.failed_test_count(); ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); PrintFailedTests(unit_test); printf("\n%2d FAILED %s\n", num_failures, num_failures == 1 ? "TEST" : "TESTS"); } int num_disabled = unit_test.reportable_disabled_test_count(); if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { if (!num_failures) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } ColoredPrintf(COLOR_YELLOW, " YOU HAVE %d DISABLED %s\n\n", num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); } // Ensure that Google Test output is printed before, e.g., heapchecker output. fflush(stdout); } // End PrettyUnitTestResultPrinter // class TestEventRepeater // // This class forwards events to other event listeners. class TestEventRepeater : public TestEventListener { public: TestEventRepeater() : forwarding_enabled_(true) {} virtual ~TestEventRepeater(); void Append(TestEventListener *listener); TestEventListener* Release(TestEventListener* listener); // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled() const { return forwarding_enabled_; } void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } virtual void OnTestProgramStart(const UnitTest& unit_test); virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); virtual void OnTestCaseStart(const TestCase& test_case); virtual void OnTestStart(const TestInfo& test_info); virtual void OnTestPartResult(const TestPartResult& result); virtual void OnTestEnd(const TestInfo& test_info); virtual void OnTestCaseEnd(const TestCase& test_case); virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); virtual void OnTestProgramEnd(const UnitTest& unit_test); private: // Controls whether events will be forwarded to listeners_. Set to false // in death test child processes. bool forwarding_enabled_; // The list of listeners that receive events. std::vector listeners_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; TestEventRepeater::~TestEventRepeater() { ForEach(listeners_, Delete); } void TestEventRepeater::Append(TestEventListener *listener) { listeners_.push_back(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { for (size_t i = 0; i < listeners_.size(); ++i) { if (listeners_[i] == listener) { listeners_.erase(listeners_.begin() + i); return listener; } } return NULL; } // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. #define GTEST_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (size_t i = 0; i < listeners_.size(); i++) { \ listeners_[i]->Name(parameter); \ } \ } \ } // This defines a member that forwards the call to all listeners in reverse // order. #define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ void TestEventRepeater::Name(const Type& parameter) { \ if (forwarding_enabled_) { \ for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ listeners_[i]->Name(parameter); \ } \ } \ } GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REPEATER_METHOD_ #undef GTEST_REVERSE_REPEATER_METHOD_ void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (size_t i = 0; i < listeners_.size(); i++) { listeners_[i]->OnTestIterationStart(unit_test, iteration); } } } void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, int iteration) { if (forwarding_enabled_) { for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { listeners_[i]->OnTestIterationEnd(unit_test, iteration); } } } // End TestEventRepeater // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: explicit XmlUnitTestResultPrinter(const char* output_file); virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); private: // Is c a whitespace character that is normalized to a space character // when it appears in an XML attribute value? static bool IsNormalizableWhitespace(char c) { return c == 0x9 || c == 0xA || c == 0xD; } // May c appear in a well-formed XML document? static bool IsValidXmlCharacter(char c) { return IsNormalizableWhitespace(c) || c >= 0x20; } // Returns an XML-escaped copy of the input string str. If // is_attribute is true, the text is meant to appear as an attribute // value, and normalizable whitespace is preserved by replacing it // with character references. static std::string EscapeXml(const std::string& str, bool is_attribute); // Returns the given string with all characters invalid in XML removed. static std::string RemoveInvalidXmlCharacters(const std::string& str); // Convenience wrapper around EscapeXml when str is an attribute value. static std::string EscapeXmlAttribute(const std::string& str) { return EscapeXml(str, true); } // Convenience wrapper around EscapeXml when str is not an attribute value. static std::string EscapeXmlText(const char* str) { return EscapeXml(str, false); } // Verifies that the given attribute belongs to the given element and // streams the attribute as XML. static void OutputXmlAttribute(std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value); // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. static void OutputXmlCDataSection(::std::ostream* stream, const char* data); // Streams an XML representation of a TestInfo object. static void OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info); // Prints an XML representation of a TestCase object static void PrintXmlTestCase(::std::ostream* stream, const TestCase& test_case); // Prints an XML summary of unit_test to output stream out. static void PrintXmlUnitTest(::std::ostream* stream, const UnitTest& unit_test); // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. // When the std::string is not empty, it includes a space at the beginning, // to delimit this attribute from prior attributes. static std::string TestPropertiesAsXmlAttributes(const TestResult& result); // The output file. const std::string output_file_; GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) : output_file_(output_file) { if (output_file_.c_str() == NULL || output_file_.empty()) { fprintf(stderr, "XML output file may not be null\n"); fflush(stderr); exit(EXIT_FAILURE); } } // Called after the unit test ends. void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { FILE* xmlout = NULL; FilePath output_file(output_file_); FilePath output_dir(output_file.RemoveFileName()); if (output_dir.CreateDirectoriesRecursively()) { xmlout = posix::FOpen(output_file_.c_str(), "w"); } if (xmlout == NULL) { // TODO(wan): report the reason of the failure. // // We don't do it for now as: // // 1. There is no urgent need for it. // 2. It's a bit involved to make the errno variable thread-safe on // all three operating systems (Linux, Windows, and Mac OS). // 3. To interpret the meaning of errno in a thread-safe way, // we need the strerror_r() function, which is not available on // Windows. fprintf(stderr, "Unable to open file \"%s\"\n", output_file_.c_str()); fflush(stderr); exit(EXIT_FAILURE); } std::stringstream stream; PrintXmlUnitTest(&stream, unit_test); fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); fclose(xmlout); } // Returns an XML-escaped copy of the input string str. If is_attribute // is true, the text is meant to appear as an attribute value, and // normalizable whitespace is preserved by replacing it with character // references. // // Invalid XML characters in str, if any, are stripped from the output. // It is expected that most, if not all, of the text processed by this // module will consist of ordinary English text. // If this module is ever modified to produce version 1.1 XML output, // most invalid characters can be retained using character references. // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. std::string XmlUnitTestResultPrinter::EscapeXml( const std::string& str, bool is_attribute) { Message m; for (size_t i = 0; i < str.size(); ++i) { const char ch = str[i]; switch (ch) { case '<': m << "<"; break; case '>': m << ">"; break; case '&': m << "&"; break; case '\'': if (is_attribute) m << "'"; else m << '\''; break; case '"': if (is_attribute) m << """; else m << '"'; break; default: if (IsValidXmlCharacter(ch)) { if (is_attribute && IsNormalizableWhitespace(ch)) m << "&#x" << String::FormatByte(static_cast(ch)) << ";"; else m << ch; } break; } } return m.GetString(); } // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( const std::string& str) { std::string output; output.reserve(str.size()); for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) if (IsValidXmlCharacter(*it)) output.push_back(*it); return output; } // The following routines generate an XML representation of a UnitTest // object. // // This is how Google Test concepts map to the DTD: // // <-- corresponds to a UnitTest object // <-- corresponds to a TestCase object // <-- corresponds to a TestInfo object // ... // ... // ... // <-- individual assertion failures // // // // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; ss << ms/1000.0; return ss.str(); } static bool PortableLocaltime(time_t seconds, struct tm* out) { #if defined(_MSC_VER) return localtime_s(out, &seconds) == 0; #elif defined(__MINGW32__) || defined(__MINGW64__) // MINGW provides neither localtime_r nor localtime_s, but uses // Windows' localtime(), which has a thread-local tm buffer. struct tm* tm_ptr = localtime(&seconds); // NOLINT if (tm_ptr == NULL) return false; *out = *tm_ptr; return true; #else return localtime_r(&seconds, out) != NULL; #endif } // Converts the given epoch time in milliseconds to a date string in the ISO // 8601 format, without the timezone information. std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { struct tm time_struct; if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) return ""; // YYYY-MM-DDThh:mm:ss return StreamableToString(time_struct.tm_year + 1900) + "-" + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + String::FormatIntWidth2(time_struct.tm_mday) + "T" + String::FormatIntWidth2(time_struct.tm_hour) + ":" + String::FormatIntWidth2(time_struct.tm_min) + ":" + String::FormatIntWidth2(time_struct.tm_sec); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, const char* data) { const char* segment = data; *stream << ""); if (next_segment != NULL) { stream->write( segment, static_cast(next_segment - segment)); *stream << "]]>]]>"); } else { *stream << segment; break; } } *stream << "]]>"; } void XmlUnitTestResultPrinter::OutputXmlAttribute( std::ostream* stream, const std::string& element_name, const std::string& name, const std::string& value) { const std::vector& allowed_names = GetReservedAttributesForElement(element_name); GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != allowed_names.end()) << "Attribute " << name << " is not allowed for element <" << element_name << ">."; *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const char* test_case_name, const TestInfo& test_info) { const TestResult& result = *test_info.result(); const std::string kTestcase = "testcase"; *stream << " \n"; } const string location = internal::FormatCompilerIndependentFileLocation( part.file_name(), part.line_number()); const string summary = location + "\n" + part.summary(); *stream << " "; const string detail = location + "\n" + part.message(); OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); *stream << "\n"; } } if (failures == 0) *stream << " />\n"; else *stream << " \n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, const TestCase& test_case) { const std::string kTestsuite = "testsuite"; *stream << " <" << kTestsuite; OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); OutputXmlAttribute(stream, kTestsuite, "tests", StreamableToString(test_case.reportable_test_count())); OutputXmlAttribute(stream, kTestsuite, "failures", StreamableToString(test_case.failed_test_count())); OutputXmlAttribute( stream, kTestsuite, "disabled", StreamableToString(test_case.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuite, "errors", "0"); OutputXmlAttribute(stream, kTestsuite, "time", FormatTimeInMillisAsSeconds(test_case.elapsed_time())); *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) << ">\n"; for (int i = 0; i < test_case.total_test_count(); ++i) { if (test_case.GetTestInfo(i)->is_reportable()) OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); } *stream << " \n"; } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, const UnitTest& unit_test) { const std::string kTestsuites = "testsuites"; *stream << "\n"; *stream << "<" << kTestsuites; OutputXmlAttribute(stream, kTestsuites, "tests", StreamableToString(unit_test.reportable_test_count())); OutputXmlAttribute(stream, kTestsuites, "failures", StreamableToString(unit_test.failed_test_count())); OutputXmlAttribute( stream, kTestsuites, "disabled", StreamableToString(unit_test.reportable_disabled_test_count())); OutputXmlAttribute(stream, kTestsuites, "errors", "0"); OutputXmlAttribute( stream, kTestsuites, "timestamp", FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); OutputXmlAttribute(stream, kTestsuites, "time", FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); if (GTEST_FLAG(shuffle)) { OutputXmlAttribute(stream, kTestsuites, "random_seed", StreamableToString(unit_test.random_seed())); } *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); *stream << ">\n"; for (int i = 0; i < unit_test.total_test_case_count(); ++i) { if (unit_test.GetTestCase(i)->reportable_test_count() > 0) PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); } *stream << "\n"; } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( const TestResult& result) { Message attributes; for (int i = 0; i < result.test_property_count(); ++i) { const TestProperty& property = result.GetTestProperty(i); attributes << " " << property.key() << "=" << "\"" << EscapeXmlAttribute(property.value()) << "\""; } return attributes.GetString(); } // End XmlUnitTestResultPrinter #if GTEST_CAN_STREAM_RESULTS_ // Checks if str contains '=', '&', '%' or '\n' characters. If yes, // replaces them by "%xx" where xx is their hexadecimal value. For // example, replaces "=" with "%3D". This algorithm is O(strlen(str)) // in both time and space -- important as the input str may contain an // arbitrarily long test failure message and stack trace. string StreamingListener::UrlEncode(const char* str) { string result; result.reserve(strlen(str) + 1); for (char ch = *str; ch != '\0'; ch = *++str) { switch (ch) { case '%': case '=': case '&': case '\n': result.append("%" + String::FormatByte(static_cast(ch))); break; default: result.push_back(ch); break; } } return result; } void StreamingListener::SocketWriter::MakeConnection() { GTEST_CHECK_(sockfd_ == -1) << "MakeConnection() can't be called when there is already a connection."; addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. hints.ai_socktype = SOCK_STREAM; addrinfo* servinfo = NULL; // Use the getaddrinfo() to get a linked list of IP addresses for // the given host name. const int error_num = getaddrinfo( host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); if (error_num != 0) { GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " << gai_strerror(error_num); } // Loop through all the results and connect to the first we can. for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; cur_addr = cur_addr->ai_next) { sockfd_ = socket( cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); if (sockfd_ != -1) { // Connect the client socket to the server socket. if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { close(sockfd_); sockfd_ = -1; } } } freeaddrinfo(servinfo); // all done with this structure if (sockfd_ == -1) { GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " << host_name_ << ":" << port_num_; } } // End of class Streaming Listener #endif // GTEST_CAN_STREAM_RESULTS__ // Class ScopedTrace // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { TraceInfo trace; trace.file = file; trace.line = line; trace.message = message.GetString(); UnitTest::GetInstance()->PushGTestTrace(trace); } // Pops the info pushed by the c'tor. ScopedTrace::~ScopedTrace() GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { UnitTest::GetInstance()->PopGTestTrace(); } // class OsStackTraceGetter // Returns the current OS stack trace as an std::string. Parameters: // // max_depth - the maximum number of stack frames to be included // in the trace. // skip_count - the number of top frames to be skipped; doesn't count // against max_depth. // string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, int /* skip_count */) GTEST_LOCK_EXCLUDED_(mutex_) { return ""; } void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { } const char* const OsStackTraceGetter::kElidedFramesMarker = "... " GTEST_NAME_ " internal frames ..."; // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { public: explicit ScopedPrematureExitFile(const char* premature_exit_filepath) : premature_exit_filepath_(premature_exit_filepath) { // If a path to the premature-exit file is specified... if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { // create the file with a single "0" character in it. I/O // errors are ignored as there's nothing better we can do and we // don't want to fail the test because of this. FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); fwrite("0", 1, 1, pfile); fclose(pfile); } } ~ScopedPrematureExitFile() { if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { remove(premature_exit_filepath_); } } private: const char* const premature_exit_filepath_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; } // namespace internal // class TestEventListeners TestEventListeners::TestEventListeners() : repeater_(new internal::TestEventRepeater()), default_result_printer_(NULL), default_xml_generator_(NULL) { } TestEventListeners::~TestEventListeners() { delete repeater_; } // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the user. void TestEventListeners::Append(TestEventListener* listener) { repeater_->Append(listener); } // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* TestEventListeners::Release(TestEventListener* listener) { if (listener == default_result_printer_) default_result_printer_ = NULL; else if (listener == default_xml_generator_) default_xml_generator_ = NULL; return repeater_->Release(listener); } // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* TestEventListeners::repeater() { return repeater_; } // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { if (default_result_printer_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_result_printer_); default_result_printer_ = listener; if (listener != NULL) Append(listener); } } // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { if (default_xml_generator_ != listener) { // It is an error to pass this method a listener that is already in the // list. delete Release(default_xml_generator_); default_xml_generator_ = listener; if (listener != NULL) Append(listener); } } // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool TestEventListeners::EventForwardingEnabled() const { return repeater_->forwarding_enabled(); } void TestEventListeners::SuppressEventForwarding() { repeater_->set_forwarding_enabled(false); } // class UnitTest // Gets the singleton UnitTest object. The first time this method is // called, a UnitTest object is constructed and returned. Consecutive // calls will return the same object. // // We don't protect this under mutex_ as a user is not supposed to // call this before main() starts, from which point on the return // value will never change. UnitTest* UnitTest::GetInstance() { // When compiled with MSVC 7.1 in optimized mode, destroying the // UnitTest object upon exiting the program messes up the exit code, // causing successful tests to appear failed. We have to use a // different implementation in this case to bypass the compiler bug. // This implementation makes the compiler happy, at the cost of // leaking the UnitTest object. // CodeGear C++Builder insists on a public destructor for the // default implementation. Use this implementation to keep good OO // design with private destructor. #if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) static UnitTest* const instance = new UnitTest; return instance; #else static UnitTest instance; return &instance; #endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Gets the number of successful test cases. int UnitTest::successful_test_case_count() const { return impl()->successful_test_case_count(); } // Gets the number of failed test cases. int UnitTest::failed_test_case_count() const { return impl()->failed_test_case_count(); } // Gets the number of all test cases. int UnitTest::total_test_case_count() const { return impl()->total_test_case_count(); } // Gets the number of all test cases that contain at least one test // that should run. int UnitTest::test_case_to_run_count() const { return impl()->test_case_to_run_count(); } // Gets the number of successful tests. int UnitTest::successful_test_count() const { return impl()->successful_test_count(); } // Gets the number of failed tests. int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } // Gets the number of disabled tests that will be reported in the XML report. int UnitTest::reportable_disabled_test_count() const { return impl()->reportable_disabled_test_count(); } // Gets the number of disabled tests. int UnitTest::disabled_test_count() const { return impl()->disabled_test_count(); } // Gets the number of tests to be printed in the XML report. int UnitTest::reportable_test_count() const { return impl()->reportable_test_count(); } // Gets the number of all tests. int UnitTest::total_test_count() const { return impl()->total_test_count(); } // Gets the number of tests that should run. int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. internal::TimeInMillis UnitTest::start_timestamp() const { return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. internal::TimeInMillis UnitTest::elapsed_time() const { return impl()->elapsed_time(); } // Returns true iff the unit test passed (i.e. all test cases passed). bool UnitTest::Passed() const { return impl()->Passed(); } // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool UnitTest::Failed() const { return impl()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* UnitTest::GetTestCase(int i) const { return impl()->GetTestCase(i); } // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& UnitTest::ad_hoc_test_result() const { return *impl()->ad_hoc_test_result(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* UnitTest::GetMutableTestCase(int i) { return impl()->GetMutableTestCase(i); } // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& UnitTest::listeners() { return *impl()->listeners(); } // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in the // order they were registered. After all tests in the program have // finished, all global test environments will be torn-down in the // *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // We don't protect this under mutex_, as we only support calling it // from the main thread. Environment* UnitTest::AddEnvironment(Environment* env) { if (env == NULL) { return NULL; } impl_->environments().push_back(env); return env; } // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the // assertion macros instead of calling this directly. void UnitTest::AddTestPartResult( TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { Message msg; msg << message; internal::MutexLock lock(&mutex_); if (impl_->gtest_trace_stack().size() > 0) { msg << "\n" << GTEST_NAME_ << " trace:"; for (int i = static_cast(impl_->gtest_trace_stack().size()); i > 0; --i) { const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) << " " << trace.message; } } if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { msg << internal::kStackTraceMarker << os_stack_trace; } const TestPartResult result = TestPartResult(result_type, file_name, line_number, msg.GetString().c_str()); impl_->GetTestPartResultReporterForCurrentThread()-> ReportTestPartResult(result); if (result_type != TestPartResult::kSuccess) { // gtest_break_on_failure takes precedence over // gtest_throw_on_failure. This allows a user to set the latter // in the code (perhaps in order to use Google Test assertions // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Using DebugBreak on Windows allows gtest to still break into a debugger // when a failure happens and both the --gtest_break_on_failure and // the --gtest_catch_exceptions flags are specified. DebugBreak(); #else // Dereference NULL through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for // portability: Symbian doesn't implement abort() well, and some debuggers // don't correctly trap abort(). *static_cast(NULL) = 1; #endif // GTEST_OS_WINDOWS } else if (GTEST_FLAG(throw_on_failure)) { #if GTEST_HAS_EXCEPTIONS throw internal::GoogleTestFailureException(result); #else // We cannot call abort() as it generates a pop-up in debug mode // that cannot be suppressed in VC 7.1 or below. exit(1); #endif } } } // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void UnitTest::RecordProperty(const std::string& key, const std::string& value) { impl_->RecordProperty(TestProperty(key, value)); } // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { const bool in_death_test_child_process = internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Google Test implements this protocol for catching that a test // program exits before returning control to Google Test: // // 1. Upon start, Google Test creates a file whose absolute path // is specified by the environment variable // TEST_PREMATURE_EXIT_FILE. // 2. When Google Test has finished its work, it deletes the file. // // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before // running a Google-Test-based test program and check the existence // of the file at the end of the test execution to see if it has // exited prematurely. // If we are in the child process of a death test, don't // create/delete the premature exit file, as doing so is unnecessary // and will confuse the parent process. Otherwise, create/delete // the file upon entering/leaving this function. If the program // somehow exits before this function has a chance to return, the // premature-exit file will be left undeleted, causing a test runner // that understands the premature-exit-file protocol to report the // test as having failed. const internal::ScopedPrematureExitFile premature_exit_file( in_death_test_child_process ? NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); #if GTEST_HAS_SEH // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs // about crashes - they are expected. if (impl()->catch_exceptions() || in_death_test_child_process) { # if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); # endif // !GTEST_OS_WINDOWS_MOBILE # if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); # endif # if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement // executed. Google Test will notify the user of any unexpected // failure via stderr. // // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. // Users of prior VC versions shall suffer the agony and pain of // clicking through the countless debug dialogs. // TODO(vladl@google.com): find a way to suppress the abort dialog() in the // debug mode when compiled with VC 7.1 or lower. if (!GTEST_FLAG(break_on_failure)) _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. # endif } #endif // GTEST_HAS_SEH return internal::HandleExceptionsInMethodIfSupported( impl(), &internal::UnitTestImpl::RunAllTests, "auxiliary test code (environments or event listeners)") ? 0 : 1; } // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* UnitTest::current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); return impl_->current_test_info(); } // Returns the random seed used at the start of the current test run. int UnitTest::random_seed() const { return impl_->random_seed(); } #if GTEST_HAS_PARAM_TEST // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) { return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST // Creates an empty UnitTest. UnitTest::UnitTest() { impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. UnitTest::~UnitTest() { delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_) { internal::MutexLock lock(&mutex_); impl_->gtest_trace_stack().pop_back(); } namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), #if GTEST_HAS_PARAM_TEST parameterized_test_registry_(), parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST last_death_test_case_(-1), current_test_case_(NULL), current_test_info_(NULL), ad_hoc_test_result_(), os_stack_trace_getter_(NULL), post_flag_parse_init_performed_(false), random_seed_(0), // Will be overridden by the flag before first use. random_(0), // Will be reseeded before first use. start_timestamp_(0), elapsed_time_(0), #if GTEST_HAS_DEATH_TEST death_test_factory_(new DefaultDeathTestFactory), #endif // Will be overridden by the flag before first use. catch_exceptions_(false) { listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. ForEach(test_cases_, internal::Delete); // Deletes every Environment. ForEach(environments_, internal::Delete); delete os_stack_trace_getter_; } // Adds a TestProperty to the current TestResult object when invoked in a // context of a test, to current test case's ad_hoc_test_result when invoke // from SetUpTestCase/TearDownTestCase, or to the global property set // otherwise. If the result already contains a property with the same key, // the value will be updated. void UnitTestImpl::RecordProperty(const TestProperty& test_property) { std::string xml_element; TestResult* test_result; // TestResult appropriate for property recording. if (current_test_info_ != NULL) { xml_element = "testcase"; test_result = &(current_test_info_->result_); } else if (current_test_case_ != NULL) { xml_element = "testsuite"; test_result = &(current_test_case_->ad_hoc_test_result_); } else { xml_element = "testsuites"; test_result = &ad_hoc_test_result_; } test_result->RecordProperty(xml_element, test_property); } #if GTEST_HAS_DEATH_TEST // Disables event forwarding if the control is currently in a death test // subprocess. Must not be called before InitGoogleTest. void UnitTestImpl::SuppressTestEventsIfInSubprocess() { if (internal_run_death_test_flag_.get() != NULL) listeners()->SuppressEventForwarding(); } #endif // GTEST_HAS_DEATH_TEST // Initializes event listeners performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); } else if (output_format != "") { printf("WARNING: unrecognized output format \"%s\" ignored.\n", output_format.c_str()); fflush(stdout); } } #if GTEST_CAN_STREAM_RESULTS_ // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureStreamingOutput() { const std::string& target = GTEST_FLAG(stream_result_to); if (!target.empty()) { const size_t pos = target.find(':'); if (pos != std::string::npos) { listeners()->Append(new StreamingListener(target.substr(0, pos), target.substr(pos+1))); } else { printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", target.c_str()); fflush(stdout); } } } #endif // GTEST_CAN_STREAM_RESULTS_ // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. void UnitTestImpl::PostFlagParsingInit() { // Ensures that this function does not execute more than once. if (!post_flag_parse_init_performed_) { post_flag_parse_init_performed_ = true; #if GTEST_HAS_DEATH_TEST InitDeathTestSubprocessControlInfo(); SuppressTestEventsIfInSubprocess(); #endif // GTEST_HAS_DEATH_TEST // Registers parameterized tests. This makes parameterized tests // available to the UnitTest reflection API without running // RUN_ALL_TESTS. RegisterParameterizedTests(); // Configures listeners for XML output. This makes it possible for users // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ // Configures listeners for streaming test results to the specified server. ConfigureStreamingOutput(); #endif // GTEST_CAN_STREAM_RESULTS_ } } // A predicate that checks the name of a TestCase against a known // value. // // This is used for implementation of the UnitTest class only. We put // it in the anonymous namespace to prevent polluting the outer // namespace. // // TestCaseNameIs is copyable. class TestCaseNameIs { public: // Constructor. explicit TestCaseNameIs(const std::string& name) : name_(name) {} // Returns true iff the name of test_case matches name_. bool operator()(const TestCase* test_case) const { return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; } private: std::string name_; }; // Finds and returns a TestCase with the given name. If one doesn't // exist, creates one and returns it. It's the CALLER'S // RESPONSIBILITY to ensure that this function is only called WHEN THE // TESTS ARE NOT SHUFFLED. // // Arguments: // // test_case_name: name of the test case // type_param: the name of the test case's type parameter, or NULL if // this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? const std::vector::const_iterator test_case = std::find_if(test_cases_.begin(), test_cases_.end(), TestCaseNameIs(test_case_name)); if (test_case != test_cases_.end()) return *test_case; // No. Let's create one. TestCase* const new_test_case = new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); // Is this a death test case? if (internal::UnitTestOptions::MatchesFilter(test_case_name, kDeathTestCaseFilter)) { // Yes. Inserts the test case after the last death test case // defined so far. This only works when the test cases haven't // been shuffled. Otherwise we may end up running a death test // after a non-death test. ++last_death_test_case_; test_cases_.insert(test_cases_.begin() + last_death_test_case_, new_test_case); } else { // No. Appends to the end of the list. test_cases_.push_back(new_test_case); } test_case_indices_.push_back(static_cast(test_case_indices_.size())); return new_test_case; } // Helpers for setting up / tearing down the given environment. They // are for use in the ForEach() function. static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } // Runs all tests in this UnitTest object, prints the result, and // returns true if all tests are successful. If any exception is // thrown during a test, the test is considered to be failed, but the // rest of the tests will still be run. // // When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. bool UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { printf("%s", "\nThis test program did NOT call ::testing::InitGoogleTest " "before calling RUN_ALL_TESTS(). Please fix it.\n"); return false; } // Do not run any test if the --help flag was specified. if (g_help_flag) return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. PostFlagParsingInit(); // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); // True iff we are in a subprocess for running a thread-safe-style // death test. bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, in_subprocess_for_death_test); // Compares the full test names with the filter to decide which // tests to run. const bool has_tests_to_run = FilterTests(should_shard ? HONOR_SHARDING_PROTOCOL : IGNORE_SHARDING_PROTOCOL) > 0; // Lists the tests and exits if the --gtest_list_tests flag was specified. if (GTEST_FLAG(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); return true; } random_seed_ = GTEST_FLAG(shuffle) ? GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; // True iff at least one test has failed. bool failed = false; TestEventListener* repeater = listeners()->repeater(); start_timestamp_ = GetTimeInMillis(); repeater->OnTestProgramStart(*parent_); // How many times to repeat the tests? We don't want to repeat them // when we are inside the subprocess of a death test. const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { // We want to preserve failures generated by ad-hoc test // assertions executed before RUN_ALL_TESTS(). ClearNonAdHocTestResult(); const TimeInMillis start = GetTimeInMillis(); // Shuffles test cases and tests if requested. if (has_tests_to_run && GTEST_FLAG(shuffle)) { random()->Reseed(random_seed_); // This should be done before calling OnTestIterationStart(), // such that a test event listener can see the actual test order // in the event. ShuffleTests(); } // Tells the unit test event listeners that the tests are about to start. repeater->OnTestIterationStart(*parent_, i); // Runs each test case if there is at least one test to run. if (has_tests_to_run) { // Sets up all environments beforehand. repeater->OnEnvironmentsSetUpStart(*parent_); ForEach(environments_, SetUpEnvironment); repeater->OnEnvironmentsSetUpEnd(*parent_); // Runs the tests only if there was no fatal failure during global // set-up. if (!Test::HasFatalFailure()) { for (int test_index = 0; test_index < total_test_case_count(); test_index++) { GetMutableTestCase(test_index)->Run(); } } // Tears down all environments in reverse order afterwards. repeater->OnEnvironmentsTearDownStart(*parent_); std::for_each(environments_.rbegin(), environments_.rend(), TearDownEnvironment); repeater->OnEnvironmentsTearDownEnd(*parent_); } elapsed_time_ = GetTimeInMillis() - start; // Tells the unit test event listener that the tests have just finished. repeater->OnTestIterationEnd(*parent_, i); // Gets the result and clears it. if (!Passed()) { failed = true; } // Restores the original test order after the iteration. This // allows the user to quickly repro a failure that happens in the // N-th iteration without repeating the first (N - 1) iterations. // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in // case the user somehow changes the value of the flag somewhere // (it's always safe to unshuffle the tests). UnshuffleTests(); if (GTEST_FLAG(shuffle)) { // Picks a new random seed for each iteration. random_seed_ = GetNextRandomSeed(random_seed_); } } repeater->OnTestProgramEnd(*parent_); return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. void WriteToShardStatusFileIfNeeded() { const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); if (test_shard_file != NULL) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == NULL) { ColoredPrintf(COLOR_RED, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); fflush(stdout); exit(EXIT_FAILURE); } fclose(file); } } // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, // but inconsistent (i.e., shard_index >= total_shards), prints // an error and exits. If in_subprocess_for_death_test, sharding is // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. bool ShouldShard(const char* total_shards_env, const char* shard_index_env, bool in_subprocess_for_death_test) { if (in_subprocess_for_death_test) { return false; } const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); if (total_shards == -1 && shard_index == -1) { return false; } else if (total_shards == -1 && shard_index != -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { const Message msg = Message() << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { const Message msg = Message() << "Invalid environment variables: we require 0 <= " << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; ColoredPrintf(COLOR_RED, msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } return total_shards > 1; } // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; } Int32 result; if (!ParseInt32(Message() << "The value of environment variable " << var, str_val, &result)) { exit(EXIT_FAILURE); } return result; } // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { return (test_id % total_shards) == shard_index; } // Compares the name of each test with the user-specified filter to // decide whether the test should be run, then records the result in // each TestCase and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see // http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; // num_runnable_tests are the number of tests that will // run across all shards (i.e., match filter and are not disabled). // num_selected_tests are the number of tests to be run on // this shard. int num_runnable_tests = 0; int num_selected_tests = 0; for (size_t i = 0; i < test_cases_.size(); i++) { TestCase* const test_case = test_cases_[i]; const std::string &test_case_name = test_case->name(); test_case->set_should_run(false); for (size_t j = 0; j < test_case->test_info_list().size(); j++) { TestInfo* const test_info = test_case->test_info_list()[j]; const std::string test_name(test_info->name()); // A test is disabled if test case name or test name matches // kDisableTestFilter. const bool is_disabled = internal::UnitTestOptions::MatchesFilter(test_case_name, kDisableTestFilter) || internal::UnitTestOptions::MatchesFilter(test_name, kDisableTestFilter); test_info->is_disabled_ = is_disabled; const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); test_info->matches_filter_ = matches_filter; const bool is_runnable = (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && matches_filter; const bool is_selected = is_runnable && (shard_tests == IGNORE_SHARDING_PROTOCOL || ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests)); num_runnable_tests += is_runnable; num_selected_tests += is_selected; test_info->should_run_ = is_selected; test_case->set_should_run(test_case->should_run() || is_selected); } } return num_selected_tests; } // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters // and "...". static void PrintOnOneLine(const char* str, int max_length) { if (str != NULL) { for (int i = 0; *str != '\0'; ++str) { if (i >= max_length) { printf("..."); break; } if (*str == '\n') { printf("\\n"); i += 2; } else { printf("%c", *str); ++i; } } } } // Prints the names of the tests matching the user-specified filter flag. void UnitTestImpl::ListTestsMatchingFilter() { // Print at most this many characters for each type/value parameter. const int kMaxParamLength = 250; for (size_t i = 0; i < test_cases_.size(); i++) { const TestCase* const test_case = test_cases_[i]; bool printed_test_case_name = false; for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = test_case->test_info_list()[j]; if (test_info->matches_filter_) { if (!printed_test_case_name) { printed_test_case_name = true; printf("%s.", test_case->name()); if (test_case->type_param() != NULL) { printf(" # %s = ", kTypeParamLabel); // We print the type parameter on a single line to make // the output easy to parse by a program. PrintOnOneLine(test_case->type_param(), kMaxParamLength); } printf("\n"); } printf(" %s", test_info->name()); if (test_info->value_param() != NULL) { printf(" # %s = ", kValueParamLabel); // We print the value parameter on a single line to make the // output easy to parse by a program. PrintOnOneLine(test_info->value_param(), kMaxParamLength); } printf("\n"); } } } fflush(stdout); } // Sets the OS stack trace getter. // // Does nothing if the input and the current OS stack trace getter are // the same; otherwise, deletes the old getter and makes the input the // current getter. void UnitTestImpl::set_os_stack_trace_getter( OsStackTraceGetterInterface* getter) { if (os_stack_trace_getter_ != getter) { delete os_stack_trace_getter_; os_stack_trace_getter_ = getter; } } // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { os_stack_trace_getter_ = new OsStackTraceGetter; } return os_stack_trace_getter_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. void UnitTestImpl::ShuffleTests() { // Shuffles the death test cases. ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); // Shuffles the non-death test cases. ShuffleRange(random(), last_death_test_case_ + 1, static_cast(test_cases_.size()), &test_case_indices_); // Shuffles the tests inside each test case. for (size_t i = 0; i < test_cases_.size(); i++) { test_cases_[i]->ShuffleTests(random()); } } // Restores the test cases and tests to their order before the first shuffle. void UnitTestImpl::UnshuffleTests() { for (size_t i = 0; i < test_cases_.size(); i++) { // Unshuffles the tests in each test case. test_cases_[i]->UnshuffleTests(); // Resets the index of each test case. test_case_indices_[i] = static_cast(i); } } // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } // Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to // suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; } bool IsTrue(bool condition) { return condition; } bool AlwaysTrue() { #if GTEST_HAS_EXCEPTIONS // This condition is always false so AlwaysTrue() never actually throws, // but it makes the compiler think that it may throw. if (IsTrue(false)) throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS return true; } // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. bool SkipPrefix(const char* prefix, const char** pstr) { const size_t prefix_len = strlen(prefix); if (strncmp(*pstr, prefix, prefix_len) == 0) { *pstr += prefix_len; return true; } return false; } // Parses a string as a command line flag. The string should have // the format "--flag=value". When def_optional is true, the "=value" // part can be omitted. // // Returns the value of the flag, or NULL if the parsing failed. const char* ParseFlagValue(const char* str, const char* flag, bool def_optional) { // str and flag must not be NULL. if (str == NULL || flag == NULL) return NULL; // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; const size_t flag_len = flag_str.length(); if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; // Skips the flag name. const char* flag_end = str + flag_len; // When def_optional is true, it's OK to not have a "=value" part. if (def_optional && (flag_end[0] == '\0')) { return flag_end; } // If def_optional is true and there are more characters after the // flag name, or if def_optional is false, there must be a '=' after // the flag name. if (flag_end[0] != '=') return NULL; // Returns the string after "=". return flag_end + 1; } // Parses a string for a bool flag, in the form of either // "--flag=value" or "--flag". // // In the former case, the value is taken as true as long as it does // not start with '0', 'f', or 'F'. // // In the latter case, the value is taken as true. // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); // Aborts if the parsing failed. if (value_str == NULL) return false; // Converts the string value to a bool. *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); return true; } // Parses a string for an Int32 flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. return ParseInt32(Message() << "The value of flag --" << flag, value_str, value); } // Parses a string for a string flag, in the form of // "--flag=value". // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); // Aborts if the parsing failed. if (value_str == NULL) return false; // Sets *value to the value of the flag. *value = value_str; return true; } // Determines whether a string has a prefix that Google Test uses for its // flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. // If Google Test detects that a command line flag has its prefix but is not // recognized, it will print its help message. Flags starting with // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. static bool HasGoogleTestFlagPrefix(const char* str) { return (SkipPrefix("--", &str) || SkipPrefix("-", &str) || SkipPrefix("/", &str)) && !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); } // Prints a string containing code-encoded text. The following escape // sequences can be used in the string to control the text color: // // @@ prints a single '@' character. // @R changes the color to red. // @G changes the color to green. // @Y changes the color to yellow. // @D changes to the default terminal text color. // // TODO(wan@google.com): Write tests for this once we add stdout // capturing to Google Test. static void PrintColorEncoded(const char* str) { GTestColor color = COLOR_DEFAULT; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of // each iteration, the str pointer advances to the beginning of the // next segment. for (;;) { const char* p = strchr(str, '@'); if (p == NULL) { ColoredPrintf(color, "%s", str); return; } ColoredPrintf(color, "%s", std::string(str, p).c_str()); const char ch = p[1]; str = p + 2; if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { color = COLOR_DEFAULT; } else if (ch == 'R') { color = COLOR_RED; } else if (ch == 'G') { color = COLOR_GREEN; } else if (ch == 'Y') { color = COLOR_YELLOW; } else { --str; } } } static const char kColorEncodedHelpMessage[] = "This program contains tests written using " GTEST_NAME_ ". You can use the\n" "following command line flags to control its behavior:\n" "\n" "Test Selection:\n" " @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" " List the names of all tests instead of running them. The name of\n" " TEST(Foo, Bar) is \"Foo.Bar\".\n" " @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" "[@G-@YNEGATIVE_PATTERNS]@D\n" " Run only the tests whose name matches one of the positive patterns but\n" " none of the negative patterns. '?' matches any single character; '*'\n" " matches any substring; ':' separates two patterns.\n" " @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" " Run all disabled tests too.\n" "\n" "Test Execution:\n" " @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" " Run the tests repeatedly; use a negative count to repeat forever.\n" " @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" " Randomize tests' orders on every iteration.\n" " @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" " Random number seed to use for shuffling test orders (between 1 and\n" " 99999, or 0 to use a seed based on the current time).\n" "\n" "Test Output:\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " Enable/disable colored output. The default is @Gauto@D.\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " Don't print the elapsed time of each test.\n" " @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate an XML report in the given directory or with the given file\n" " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" #if GTEST_CAN_STREAM_RESULTS_ " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " Stream test results to the given server.\n" #endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " Set the default death test style.\n" #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " Turn assertion failures into C++ exceptions.\n" " @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" " Do not report exceptions as test failures. Instead, allow them\n" " to crash the program or throw a pop-up (on Windows).\n" "\n" "Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " "the corresponding\n" "environment variable of a flag (all letters in upper-case). For example, to\n" "disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ "color=no@D or set\n" "the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" "\n" "For more information, please read the " GTEST_NAME_ " documentation at\n" "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. template void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { for (int i = 1; i < *argc; i++) { const std::string arg_string = StreamableToString(argv[i]); const char* const arg = arg_string.c_str(); using internal::ParseBoolFlag; using internal::ParseInt32Flag; using internal::ParseStringFlag; // Do we see a Google Test flag? if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || ParseBoolFlag(arg, kBreakOnFailureFlag, >EST_FLAG(break_on_failure)) || ParseBoolFlag(arg, kCatchExceptionsFlag, >EST_FLAG(catch_exceptions)) || ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || ParseStringFlag(arg, kDeathTestStyleFlag, >EST_FLAG(death_test_style)) || ParseBoolFlag(arg, kDeathTestUseFork, >EST_FLAG(death_test_use_fork)) || ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag, >EST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag, >EST_FLAG(stack_trace_depth)) || ParseStringFlag(arg, kStreamResultToFlag, >EST_FLAG(stream_result_to)) || ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being // NULL. The following loop moves the trailing NULL element as // well. for (int j = i; j != *argc; j++) { argv[j] = argv[j + 1]; } // Decrements the argument count. (*argc)--; // We also need to decrement the iterator as we just removed // an element. i--; } else if (arg_string == "--help" || arg_string == "-h" || arg_string == "-?" || arg_string == "/?" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. g_help_flag = true; } } if (g_help_flag) { // We print the help here instead of in RUN_ALL_TESTS(), as the // latter may not be called at all if the user is using Google // Test with another testing framework. PrintColorEncoded(kColorEncodedHelpMessage); } } // Parses the command line for Google Test flags, without initializing // other parts of Google Test. void ParseGoogleTestFlagsOnly(int* argc, char** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { ParseGoogleTestFlagsOnlyImpl(argc, argv); } // The internal implementation of InitGoogleTest(). // // The type parameter CharType can be instantiated to either char or // wchar_t. template void InitGoogleTestImpl(int* argc, CharType** argv) { g_init_gtest_count++; // We don't want to run the initialization code twice. if (g_init_gtest_count != 1) return; if (*argc <= 0) return; internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); } #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. void InitGoogleTest(int* argc, char** argv) { internal::InitGoogleTestImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. void InitGoogleTest(int* argc, wchar_t** argv) { internal::InitGoogleTestImpl(argc, argv); } } // namespace testing node-v4.2.6/deps/gtest/src/gtest_main.cc000644 000766 000024 00000003345 12650222322 020260 0ustar00iojsstaff000000 000000 // Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "gtest/gtest.h" GTEST_API_ int main(int argc, char **argv) { printf("Running main() from gtest_main.cc\n"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } node-v4.2.6/deps/gtest/include/gtest/000755 000766 000024 00000000000 12650222322 017574 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/gtest/include/gtest/gtest-death-test.h000644 000766 000024 00000026403 12650222322 023140 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for death tests. It is // #included by gtest.h so a user doesn't need to include this // directly. #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #include "gtest/internal/gtest-death-test-internal.h" namespace testing { // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", // meaning that the child process will execute the test logic immediately // after forking. GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST namespace internal { // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. GTEST_API_ bool InDeathTestChild(); } // namespace internal // The following macros are useful for writing death tests. // Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is // executed: // // 1. It generates a warning if there is more than one active // thread. This is because it's safe to fork() or clone() only // when there is a single thread. // // 2. The parent process clone()s a sub-process and runs the death // test in it; the sub-process exits with code 0 at the end of the // death test, if it hasn't exited already. // // 3. The parent process waits for the sub-process to terminate. // // 4. The parent process checks the exit code and error message of // the sub-process. // // Examples: // // ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); // for (int i = 0; i < 5; i++) { // EXPECT_DEATH(server.ProcessRequest(i), // "Invalid request .* in ProcessRequest()") // << "Failed to die on request " << i; // } // // ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); // // bool KilledBySIGHUP(int exit_code) { // return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; // } // // ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); // // On the regular expressions used in death tests: // // On POSIX-compliant systems (*nix), we use the library, // which uses the POSIX extended regex syntax. // // On other platforms (e.g. Windows), we only support a simple regex // syntax implemented as part of Google Test. This limited // implementation should be enough most of the time when writing // death tests; though it lacks many features you can find in PCRE // or POSIX extended regex syntax. For example, we don't support // union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and // repetition count ("x{5,7}"), among others. // // Below is the syntax that we do support. We chose it to be a // subset of both PCRE and POSIX extended regex, so it's easy to // learn wherever you come from. In the following: 'A' denotes a // literal character, period (.), or a single \\ escape sequence; // 'x' and 'y' denote regular expressions; 'm' and 'n' are for // natural numbers. // // c matches any literal character c // \\d matches any decimal digit // \\D matches any character that's not a decimal digit // \\f matches \f // \\n matches \n // \\r matches \r // \\s matches any ASCII whitespace, including \n // \\S matches any character that's not a whitespace // \\t matches \t // \\v matches \v // \\w matches any letter, _, or decimal digit // \\W matches any character that \\w doesn't match // \\c matches any literal character c, which must be a punctuation // . matches any single character except \n // A? matches 0 or 1 occurrences of A // A* matches 0 or many occurrences of A // A+ matches 1 or many occurrences of A // ^ matches the beginning of a string (not that of each line) // $ matches the end of a string (not that of each line) // xy matches x followed by y // // If you accidentally use PCRE or POSIX extended regex features // not implemented by us, you will get a run-time failure. In that // case, please try to rewrite your regular expression within the // above syntax. // // This implementation is *not* meant to be as highly tuned or robust // as a compiled regex library, but should perform well enough for a // death test, which already incurs significant overhead by launching // a child process. // // Known caveats: // // A "threadsafe" style death test obtains the path to the test // program from argv[0] and re-executes it in the sub-process. For // simplicity, the current implementation doesn't search the PATH // when launching the sub-process. This means that the user must // invoke the test program via a path that contains at least one // path separator (e.g. path/to/foo_test and // /absolute/path/to/bar_test are fine, but foo_test is not). This // is rarely a problem as people usually don't put the test binary // directory in PATH. // // TODO(wan@google.com): make thread-safe death tests search the PATH. // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. # define ASSERT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: # define EXPECT_EXIT(statement, predicate, regex) \ GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. # define ASSERT_DEATH(statement, regex) \ ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: # define EXPECT_DEATH(statement, regex) \ EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. class GTEST_API_ ExitedWithCode { public: explicit ExitedWithCode(int exit_code); bool operator()(int exit_status) const; private: // No implementation - assignment is unsupported. void operator=(const ExitedWithCode& other); const int exit_code_; }; # if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { public: explicit KilledBySignal(int signum); bool operator()(int exit_status) const; private: const int signum_; }; # endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, // since the sideeffects of the call are only visible in opt mode, and not // in debug mode. // // In practice, this can be used to test functions that utilize the // LOG(DFATAL) macro using the following style: // // int DieInDebugOr12(int* sideeffect) { // if (sideeffect) { // *sideeffect = 12; // } // LOG(DFATAL) << "death"; // return 12; // } // // TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { // int sideeffect = 0; // // Only asserts in dbg. // EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); // // #ifdef NDEBUG // // opt-mode has sideeffect visible. // EXPECT_EQ(12, sideeffect); // #else // // dbg-mode no visible sideeffect. // EXPECT_EQ(0, sideeffect); // #endif // } // // This will assert that DieInDebugReturn12InOpt() crashes in debug // mode, usually due to a DCHECK or LOG(DFATAL), but returns the // appropriate fallback value (12 in this case) in opt mode. If you // need to test that a function has appropriate side-effects in opt // mode, include assertions against the side-effects. A general // pattern for this is: // // EXPECT_DEBUG_DEATH({ // // Side-effects here will have an effect after this statement in // // opt mode, but none in debug mode. // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // # ifdef NDEBUG # define EXPECT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ GTEST_EXECUTE_STATEMENT_(statement, regex) # else # define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) # endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and // ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if // death tests are supported; otherwise they just issue a warning. This is // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else # define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) # define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-message.h000644 000766 000024 00000021742 12650222322 022523 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the Message class. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! #ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ #include #include "gtest/internal/gtest-port.h" // Ensures that there is at least one operator<< in the global namespace. // See Message& operator<<(...) below for why. void operator<<(const testing::internal::Secret&, int); namespace testing { // The Message class works like an ostream repeater. // // Typical usage: // // 1. You stream a bunch of values to a Message object. // It will remember the text in a stringstream. // 2. Then you stream the Message object to an ostream. // This causes the text in the Message to be streamed // to the ostream. // // For example; // // testing::Message foo; // foo << 1 << " != " << 2; // std::cout << foo; // // will print "1 != 2". // // Message is not intended to be inherited from. In particular, its // destructor is not virtual. // // Note that stringstream behaves differently in gcc and in MSVC. You // can stream a NULL char pointer to it in the former, but not in the // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". class GTEST_API_ Message { private: // The type of basic IO manipulators (endl, ends, and flush) for // narrow streams. typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); public: // Constructs an empty Message. Message(); // Copy constructor. Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT *ss_ << msg.GetString(); } // Constructs a Message from a C-string. explicit Message(const char* str) : ss_(new ::std::stringstream) { *ss_ << str; } #if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template inline Message& operator <<(const T& value) { StreamHelper(typename internal::is_pointer::type(), value); return *this; } #else // Streams a non-pointer value to this object. template inline Message& operator <<(const T& val) { // Some libraries overload << for STL containers. These // overloads are defined in the global namespace instead of ::std. // // C++'s symbol lookup rule (i.e. Koenig lookup) says that these // overloads are visible in either the std namespace or the global // namespace, but not other namespaces, including the testing // namespace which Google Test's Message class is in. // // To allow STL containers (and other types that has a << operator // defined in the global namespace) to be used in Google Test // assertions, testing::Message must access the custom << operator // from the global namespace. With this using declaration, // overloads of << defined in the global namespace and those // visible via Koenig lookup are both exposed in this function. using ::operator <<; *ss_ << val; return *this; } // Streams a pointer value to this object. // // This function is an overload of the previous one. When you // stream a pointer to a Message, this definition will be used as it // is more specialized. (The C++ Standard, section // [temp.func.order].) If you stream a non-pointer, then the // previous definition will be used. // // The reason for this overload is that streaming a NULL pointer to // ostream is undefined behavior. Depending on the compiler, you // may get "0", "(nil)", "(null)", or an access violation. To // ensure consistent result across compilers, we always treat NULL // as "(null)". template inline Message& operator <<(T* const& pointer) { // NOLINT if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } return *this; } #endif // GTEST_OS_SYMBIAN // Since the basic IO manipulators are overloaded for both narrow // and wide streams, we have to provide this specialized definition // of operator <<, even though its body is the same as the // templatized version above. Without this definition, streaming // endl or other basic IO manipulators to Message will confuse the // compiler. Message& operator <<(BasicNarrowIoManip val) { *ss_ << val; return *this; } // Instead of 1/0, we want to see true/false for bool values. Message& operator <<(bool b) { return *this << (b ? "true" : "false"); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. Message& operator <<(const wchar_t* wide_c_str); Message& operator <<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. Message& operator <<(const ::wstring& wstr); #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. std::string GetString() const; private: #if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ // decide between class template specializations for T and T*, so a // tr1::type_traits-like is_pointer works, and we can overload on that. template inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { if (pointer == NULL) { *ss_ << "(null)"; } else { *ss_ << pointer; } } template inline void StreamHelper(internal::false_type /*is_pointer*/, const T& value) { // See the comments in Message& operator <<(const T&) above for why // we need this using statement. using ::operator <<; *ss_ << value; } #endif // GTEST_OS_SYMBIAN // We'll hold the text streamed to this object here. const internal::scoped_ptr< ::std::stringstream> ss_; // We declare (but don't implement) this to prevent the compiler // from implementing the assignment operator. void operator=(const Message&); }; // Streams a Message to an ostream. inline std::ostream& operator <<(std::ostream& os, const Message& sb) { return os << sb.GetString(); } namespace internal { // Converts a streamable value to an std::string. A NULL pointer is // converted to "(null)". When the input value is a ::string, // ::std::string, ::wstring, or ::std::wstring object, each NUL // character in it is replaced with "\\0". template std::string StreamableToString(const T& streamable) { return (Message() << streamable).GetString(); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-param-test.h000644 000766 000024 00000224130 12650222322 023150 0ustar00iojsstaff000000 000000 // This file was GENERATED by command: // pump.py gtest-param-test.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: vladl@google.com (Vlad Losev) // // Macros and functions for implementing parameterized tests // in Google C++ Testing Framework (Google Test) // // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // // Here is how you use value-parameterized tests: #if 0 // To write value-parameterized tests, first you should define a fixture // class. It is usually derived from testing::TestWithParam (see below for // another inheritance scheme that's sometimes useful in more complicated // class hierarchies), where the type of your parameter values. // TestWithParam is itself derived from testing::Test. T can be any // copyable type. If it's a raw pointer, you are responsible for managing the // lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. }; // Then, use the TEST_P macro to define as many parameterized tests // for this fixture as you want. The _P suffix is for "parameterized" // or "pattern", whichever you prefer to think. TEST_P(FooTest, DoesBlah) { // Inside a test, access the test parameter with the GetParam() method // of the TestWithParam class: EXPECT_TRUE(foo.Blah(GetParam())); ... } TEST_P(FooTest, HasBlahBlah) { ... } // Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test // case with any set of parameters you want. Google Test defines a number // of functions for generating test parameters. They return what we call // (surprise!) parameter generators. Here is a summary of them, which // are all in the testing namespace: // // // Range(begin, end [, step]) - Yields values {begin, begin+step, // begin+step+step, ...}. The values do not // include end. step defaults to 1. // Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. // ValuesIn(container) - Yields values from a C-style array, an STL // ValuesIn(begin,end) container, or an iterator range [begin, end). // Bool() - Yields sequence {false, true}. // Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product // for the math savvy) of the values generated // by the N generators. // // For more details, see comments at the definitions of these functions below // in this file. // // The following statement will instantiate tests from the FooTest test case // each with parameter values "meeny", "miny", and "moe". INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest, Values("meeny", "miny", "moe")); // To distinguish different instances of the pattern, (yes, you // can instantiate it more then once) the first argument to the // INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the // actual test case name. Remember to pick unique prefixes for different // instantiations. The tests from the instantiation above will have // these names: // // * InstantiationName/FooTest.DoesBlah/0 for "meeny" // * InstantiationName/FooTest.DoesBlah/1 for "miny" // * InstantiationName/FooTest.DoesBlah/2 for "moe" // * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" // * InstantiationName/FooTest.HasBlahBlah/1 for "miny" // * InstantiationName/FooTest.HasBlahBlah/2 for "moe" // // You can use these names in --gtest_filter. // // This statement will instantiate all tests from FooTest again, each // with parameter values "cat" and "dog": const char* pets[] = {"cat", "dog"}; INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // The tests from the instantiation above will have these names: // // * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" // * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" // * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" // * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" // // Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests // in the given test case, whether their definitions come before or // AFTER the INSTANTIATE_TEST_CASE_P statement. // // Please also note that generator expressions (including parameters to the // generators) are evaluated in InitGoogleTest(), after main() has started. // This allows the user on one hand, to adjust generator parameters in order // to dynamically determine a set of tests to run and on the other hand, // give the user a chance to inspect the generated tests with Google Test // reflection API before RUN_ALL_TESTS() is executed. // // You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc // for more examples. // // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. // // // A parameterized test fixture must be derived from testing::Test and from // testing::WithParamInterface, where T is the type of the parameter // values. Inheriting from TestWithParam satisfies that requirement because // TestWithParam inherits from both Test and WithParamInterface. In more // complicated hierarchies, however, it is occasionally useful to inherit // separately from Test and WithParamInterface. For example: class BaseTest : public ::testing::Test { // You can inherit all the usual members for a non-parameterized test // fixture here. }; class DerivedTest : public BaseTest, public ::testing::WithParamInterface { // The usual test fixture members go here too. }; TEST_F(BaseTest, HasFoo) { // This is an ordinary non-parameterized test. } TEST_P(DerivedTest, DoesBlah) { // GetParam works just the same here as if you inherit from TestWithParam. EXPECT_TRUE(foo.Blah(GetParam())); } #endif // 0 #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN # include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-param-util-generated.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- // parameterized tests. When a parameterized test case is instantiated // with a particular generator, Google Test creates and runs tests // for each element in the sequence produced by the generator. // // In the following sample, tests from test case FooTest are instantiated // each three times with parameter values 3, 5, and 8: // // class FooTest : public TestWithParam { ... }; // // TEST_P(FooTest, TestThis) { // } // TEST_P(FooTest, TestThat) { // } // INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); // // Range() returns generators providing sequences of values in a range. // // Synopsis: // Range(start, end) // - returns a generator producing a sequence of values {start, start+1, // start+2, ..., }. // Range(start, end, step) // - returns a generator producing a sequence of values {start, start+step, // start+step+step, ..., }. // Notes: // * The generated sequences never include end. For example, Range(1, 5) // returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) // returns a generator producing {1, 3, 5, 7}. // * start and end must have the same type. That type may be any integral or // floating-point type or a user defined type satisfying these conditions: // * It must be assignable (have operator=() defined). // * It must have operator+() (operator+(int-compatible type) for // two-operand version). // * It must have operator<() defined. // Elements in the resulting sequences will also have that type. // * Condition start < end must be satisfied in order for resulting sequences // to contain any elements. // template internal::ParamGenerator Range(T start, T end, IncrementT step) { return internal::ParamGenerator( new internal::RangeGenerator(start, end, step)); } template internal::ParamGenerator Range(T start, T end) { return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from // a container. // // Synopsis: // ValuesIn(const T (&array)[N]) // - returns a generator producing sequences with elements from // a C-style array. // ValuesIn(const Container& container) // - returns a generator producing sequences with elements from // an STL-style container. // ValuesIn(Iterator begin, Iterator end) // - returns a generator producing sequences with elements from // a range [begin, end) defined by a pair of STL-style iterators. These // iterators can also be plain C pointers. // // Please note that ValuesIn copies the values from the containers // passed in and keeps them to generate tests in RUN_ALL_TESTS(). // // Examples: // // This instantiates tests from test case StringTest // each with C-string values of "foo", "bar", and "baz": // // const char* strings[] = {"foo", "bar", "baz"}; // INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); // // This instantiates tests from test case StlStringTest // each with STL strings with values "a" and "b": // // ::std::vector< ::std::string> GetParameterStrings() { // ::std::vector< ::std::string> v; // v.push_back("a"); // v.push_back("b"); // return v; // } // // INSTANTIATE_TEST_CASE_P(CharSequence, // StlStringTest, // ValuesIn(GetParameterStrings())); // // // This will also instantiate tests from CharTest // each with parameter values 'a' and 'b': // // ::std::list GetParameterChars() { // ::std::list list; // list.push_back('a'); // list.push_back('b'); // return list; // } // ::std::list l = GetParameterChars(); // INSTANTIATE_TEST_CASE_P(CharSequence2, // CharTest, // ValuesIn(l.begin(), l.end())); // template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end) { typedef typename ::testing::internal::IteratorTraits ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } template internal::ParamGenerator ValuesIn(const T (&array)[N]) { return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( const Container& container) { return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of // parameters. // // Synopsis: // Values(T v1, T v2, ..., T vN) // - returns a generator producing sequences with elements v1, v2, ..., vN. // // For example, this instantiates tests from test case BarTest each // with values "one", "two", and "three": // // INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); // // This instantiates tests from test case BazTest each with values 1, 2, 3.5. // The exact type of values will depend on the type of parameter in BazTest. // // INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); // // Currently, Values() supports from 1 to 50 parameters. // template internal::ValueArray1 Values(T1 v1) { return internal::ValueArray1(v1); } template internal::ValueArray2 Values(T1 v1, T2 v2) { return internal::ValueArray2(v1, v2); } template internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { return internal::ValueArray3(v1, v2, v3); } template internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { return internal::ValueArray4(v1, v2, v3, v4); } template internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) { return internal::ValueArray5(v1, v2, v3, v4, v5); } template internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) { return internal::ValueArray6(v1, v2, v3, v4, v5, v6); } template internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) { return internal::ValueArray7(v1, v2, v3, v4, v5, v6, v7); } template internal::ValueArray8 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { return internal::ValueArray8(v1, v2, v3, v4, v5, v6, v7, v8); } template internal::ValueArray9 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { return internal::ValueArray9(v1, v2, v3, v4, v5, v6, v7, v8, v9); } template internal::ValueArray10 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { return internal::ValueArray10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10); } template internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) { return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } template internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) { return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); } template internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) { return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); } template internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14); } template internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15); } template internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) { return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16); } template internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) { return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17); } template internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) { return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18); } template internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); } template internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); } template internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { return internal::ValueArray21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); } template internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) { return internal::ValueArray22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22); } template internal::ValueArray23 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) { return internal::ValueArray23(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23); } template internal::ValueArray24 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) { return internal::ValueArray24(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24); } template internal::ValueArray25 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { return internal::ValueArray25(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25); } template internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) { return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); } template internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) { return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); } template internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) { return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28); } template internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) { return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29); } template internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30); } template internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31); } template internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) { return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32); } template internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) { return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); } template internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) { return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); } template internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { return internal::ValueArray35(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); } template internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { return internal::ValueArray36(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36); } template internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) { return internal::ValueArray37(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37); } template internal::ValueArray38 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) { return internal::ValueArray38(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38); } template internal::ValueArray39 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) { return internal::ValueArray39(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39); } template internal::ValueArray40 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); } template internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); } template internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) { return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42); } template internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) { return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43); } template internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) { return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44); } template internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45); } template internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46); } template internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); } template internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) { return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); } template internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) { return internal::ValueArray49(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); } template internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { return internal::ValueArray50(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50); } // Bool() allows generating tests with parameters in a set of (false, true). // // Synopsis: // Bool() // - returns a generator producing sequences with elements {false, true}. // // It is useful when testing code that depends on Boolean flags. Combinations // of multiple flags can be tested when several Bool()'s are combined using // Combine() function. // // In the following example all tests in the test case FlagDependentTest // will be instantiated twice with parameters false and true. // // class FlagDependentTest : public testing::TestWithParam { // virtual void SetUp() { // external_flag = GetParam(); // } // } // INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); // inline internal::ParamGenerator Bool() { return Values(false, true); } # if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // // Synopsis: // Combine(gen1, gen2, ..., genN) // - returns a generator producing sequences with elements coming from // the Cartesian product of elements from the sequences generated by // gen1, gen2, ..., genN. The sequence elements will have a type of // tuple where T1, T2, ..., TN are the types // of elements from sequences produces by gen1, gen2, ..., genN. // // Combine can have up to 10 arguments. This number is currently limited // by the maximum number of elements in the tuple implementation used by Google // Test. // // Example: // // This will instantiate tests in test case AnimalTest each one with // the parameter values tuple("cat", BLACK), tuple("cat", WHITE), // tuple("dog", BLACK), and tuple("dog", WHITE): // // enum Color { BLACK, GRAY, WHITE }; // class AnimalTest // : public testing::TestWithParam > {...}; // // TEST_P(AnimalTest, AnimalLooksNice) {...} // // INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, // Combine(Values("cat", "dog"), // Values(BLACK, WHITE))); // // This will instantiate tests in FlagDependentTest with all variations of two // Boolean flags: // // class FlagDependentTest // : public testing::TestWithParam > { // virtual void SetUp() { // // Assigns external_flag_1 and external_flag_2 values from the tuple. // tie(external_flag_1, external_flag_2) = GetParam(); // } // }; // // TEST_P(FlagDependentTest, TestFeature1) { // // Test your code using external_flag_1 and external_flag_2 here. // } // INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, // Combine(Bool(), Bool())); // template internal::CartesianProductHolder2 Combine( const Generator1& g1, const Generator2& g2) { return internal::CartesianProductHolder2( g1, g2); } template internal::CartesianProductHolder3 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3) { return internal::CartesianProductHolder3( g1, g2, g3); } template internal::CartesianProductHolder4 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) { return internal::CartesianProductHolder4( g1, g2, g3, g4); } template internal::CartesianProductHolder5 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) { return internal::CartesianProductHolder5( g1, g2, g3, g4, g5); } template internal::CartesianProductHolder6 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) { return internal::CartesianProductHolder6( g1, g2, g3, g4, g5, g6); } template internal::CartesianProductHolder7 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) { return internal::CartesianProductHolder7( g1, g2, g3, g4, g5, g6, g7); } template internal::CartesianProductHolder8 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) { return internal::CartesianProductHolder8( g1, g2, g3, g4, g5, g6, g7, g8); } template internal::CartesianProductHolder9 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) { return internal::CartesianProductHolder9( g1, g2, g3, g4, g5, g6, g7, g8, g9); } template internal::CartesianProductHolder10 Combine( const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) { return internal::CartesianProductHolder10( g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } # endif // GTEST_HAS_COMBINE # define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ virtual void TestBody(); \ private: \ static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ #test_case_name, \ #test_name, \ new ::testing::internal::TestMetaFactory< \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ return 0; \ } \ static int gtest_registering_dummy_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ int GTEST_TEST_CLASS_NAME_(test_case_name, \ test_name)::gtest_registering_dummy_ = \ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ #prefix, \ >est_##prefix##test_case_name##_EvalGenerator_, \ __FILE__, __LINE__) } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-printers.h000644 000766 000024 00000077237 12650222322 022757 0ustar00iojsstaff000000 000000 // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Google Test - The Google C++ Testing Framework // // This file implements a universal value printer that can print a // value of any type T: // // void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); // // A user can teach this function how to print a class type T by // defining either operator<<() or PrintTo() in the namespace that // defines T. More specifically, the FIRST defined function in the // following list will be used (assuming T is defined in namespace // foo): // // 1. foo::PrintTo(const T&, ostream*) // 2. operator<<(ostream&, const T&) defined in either foo or the // global namespace. // // If none of the above is defined, it will print the debug string of // the value if it is a protocol buffer, or print the raw bytes in the // value otherwise. // // To aid debugging: when T is a reference type, the address of the // value is also printed; when T is a (const) char pointer, both the // pointer value and the NUL-terminated string it points to are // printed. // // We also provide some convenient wrappers: // // // Prints a value to a string. For a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // std::string ::testing::PrintToString(const T& value); // // // Prints a value tersely: for a reference type, the referenced // // value (but not the address) is printed; for a (const or not) char // // pointer, the NUL-terminated string (but not the pointer) is // // printed. // void ::testing::internal::UniversalTersePrint(const T& value, ostream*); // // // Prints value using the type inferred by the compiler. The difference // // from UniversalTersePrint() is that this function prints both the // // pointer and the NUL-terminated string for a (const or not) char pointer. // void ::testing::internal::UniversalPrint(const T& value, ostream*); // // // Prints the fields of a tuple tersely to a string vector, one // // element for each field. Tuple support must be enabled in // // gtest-port.h. // std::vector UniversalTersePrintTupleFieldsToStrings( // const Tuple& value); // // Known limitation: // // The print primitives print the elements of an STL-style container // using the compiler-inferred type of *iter where iter is a // const_iterator of the container. When const_iterator is an input // iterator but not a forward iterator, this inferred type may not // match value_type, and the print output may be incorrect. In // practice, this is rarely a problem as for most containers // const_iterator is a forward iterator. We'll fix this if there's an // actual need for it. Note that this fix cannot rely on value_type // being defined as many user-defined container types don't have // value_type. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #include // NOLINT #include #include #include #include #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-internal.h" #if GTEST_HAS_STD_TUPLE_ # include #endif namespace testing { // Definitions in the 'internal' and 'internal2' name spaces are // subject to change without notice. DO NOT USE THEM IN USER CODE! namespace internal2 { // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, ::std::ostream* os); // For selecting which printer to use when a given type has neither << // nor PrintTo(). enum TypeKind { kProtobuf, // a protobuf type kConvertibleToInteger, // a type implicitly convertible to BiggestInt // (e.g. a named or unnamed enum type) kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called // by the universal printer to print a value of type T when neither // operator<< nor PrintTo() is defined for T, where kTypeKind is the // "kind" of T as defined by enum TypeKind. template class TypeWithoutFormatter { public: // This default version is called when kTypeKind is kOtherType. static void PrintValue(const T& value, ::std::ostream* os) { PrintBytesInObjectTo(reinterpret_cast(&value), sizeof(value), os); } }; // We print a protobuf using its ShortDebugString() when the string // doesn't exceed this many characters; otherwise we print it using // DebugString() for better readability. const size_t kProtobufOneLinerMaxLength = 50; template class TypeWithoutFormatter { public: static void PrintValue(const T& value, ::std::ostream* os) { const ::testing::internal::string short_str = value.ShortDebugString(); const ::testing::internal::string pretty_str = short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); *os << ("<" + pretty_str + ">"); } }; template class TypeWithoutFormatter { public: // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // // Most likely T is an enum type (either named or unnamed), in which // case printing it as an integer is the desired behavior. In case // T is not an enum, printing it as an integer is the best we can do // given that it has no user-defined printer. static void PrintValue(const T& value, ::std::ostream* os) { const internal::BiggestInt kBigInt = value; *os << kBigInt; } }; // Prints the given value to the given ostream. If the value is a // protocol message, its debug string is printed; if it's an enum or // of a type implicitly convertible to BiggestInt, it's printed as an // integer; otherwise the bytes in the value are printed. This is // what UniversalPrinter::Print() does when it knows nothing about // type T and T has neither << operator nor PrintTo(). // // A user can override this behavior for a class type Foo by defining // a << operator in the namespace where Foo is defined. // // We put this operator in namespace 'internal2' instead of 'internal' // to simplify the implementation, as much code in 'internal' needs to // use << in STL, which would conflict with our own << were it defined // in 'internal'. // // Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If // we define it to take an std::ostream instead, we'll get an // "ambiguous overloads" compiler error when trying to print a type // Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether // operator<<(std::ostream&, const T&) or // operator<<(std::basic_stream, const Foo&) is more // specific. template ::std::basic_ostream& operator<<( ::std::basic_ostream& os, const T& x) { TypeWithoutFormatter::value ? kProtobuf : internal::ImplicitlyConvertible::value ? kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); return os; } } // namespace internal2 } // namespace testing // This namespace MUST NOT BE NESTED IN ::testing, or the name look-up // magic needed for implementing UniversalPrinter won't work. namespace testing_internal { // Used to print a value that is not an STL-style container when the // user doesn't define PrintTo() for it. template void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { // With the following statement, during unqualified name lookup, // testing::internal2::operator<< appears as if it was declared in // the nearest enclosing namespace that contains both // ::testing_internal and ::testing::internal2, i.e. the global // namespace. For more details, refer to the C++ Standard section // 7.3.4-1 [namespace.udir]. This allows us to fall back onto // testing::internal2::operator<< in case T doesn't come with a << // operator. // // We cannot write 'using ::testing::internal2::operator<<;', which // gcc 3.3 fails to compile due to a compiler bug. using namespace ::testing::internal2; // NOLINT // Assuming T is defined in namespace foo, in the next statement, // the compiler will consider all of: // // 1. foo::operator<< (thanks to Koenig look-up), // 2. ::operator<< (as the current namespace is enclosed in ::), // 3. testing::internal2::operator<< (thanks to the using statement above). // // The operator<< whose type matches T best will be picked. // // We deliberately allow #2 to be a candidate, as sometimes it's // impossible to define #1 (e.g. when foo is ::std, defining // anything in it is undefined behavior unless you are a compiler // vendor.). *os << value; } } // namespace testing_internal namespace testing { namespace internal { // UniversalPrinter::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. // // We define UniversalPrinter as a class template (as opposed to a // function template), as we need to partially specialize it for // reference types, which cannot be done with function templates. template class UniversalPrinter; template void UniversalPrint(const T& value, ::std::ostream* os); // Used to print an STL-style container when the user doesn't define // a PrintTo() for it. template void DefaultPrintTo(IsContainer /* dummy */, false_type /* is not a pointer */, const C& container, ::std::ostream* os) { const size_t kMaxCount = 32; // The maximum number of elements to print. *os << '{'; size_t count = 0; for (typename C::const_iterator it = container.begin(); it != container.end(); ++it, ++count) { if (count > 0) { *os << ','; if (count == kMaxCount) { // Enough has been printed. *os << " ..."; break; } } *os << ' '; // We cannot call PrintTo(*it, os) here as PrintTo() doesn't // handle *it being a native array. internal::UniversalPrint(*it, os); } if (count > 0) { *os << ' '; } *os << '}'; } // Used to print a pointer that is neither a char pointer nor a member // pointer, when the user doesn't define PrintTo() for it. (A member // variable pointer or member function pointer doesn't really point to // a location in the address space. Their representation is // implementation-defined. Therefore they will be printed as raw // bytes.) template void DefaultPrintTo(IsNotContainer /* dummy */, true_type /* is a pointer */, T* p, ::std::ostream* os) { if (p == NULL) { *os << "NULL"; } else { // C++ doesn't allow casting from a function pointer to any object // pointer. // // IsTrue() silences warnings: "Condition is always true", // "unreachable code". if (IsTrue(ImplicitlyConvertible::value)) { // T is not a function type. We just call << to print p, // relying on ADL to pick up user-defined << for their pointer // types, if any. *os << p; } else { // T is a function type, so '*os << p' doesn't do what we want // (it just prints p as bool). We want to print p as a const // void*. However, we cannot cast it to const void* directly, // even using reinterpret_cast, as earlier versions of gcc // (e.g. 3.4.5) cannot compile the cast when p is a function // pointer. Casting to UInt64 first solves the problem. *os << reinterpret_cast( reinterpret_cast(p)); } } } // Used to print a non-container, non-pointer value when the user // doesn't define PrintTo() for it. template void DefaultPrintTo(IsNotContainer /* dummy */, false_type /* is not a pointer */, const T& value, ::std::ostream* os) { ::testing_internal::DefaultPrintNonContainerTo(value, os); } // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter::Print() does when PrintTo() is not specialized // or overloaded for type T. // // A user can override this behavior for a class type Foo by defining // an overload of PrintTo() in the namespace where Foo is defined. We // give the user this option as sometimes defining a << operator for // Foo is not desirable (e.g. the coding style may prevent doing it, // or there is already a << operator but it doesn't do what the user // wants). template void PrintTo(const T& value, ::std::ostream* os) { // DefaultPrintTo() is overloaded. The type of its first two // arguments determine which version will be picked. If T is an // STL-style container, the version for container will be called; if // T is a pointer, the pointer version will be called; otherwise the // generic version will be called. // // Note that we check for container types here, prior to we check // for protocol message types in our operator<<. The rationale is: // // For protocol messages, we want to give people a chance to // override Google Mock's format by defining a PrintTo() or // operator<<. For STL containers, other formats can be // incompatible with Google Mock's format for the container // elements; therefore we check for container types here to ensure // that our format is used. // // The second argument of DefaultPrintTo() is needed to bypass a bug // in Symbian's C++ compiler that prevents it from picking the right // overload between: // // PrintTo(const T& x, ...); // PrintTo(T* x, ...); DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); } // The following list of PrintTo() overloads tells // UniversalPrinter::Print() how to print standard types (built-in // types, strings, plain arrays, and pointers). // Overloads for various char types. GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); inline void PrintTo(char c, ::std::ostream* os) { // When printing a plain char, we always treat it as unsigned. This // way, the output won't be affected by whether the compiler thinks // char is signed or not. PrintTo(static_cast(c), os); } // Overloads for other simple built-in types. inline void PrintTo(bool x, ::std::ostream* os) { *os << (x ? "true" : "false"); } // Overload for wchar_t type. // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its decimal code (except for L'\0'). // The L'\0' char is printed as "L'\\0'". The decimal code is printed // as signed integer when wchar_t is implemented by the compiler // as a signed type and is printed as an unsigned integer when wchar_t // is implemented as an unsigned type. GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // signed/unsigned char is often used for representing binary data, so // we print pointers to it as void* to be safe. inline void PrintTo(const signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(signed char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(const unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } inline void PrintTo(unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned // short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native // type. When wchar_t is a typedef, defining an overload for const // wchar_t* would cause unsigned short* be printed as a wide string, // possibly causing invalid memory accesses. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); inline void PrintTo(wchar_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_(s), os); } #endif // Overload for C arrays. Multi-dimensional arrays are printed // properly. // Prints the given number of elements in an array, without printing // the curly braces. template void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { UniversalPrint(a[0], os); for (size_t i = 1; i != count; i++) { *os << ", "; UniversalPrint(a[i], os); } } // Overloads for ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); inline void PrintTo(const ::string& s, ::std::ostream* os) { PrintStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_STRING GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } // Overloads for ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); inline void PrintTo(const ::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { PrintWideStringTo(s, os); } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ // Helper function for printing a tuple. T must be instantiated with // a tuple type. template void PrintTupleTo(const T& t, ::std::ostream* os); #endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ #if GTEST_HAS_TR1_TUPLE // Overload for ::std::tr1::tuple. Needed for printing function arguments, // which are packed as tuples. // Overloaded PrintTo() for tuples of various arities. We support // tuples of up-to 10 fields. The following implementation works // regardless of whether tr1::tuple is implemented using the // non-standard variadic template feature or not. inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } template void PrintTo( const ::std::tr1::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } #endif // GTEST_HAS_TR1_TUPLE #if GTEST_HAS_STD_TUPLE_ template void PrintTo(const ::std::tuple& t, ::std::ostream* os) { PrintTupleTo(t, os); } #endif // GTEST_HAS_STD_TUPLE_ // Overload for std::pair. template void PrintTo(const ::std::pair& value, ::std::ostream* os) { *os << '('; // We cannot use UniversalPrint(value.first, os) here, as T1 may be // a reference type. The same for printing value.second. UniversalPrinter::Print(value.first, os); *os << ", "; UniversalPrinter::Print(value.second, os); *os << ')'; } // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the // function. static void Print(const T& value, ::std::ostream* os) { // By default, ::testing::internal::PrintTo() is used for printing // the value. // // Thanks to Koenig look-up, if T is a class and has its own // PrintTo() function defined in its namespace, that function will // be visible here. Since it is more specific than the generic ones // in ::testing::internal, it will be picked by the compiler in the // following statement - exactly what we want. PrintTo(value, os); } GTEST_DISABLE_MSC_WARNINGS_POP_() }; // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { if (len == 0) { *os << "{}"; } else { *os << "{ "; const size_t kThreshold = 18; const size_t kChunkSize = 8; // If the array has more than kThreshold elements, we'll have to // omit some details by printing only the first and the last // kChunkSize elements. // TODO(wan@google.com): let the user control the threshold using a flag. if (len <= kThreshold) { PrintRawArrayTo(begin, len, os); } else { PrintRawArrayTo(begin, kChunkSize, os); *os << ", ..., "; PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); } *os << " }"; } } // This overload prints a (const) char array compactly. GTEST_API_ void UniversalPrintArray( const char* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( const wchar_t* begin, size_t len, ::std::ostream* os); // Implements printing an array type T[N]. template class UniversalPrinter { public: // Prints the given array, omitting some elements when there are too // many. static void Print(const T (&a)[N], ::std::ostream* os) { UniversalPrintArray(a, N, os); } }; // Implements printing a reference type T&. template class UniversalPrinter { public: // MSVC warns about adding const to a function type, so we want to // disable the warning. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here // as static_cast doesn't compile when T is a function type. *os << "@" << reinterpret_cast(&value) << " "; // Then prints the value itself. UniversalPrint(value, os); } GTEST_DISABLE_MSC_WARNINGS_POP_() }; // Prints a value tersely: for a reference type, the referenced value // (but not the address) is printed; for a (const) char pointer, the // NUL-terminated string (but not the pointer) is printed. template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T& value, ::std::ostream* os) { UniversalPrint(value, os); } }; template class UniversalTersePrinter { public: static void Print(const T (&value)[N], ::std::ostream* os) { UniversalPrinter::Print(value, os); } }; template <> class UniversalTersePrinter { public: static void Print(const char* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(string(str), os); } } }; template <> class UniversalTersePrinter { public: static void Print(char* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; #if GTEST_HAS_STD_WSTRING template <> class UniversalTersePrinter { public: static void Print(const wchar_t* str, ::std::ostream* os) { if (str == NULL) { *os << "NULL"; } else { UniversalPrint(::std::wstring(str), os); } } }; #endif template <> class UniversalTersePrinter { public: static void Print(wchar_t* str, ::std::ostream* os) { UniversalTersePrinter::Print(str, os); } }; template void UniversalTersePrint(const T& value, ::std::ostream* os) { UniversalTersePrinter::Print(value, os); } // Prints a value using the type inferred by the compiler. The // difference between this and UniversalTersePrint() is that for a // (const) char pointer, this prints both the pointer and the // NUL-terminated string. template void UniversalPrint(const T& value, ::std::ostream* os) { // A workarond for the bug in VC++ 7.1 that prevents us from instantiating // UniversalPrinter with T directly. typedef T T1; UniversalPrinter::Print(value, os); } typedef ::std::vector Strings; // TuplePolicy must provide: // - tuple_size // size of tuple TupleT. // - get(const TupleT& t) // static function extracting element I of tuple TupleT. // - tuple_element::type // type of element I of tuple TupleT. template struct TuplePolicy; #if GTEST_HAS_TR1_TUPLE template struct TuplePolicy { typedef TupleT Tuple; static const size_t tuple_size = ::std::tr1::tuple_size::value; template struct tuple_element : ::std::tr1::tuple_element {}; template static typename AddReference< const typename ::std::tr1::tuple_element::type>::type get( const Tuple& tuple) { return ::std::tr1::get(tuple); } }; template const size_t TuplePolicy::tuple_size; #endif // GTEST_HAS_TR1_TUPLE #if GTEST_HAS_STD_TUPLE_ template struct TuplePolicy< ::std::tuple > { typedef ::std::tuple Tuple; static const size_t tuple_size = ::std::tuple_size::value; template struct tuple_element : ::std::tuple_element {}; template static const typename ::std::tuple_element::type& get( const Tuple& tuple) { return ::std::get(tuple); } }; template const size_t TuplePolicy< ::std::tuple >::tuple_size; #endif // GTEST_HAS_STD_TUPLE_ #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ // This helper template allows PrintTo() for tuples and // UniversalTersePrintTupleFieldsToStrings() to be defined by // induction on the number of tuple fields. The idea is that // TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N // fields in tuple t, and can be defined in terms of // TuplePrefixPrinter. // // The inductive case. template struct TuplePrefixPrinter { // Prints the first N fields of a tuple. template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); GTEST_INTENTIONAL_CONST_COND_PUSH_() if (N > 1) { GTEST_INTENTIONAL_CONST_COND_POP_() *os << ", "; } UniversalPrinter< typename TuplePolicy::template tuple_element::type> ::Print(TuplePolicy::template get(t), os); } // Tersely prints the first N fields of a tuple to a string vector, // one element for each field. template static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); ::std::stringstream ss; UniversalTersePrint(TuplePolicy::template get(t), &ss); strings->push_back(ss.str()); } }; // Base case. template <> struct TuplePrefixPrinter<0> { template static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} template static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} }; // Helper function for printing a tuple. // Tuple must be either std::tr1::tuple or std::tuple type. template void PrintTupleTo(const Tuple& t, ::std::ostream* os) { *os << "("; TuplePrefixPrinter::tuple_size>::PrintPrefixTo(t, os); *os << ")"; } // Prints the fields of a tuple tersely to a string vector, one // element for each field. See the comment before // UniversalTersePrint() for how we define "tersely". template Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { Strings result; TuplePrefixPrinter::tuple_size>:: TersePrintPrefixToStrings(value, &result); return result; } #endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ } // namespace internal template ::std::string PrintToString(const T& value) { ::std::stringstream ss; internal::UniversalTersePrinter::Print(value, &ss); return ss.str(); } } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-spi.h000644 000766 000024 00000023340 12650222322 021666 0ustar00iojsstaff000000 000000 // Copyright 2007, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Utilities for testing Google Test itself and code that uses Google Test // (e.g. frameworks built on top of Google Test). #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #include "gtest/gtest.h" namespace testing { // This helper class can be used to mock out Google Test failure reporting // so that we can test Google Test or code that builds on Google Test. // // An object of this class appends a TestPartResult object to the // TestPartResultArray object given in the constructor whenever a Google Test // failure is reported. It can either intercept only failures that are // generated in the same thread that created this object or it can intercept // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. class GTEST_API_ ScopedFakeTestPartResultReporter : public TestPartResultReporterInterface { public: // The two possible mocking modes of this object. enum InterceptMode { INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. INTERCEPT_ALL_THREADS // Intercepts all failures. }; // The c'tor sets this object as the test part result reporter used // by Google Test. The 'result' parameter specifies where to report the // results. This reporter will only catch failures generated in the current // thread. DEPRECATED explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); // Same as above, but you can choose the interception scope of this object. ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, TestPartResultArray* result); // The d'tor restores the previous test part result reporter. virtual ~ScopedFakeTestPartResultReporter(); // Appends the TestPartResult object to the TestPartResultArray // received in the constructor. // // This method is from the TestPartResultReporterInterface // interface. virtual void ReportTestPartResult(const TestPartResult& result); private: void Init(); const InterceptMode intercept_mode_; TestPartResultReporterInterface* old_reporter_; TestPartResultArray* const result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); }; namespace internal { // A helper class for implementing EXPECT_FATAL_FAILURE() and // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. class GTEST_API_ SingleFailureChecker { public: // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, const string& substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; const TestPartResult::Type type_; const string substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; } // namespace internal } // namespace testing // A set of macros for testing Google Test assertions or code that's expected // to generate Google Test fatal failures. It verifies that the given // statement will cause exactly one fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_FATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - 'statement' cannot reference local non-static variables or // non-static members of the current object. // - 'statement' cannot return a value. // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. #define EXPECT_FATAL_FAILURE(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do { \ class GTestExpectFatalFailureHelper {\ public:\ static void Execute() { statement; }\ };\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ALL_THREADS, >est_failures);\ GTestExpectFatalFailureHelper::Execute();\ }\ } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given // statement will cause exactly one non-fatal Google Test failure with 'substr' // being part of the failure message. // // There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only // affects and considers failures generated in the current thread and // EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. // // 'statement' is allowed to reference local variables and members of // the current object. // // The verification of the assertion is done correctly even when the statement // throws an exception or aborts the current function. // // Known restrictions: // - You cannot stream a failure message to this macro. // // Note that even though the implementations of the following two // macros are much alike, we cannot refactor them to use a common // helper macro, due to some peculiarity in how the preprocessor // works. If we do that, the code won't compile when the user gives // EXPECT_NONFATAL_FAILURE() a statement that contains a macro that // expands to code containing an unprotected comma. The // AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc // catches that. // // For the same reason, we have to write // if (::testing::internal::AlwaysTrue()) { statement; } // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. #define EXPECT_NONFATAL_FAILURE(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter:: \ INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ do {\ ::testing::TestPartResultArray gtest_failures;\ ::testing::internal::SingleFailureChecker gtest_checker(\ >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ (substr));\ {\ ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ >est_failures);\ if (::testing::internal::AlwaysTrue()) { statement; }\ }\ } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-test-part.h000644 000766 000024 00000014555 12650222322 023026 0ustar00iojsstaff000000 000000 // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: mheule@google.com (Markus Heule) // #ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" namespace testing { // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. class GTEST_API_ TestPartResult { public: // The possible outcomes of a test part (i.e. an assertion or an // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). enum Type { kSuccess, // Succeeded. kNonFatalFailure, // Failed but the test can continue. kFatalFailure // Failed and the test should be terminated. }; // C'tor. TestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestPartResult object. TestPartResult(Type a_type, const char* a_file_name, int a_line_number, const char* a_message) : type_(a_type), file_name_(a_file_name == NULL ? "" : a_file_name), line_number_(a_line_number), summary_(ExtractSummary(a_message)), message_(a_message) { } // Gets the outcome of the test part. Type type() const { return type_; } // Gets the name of the source file where the test part took place, or // NULL if it's unknown. const char* file_name() const { return file_name_.empty() ? NULL : file_name_.c_str(); } // Gets the line in the source file where the test part took place, // or -1 if it's unknown. int line_number() const { return line_number_; } // Gets the summary of the failure message. const char* summary() const { return summary_.c_str(); } // Gets the message associated with the test part. const char* message() const { return message_.c_str(); } // Returns true iff the test part passed. bool passed() const { return type_ == kSuccess; } // Returns true iff the test part failed. bool failed() const { return type_ != kSuccess; } // Returns true iff the test part non-fatally failed. bool nonfatally_failed() const { return type_ == kNonFatalFailure; } // Returns true iff the test part fatally failed. bool fatally_failed() const { return type_ == kFatalFailure; } private: Type type_; // Gets the summary of the failure message by omitting the stack // trace in it. static std::string ExtractSummary(const char* message); // The name of the source file where the test part took place, or // "" if the source file is unknown. std::string file_name_; // The line in the source file where the test part took place, or -1 // if the line number is unknown. int line_number_; std::string summary_; // The test failure summary. std::string message_; // The test failure message. }; // Prints a TestPartResult object. std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // An array of TestPartResult objects. // // Don't inherit from TestPartResultArray as its destructor is not // virtual. class GTEST_API_ TestPartResultArray { public: TestPartResultArray() {} // Appends the given TestPartResult to the array. void Append(const TestPartResult& result); // Returns the TestPartResult at the given index (0-based). const TestPartResult& GetTestPartResult(int index) const; // Returns the number of TestPartResult objects in the array. int size() const; private: std::vector array_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; // This interface knows how to report a test part result. class TestPartResultReporterInterface { public: virtual ~TestPartResultReporterInterface() {} virtual void ReportTestPartResult(const TestPartResult& result) = 0; }; namespace internal { // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a // statement generates new fatal failures. To do so it registers itself as the // current test part result reporter. Besides checking if fatal failures were // reported, it only delegates the reporting to the former result reporter. // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. class GTEST_API_ HasNewFatalFailureHelper : public TestPartResultReporterInterface { public: HasNewFatalFailureHelper(); virtual ~HasNewFatalFailureHelper(); virtual void ReportTestPartResult(const TestPartResult& result); bool has_new_fatal_failure() const { return has_new_fatal_failure_; } private: bool has_new_fatal_failure_; TestPartResultReporterInterface* original_reporter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); }; } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ node-v4.2.6/deps/gtest/include/gtest/gtest-typed-test.h000644 000766 000024 00000024002 12650222322 023171 0ustar00iojsstaff000000 000000 // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ // This header implements typed tests and type-parameterized tests. // Typed (aka type-driven) tests repeat the same test for types in a // list. You must know which types you want to test with when writing // typed tests. Here's how you do it: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { public: ... typedef std::list List; static T shared_; T value_; }; // Next, associate a list of types with the test case, which will be // repeated for each type in the list. The typedef is necessary for // the macro to parse correctly. typedef testing::Types MyTypes; TYPED_TEST_CASE(FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // TYPED_TEST_CASE(FooTest, int); // Then, use TYPED_TEST() instead of TEST_F() to define as many typed // tests for this test case as you want. TYPED_TEST(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. // Since we are inside a derived class template, C++ requires use to // visit the members of FooTest via 'this'. TypeParam n = this->value_; // To visit static members of the fixture, add the TestFixture:: // prefix. n += TestFixture::shared_; // To refer to typedefs in the fixture, add the "typename // TestFixture::" prefix. typename TestFixture::List values; values.push_back(n); ... } TYPED_TEST(FooTest, HasPropertyA) { ... } #endif // 0 // Type-parameterized tests are abstract test patterns parameterized // by a type. Compared with typed tests, type-parameterized tests // allow you to define the test pattern without knowing what the type // parameters are. The defined pattern can be instantiated with // different types any number of times, in any number of translation // units. // // If you are designing an interface or concept, you can define a // suite of type-parameterized tests to verify properties that any // valid implementation of the interface/concept should have. Then, // each implementation can easily instantiate the test suite to verify // that it conforms to the requirements, without having to write // similar tests repeatedly. Here's an example: #if 0 // First, define a fixture class template. It should be parameterized // by a type. Remember to derive it from testing::Test. template class FooTest : public testing::Test { ... }; // Next, declare that you will define a type-parameterized test case // (the _P suffix is for "parameterized" or "pattern", whichever you // prefer): TYPED_TEST_CASE_P(FooTest); // Then, use TYPED_TEST_P() to define as many type-parameterized tests // for this type-parameterized test case as you want. TYPED_TEST_P(FooTest, DoesBlah) { // Inside a test, refer to TypeParam to get the type parameter. TypeParam n = 0; ... } TYPED_TEST_P(FooTest, HasPropertyA) { ... } // Now the tricky part: you need to register all test patterns before // you can instantiate them. The first argument of the macro is the // test case name; the rest are the names of the tests in this test // case. REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA); // Finally, you are free to instantiate the pattern with the types you // want. If you put the above code in a header file, you can #include // it in multiple C++ source files and instantiate it multiple times. // // To distinguish different instances of the pattern, the first // argument to the INSTANTIATE_* macro is a prefix that will be added // to the actual test case name. Remember to pick unique prefixes for // different instances. typedef testing::Types MyTypes; INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // If the type list contains only one type, you can write that type // directly without Types<...>: // INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); #endif // 0 #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-type-util.h" // Implements typed tests. #if GTEST_HAS_TYPED_TEST // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the typedef for the type parameters of the // given test case. # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define TYPED_TEST_CASE(CaseName, Types) \ typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) # define TYPED_TEST(CaseName, TestName) \ template \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTest< \ CaseName, \ ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ "", #CaseName, #TestName, 0); \ template \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() #endif // GTEST_HAS_TYPED_TEST // Implements type-parameterized tests. #if GTEST_HAS_TYPED_TEST_P // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. # define GTEST_CASE_NAMESPACE_(TestCaseName) \ gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. # define TYPED_TEST_CASE_P(CaseName) \ static ::testing::internal::TypedTestCasePState \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) # define TYPED_TEST_P(CaseName, TestName) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ template \ class TestName : public CaseName { \ private: \ typedef CaseName TestFixture; \ typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ __FILE__, __LINE__, #CaseName, #TestName); \ } \ template \ void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ } \ static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ __FILE__, __LINE__, #__VA_ARGS__) // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestCase::type>::Register(\ #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ node-v4.2.6/deps/gtest/include/gtest/gtest.h000644 000766 000024 00000257663 12650222322 021116 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // The Google C++ Testing Framework (Google Test) // // This header file defines the public API for Google Test. It should be // included by any test program that uses Google Test. // // IMPORTANT NOTE: Due to limitation of the C++ language, we have to // leave some internal implementation details in this header file. // They are clearly marked by comments like this: // // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // // Such code is NOT meant to be used by a user directly, and is subject // to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user // program! // // Acknowledgment: Google Test borrowed the idea of automatic test // registration from Barthelemy Dagenais' (barthelemy@prologique.com) // easyUnit framework. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_H_ #include #include #include #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" #include "gtest/gtest-death-test.h" #include "gtest/gtest-message.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest-printers.h" #include "gtest/gtest_prod.h" #include "gtest/gtest-test-part.h" #include "gtest/gtest-typed-test.h" // Depending on the platform, different string classes are available. // On Linux, in addition to ::std::string, Google also makes use of // class ::string, which has the same interface as ::std::string, but // has a different implementation. // // You can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that // ::string is available AND is a distinct type to ::std::string, or // define it to 0 to indicate otherwise. // // If ::std::string and ::string are the same class on your platform // due to aliasing, you should define GTEST_HAS_GLOBAL_STRING to 0. // // If you do not define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { // Declares the flags. // This flag temporary enables the disabled tests. GTEST_DECLARE_bool_(also_run_disabled_tests); // This flag brings the debugger on an assertion failure. GTEST_DECLARE_bool_(break_on_failure); // This flag controls whether Google Test catches all test-thrown exceptions // and logs them as failures. GTEST_DECLARE_bool_(catch_exceptions); // This flag enables using colors in terminal output. Available values are // "yes" to enable colors, "no" (disable colors), or "auto" (the default) // to let Google Test decide. GTEST_DECLARE_string_(color); // This flag sets up the filter to select by name using a glob pattern // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); // This flag causes the Google Test to list tests. None of the tests listed // are actually run if the flag is provided. GTEST_DECLARE_bool_(list_tests); // This flag controls whether Google Test emits a detailed XML report to a file // in addition to its normal textual output. GTEST_DECLARE_string_(output); // This flags control whether Google Test prints the elapsed time for each // test. GTEST_DECLARE_bool_(print_time); // This flag specifies the random number seed. GTEST_DECLARE_int32_(random_seed); // This flag sets how many times the tests are repeated. The default value // is 1. If the value is -1 the tests are repeating forever. GTEST_DECLARE_int32_(repeat); // This flag controls whether Google Test includes Google Test internal // stack frames in failure stack traces. GTEST_DECLARE_bool_(show_internal_stack_frames); // When this flag is specified, tests' order is randomized on every iteration. GTEST_DECLARE_bool_(shuffle); // This flag specifies the maximum number of stack frames to be // printed in a failure message. GTEST_DECLARE_int32_(stack_trace_depth); // When this flag is specified, a failed assertion will throw an // exception if exceptions are enabled, or exit the program with a // non-zero code otherwise. GTEST_DECLARE_bool_(throw_on_failure); // When this flag is set with a "host:port" string, on supported // platforms test results are streamed to the specified port on // the specified host machine. GTEST_DECLARE_string_(stream_result_to); // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; namespace internal { class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; class StreamingListenerTest; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; class UnitTestRecordPropertyTestHelper; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); } // namespace internal // The friend relationship of some of these classes is cyclic. // If we don't forward declare them the compiler might confuse the classes // in friendship clauses with same named classes on the scope. class Test; class TestCase; class TestInfo; class UnitTest; // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object // remembers a non-empty message that describes how it failed. // // To create an instance of this class, use one of the factory functions // (AssertionSuccess() and AssertionFailure()). // // This class is useful for two purposes: // 1. Defining predicate functions to be used with Boolean test assertions // EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts // 2. Defining predicate-format functions to be // used with predicate assertions (ASSERT_PRED_FORMAT*, etc). // // For example, if you define IsEven predicate: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) // will print the message // // Value of: IsEven(Fib(5)) // Actual: false (5 is odd) // Expected: true // // instead of a more opaque // // Value of: IsEven(Fib(5)) // Actual: false // Expected: true // // in case IsEven is a simple Boolean predicate. // // If you expect your predicate to be reused and want to support informative // messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up // about half as often as positive ones in our tests), supply messages for // both success and failure cases: // // testing::AssertionResult IsEven(int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess() << n << " is even"; // else // return testing::AssertionFailure() << n << " is odd"; // } // // Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print // // Value of: IsEven(Fib(6)) // Actual: true (8 is even) // Expected: false // // NB: Predicates that support negative Boolean assertions have reduced // performance in positive ones so be careful not to use them in tests // that have lots (tens of thousands) of positive Boolean assertions. // // To use this class with EXPECT_PRED_FORMAT assertions such as: // // // Verifies that Foo() returns an even number. // EXPECT_PRED_FORMAT1(IsEven, Foo()); // // you need to define: // // testing::AssertionResult IsEven(const char* expr, int n) { // if ((n % 2) == 0) // return testing::AssertionSuccess(); // else // return testing::AssertionFailure() // << "Expected: " << expr << " is even\n Actual: it's " << n; // } // // If Foo() returns 5, you will see the following message: // // Expected: Foo() is even // Actual: it's 5 // class GTEST_API_ AssertionResult { public: // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) // Used in the EXPECT_TRUE/FALSE(bool_expression). // // T must be contextually convertible to bool. // // The second parameter prevents this overload from being considered if // the argument is implicitly convertible to AssertionResult. In that case // we want AssertionResult's copy constructor to be used. template explicit AssertionResult( const T& success, typename internal::EnableIf< !internal::ImplicitlyConvertible::value>::type* /*enabler*/ = NULL) : success_(success) {} GTEST_DISABLE_MSC_WARNINGS_POP_() // Assignment operator. AssertionResult& operator=(AssertionResult other) { swap(other); return *this; } // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult operator!() const; // Returns the text streamed into this AssertionResult. Test assertions // use it when they fail (i.e., the predicate's outcome doesn't match the // assertion's expectation). When nothing has been streamed into the // object, returns an empty string. const char* message() const { return message_.get() != NULL ? message_->c_str() : ""; } // TODO(vladl@google.com): Remove this after making sure no clients use it. // Deprecated; please use message() instead. const char* failure_message() const { return message(); } // Streams a custom failure message into this object. template AssertionResult& operator<<(const T& value) { AppendMessage(Message() << value); return *this; } // Allows streaming basic output manipulators such as endl or flush into // this object. AssertionResult& operator<<( ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { AppendMessage(Message() << basic_manipulator); return *this; } private: // Appends the contents of message to message_. void AppendMessage(const Message& a_message) { if (message_.get() == NULL) message_.reset(new ::std::string); message_->append(a_message.GetString().c_str()); } // Swap the contents of this AssertionResult with other. void swap(AssertionResult& other); // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation // construct is not satisfied with the predicate's outcome. // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. internal::scoped_ptr< ::std::string> message_; }; // Makes a successful assertion result. GTEST_API_ AssertionResult AssertionSuccess(); // Makes a failed assertion result. GTEST_API_ AssertionResult AssertionFailure(); // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << msg. GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // The abstract class that all tests inherit from. // // In Google Test, a unit test program contains one or many TestCases, and // each TestCase contains one or many Tests. // // When you define a test using the TEST macro, you don't need to // explicitly derive from Test - the TEST macro automatically does // this for you. // // The only time you derive from Test is when defining a test fixture // to be used a TEST_F. For example: // // class FooTest : public testing::Test { // protected: // void SetUp() override { ... } // void TearDown() override { ... } // ... // }; // // TEST_F(FooTest, Bar) { ... } // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. class GTEST_API_ Test { public: friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; // The d'tor is virtual as we intend to inherit from Test. virtual ~Test(); // Sets up the stuff shared by all tests in this test case. // // Google Test will call Foo::SetUpTestCase() before running the first // test in test case Foo. Hence a sub-class can define its own // SetUpTestCase() method to shadow the one defined in the super // class. static void SetUpTestCase() {} // Tears down the stuff shared by all tests in this test case. // // Google Test will call Foo::TearDownTestCase() after running the last // test in test case Foo. Hence a sub-class can define its own // TearDownTestCase() method to shadow the one defined in the super // class. static void TearDownTestCase() {} // Returns true iff the current test has a fatal failure. static bool HasFatalFailure(); // Returns true iff the current test has a non-fatal failure. static bool HasNonfatalFailure(); // Returns true iff the current test has a (either fatal or // non-fatal) failure. static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } // Logs a property for the current test, test case, or for the entire // invocation of the test program when used outside of the context of a // test case. Only the last value for a given key is remembered. These // are public static so they can be called from utility functions that are // not members of the test fixture. Calls to RecordProperty made during // lifespan of the test (from the moment its constructor starts to the // moment its destructor finishes) will be output in XML as attributes of // the element. Properties recorded from fixture's // SetUpTestCase or TearDownTestCase are logged as attributes of the // corresponding element. Calls to RecordProperty made in the // global context (before or after invocation of RUN_ALL_TESTS and from // SetUp/TearDown method of Environment objects registered with Google // Test) will be output as attributes of the element. static void RecordProperty(const std::string& key, const std::string& value); static void RecordProperty(const std::string& key, int value); protected: // Creates a Test object. Test(); // Sets up the test fixture. virtual void SetUp(); // Tears down the test fixture. virtual void TearDown(); private: // Returns true iff the current test has the same fixture class as // the first test in the current test case. static bool HasSameFixtureClass(); // Runs the test after the test fixture has been set up. // // A sub-class must implement this to define the test logic. // // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. // Instead, use the TEST or TEST_F macro. virtual void TestBody() = 0; // Sets up, executes, and tears down the test. void Run(); // Deletes self. We deliberately pick an unusual name for this // internal method to avoid clashing with names used in user TESTs. void DeleteSelf_() { delete this; } // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; // Often a user misspells SetUp() as Setup() and spends a long time // wondering why it is never called by Google Test. The declaration of // the following method is solely for catching such an error at // compile time: // // - The return type is deliberately chosen to be not void, so it // will be a conflict if void Setup() is declared in the user's // test fixture. // // - This method is private, so it will be another compiler error // if the method is called from the user's test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } // We disallow copying Tests. GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; typedef internal::TimeInMillis TimeInMillis; // A copyable object representing a user specified test property which can be // output as a key/value string pair. // // Don't inherit from TestProperty as its destructor is not virtual. class TestProperty { public: // C'tor. TestProperty does NOT have a default constructor. // Always use this constructor (with parameters) to create a // TestProperty object. TestProperty(const std::string& a_key, const std::string& a_value) : key_(a_key), value_(a_value) { } // Gets the user supplied key. const char* key() const { return key_.c_str(); } // Gets the user supplied value. const char* value() const { return value_.c_str(); } // Sets a new value, overriding the one supplied in the constructor. void SetValue(const std::string& new_value) { value_ = new_value; } private: // The key supplied by the user. std::string key_; // The value supplied by the user. std::string value_; }; // The result of a single Test. This includes a list of // TestPartResults, a list of TestProperties, a count of how many // death tests there are in the Test, and how much time it took to run // the Test. // // TestResult is not copyable. class GTEST_API_ TestResult { public: // Creates an empty TestResult. TestResult(); // D'tor. Do not inherit from TestResult. ~TestResult(); // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. int total_part_count() const; // Returns the number of the test properties. int test_property_count() const; // Returns true iff the test passed (i.e. no test part failed). bool Passed() const { return !Failed(); } // Returns true iff the test failed. bool Failed() const; // Returns true iff the test fatally failed. bool HasFatalFailure() const; // Returns true iff the test has a non-fatal failure. bool HasNonfatalFailure() const; // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test part result among all the results. i can range // from 0 to test_property_count() - 1. If i is not in that range, aborts // the program. const TestPartResult& GetTestPartResult(int i) const; // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. const TestProperty& GetTestProperty(int i) const; private: friend class TestInfo; friend class TestCase; friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; // Gets the vector of TestPartResults. const std::vector& test_part_results() const { return test_part_results_; } // Gets the vector of TestProperties. const std::vector& test_properties() const { return test_properties_; } // Sets the elapsed time. void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } // Adds a test property to the list. The property is validated and may add // a non-fatal failure if invalid (e.g., if it conflicts with reserved // key names). If a property is already recorded for the same key, the // value will be updated, rather than storing multiple values for the same // key. xml_element specifies the element for which the property is being // recorded and is used for validation. void RecordProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a failure if the key is a reserved attribute of Google Test // testcase tags. Returns true if the property is valid. // TODO(russr): Validate attribute names are legal and human readable. static bool ValidateTestProperty(const std::string& xml_element, const TestProperty& test_property); // Adds a test part result to the list. void AddTestPartResult(const TestPartResult& test_part_result); // Returns the death test count. int death_test_count() const { return death_test_count_; } // Increments the death test count, returning the new count. int increment_death_test_count() { return ++death_test_count_; } // Clears the test part results. void ClearTestPartResults(); // Clears the object. void Clear(); // Protects mutable state of the property vector and of owned // properties, whose values may be updated. internal::Mutex test_properites_mutex_; // The vector of TestPartResults std::vector test_part_results_; // The vector of TestProperties std::vector test_properties_; // Running count of death tests. int death_test_count_; // The elapsed time, in milliseconds. TimeInMillis elapsed_time_; // We disallow copying TestResult. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult // A TestInfo object stores the following information about a test: // // Test case name // Test name // Whether the test should be run // A function pointer that creates the test object when invoked // Test result // // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. class GTEST_API_ TestInfo { public: // Destructs a TestInfo object. This function is not virtual, so // don't inherit from TestInfo. ~TestInfo(); // Returns the test case name. const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a typed // or a type-parameterized test. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns the text representation of the value parameter, or NULL if this // is not a value-parameterized test. const char* value_param() const { if (value_param_.get() != NULL) return value_param_->c_str(); return NULL; } // Returns true if this test should run, that is if the test is not // disabled (or it is disabled but the also_run_disabled_tests flag has // been specified) and its full name matches the user-specified filter. // // Google Test allows the user to filter the tests by their full names. // The full name of a test Bar in test case Foo is defined as // "Foo.Bar". Only the tests that match the filter will run. // // A filter is a colon-separated list of glob (not regex) patterns, // optionally followed by a '-' and a colon-separated list of // negative patterns (tests to exclude). A test is run if it // matches one of the positive patterns and does not match any of // the negative patterns. // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". bool should_run() const { return should_run_; } // Returns true iff this test will appear in the XML report. bool is_reportable() const { // For now, the XML report includes all tests matching the filter. // In the future, we may trim tests that are excluded because of // sharding. return matches_filter_; } // Returns the result of the test. const TestResult* result() const { return &result_; } private: #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; friend class internal::UnitTestImpl; friend class internal::StreamingListenerTest; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const std::string& test_case_name, const std::string& name, const char* a_type_param, // NULL if not a type-parameterized test const char* a_value_param, // NULL if not a value-parameterized test internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); // Increments the number of death tests encountered in this test so // far. int increment_death_test_count() { return result_.increment_death_test_count(); } // Creates the test object, runs it, records its result, and then // deletes it. void Run(); static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } // These fields are immutable properties of the test. const std::string test_case_name_; // Test case name const std::string name_; // Test name // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr value_param_; const internal::TypeId fixture_class_id_; // ID of the test fixture class bool should_run_; // True iff this test should run bool is_disabled_; // True iff this test is disabled bool matches_filter_; // True if this test matches the // user-specified filter. internal::TestFactoryBase* const factory_; // The factory that creates // the test object // This field is mutable and needs to be reset before running the // test for the second time. TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. class GTEST_API_ TestCase { public: // Creates a TestCase with the given name. // // TestCase does NOT have a default constructor. Always use this // constructor to create a TestCase object. // // Arguments: // // name: name of the test case // a_type_param: the name of the test's type parameter, or NULL if // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase(const char* name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); // Destructor of TestCase. virtual ~TestCase(); // Gets the name of the TestCase. const char* name() const { return name_.c_str(); } // Returns the name of the parameter type, or NULL if this is not a // type-parameterized test case. const char* type_param() const { if (type_param_.get() != NULL) return type_param_->c_str(); return NULL; } // Returns true if any test in this test case should run. bool should_run() const { return should_run_; } // Gets the number of successful tests in this test case. int successful_test_count() const; // Gets the number of failed tests in this test case. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests in this test case. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Get the number of tests in this test case that should run. int test_to_run_count() const; // Gets the number of all tests in this test case. int total_test_count() const; // Returns true iff the test case passed. bool Passed() const { return !Failed(); } // Returns true iff the test case failed. bool Failed() const { return failed_test_count() > 0; } // Returns the elapsed time, in milliseconds. TimeInMillis elapsed_time() const { return elapsed_time_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. const TestInfo* GetTestInfo(int i) const; // Returns the TestResult that holds test properties recorded during // execution of SetUpTestCase and TearDownTestCase. const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } private: friend class Test; friend class internal::UnitTestImpl; // Gets the (mutable) vector of TestInfos in this TestCase. std::vector& test_info_list() { return test_info_list_; } // Gets the (immutable) vector of TestInfos in this TestCase. const std::vector& test_info_list() const { return test_info_list_; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. TestInfo* GetMutableTestInfo(int i); // Sets the should_run member. void set_should_run(bool should) { should_run_ = should; } // Adds a TestInfo to this test case. Will delete the TestInfo upon // destruction of the TestCase object. void AddTestInfo(TestInfo * test_info); // Clears the results of all tests in this test case. void ClearResult(); // Clears the results of all tests in the given test case. static void ClearTestCaseResult(TestCase* test_case) { test_case->ClearResult(); } // Runs every test in this TestCase. void Run(); // Runs SetUpTestCase() for this TestCase. This wrapper is needed // for catching exceptions thrown from SetUpTestCase(). void RunSetUpTestCase() { (*set_up_tc_)(); } // Runs TearDownTestCase() for this TestCase. This wrapper is // needed for catching exceptions thrown from TearDownTestCase(). void RunTearDownTestCase() { (*tear_down_tc_)(); } // Returns true iff test passed. static bool TestPassed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Passed(); } // Returns true iff test failed. static bool TestFailed(const TestInfo* test_info) { return test_info->should_run() && test_info->result()->Failed(); } // Returns true iff the test is disabled and will be reported in the XML // report. static bool TestReportableDisabled(const TestInfo* test_info) { return test_info->is_reportable() && test_info->is_disabled_; } // Returns true iff test is disabled. static bool TestDisabled(const TestInfo* test_info) { return test_info->is_disabled_; } // Returns true iff this test will appear in the XML report. static bool TestReportable(const TestInfo* test_info) { return test_info->is_reportable(); } // Returns true if the given test should run. static bool ShouldRunTest(const TestInfo* test_info) { return test_info->should_run(); } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); // Restores the test order to before the first shuffle. void UnshuffleTests(); // Name of the test case. std::string name_; // Name of the parameter type, or NULL if this is not a typed or a // type-parameterized test. const internal::scoped_ptr type_param_; // The vector of TestInfos in their original order. It owns the // elements in the vector. std::vector test_info_list_; // Provides a level of indirection for the test list to allow easy // shuffling and restoring the test order. The i-th element in this // vector is the index of the i-th test in the shuffled test list. std::vector test_indices_; // Pointer to the function that sets up the test case. Test::SetUpTestCaseFunc set_up_tc_; // Pointer to the function that tears down the test case. Test::TearDownTestCaseFunc tear_down_tc_; // True iff any test in this test case should run. bool should_run_; // Elapsed time, in milliseconds. TimeInMillis elapsed_time_; // Holds test properties recorded during execution of SetUpTestCase and // TearDownTestCase. TestResult ad_hoc_test_result_; // We disallow copying TestCases. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; // An Environment object is capable of setting up and tearing down an // environment. You should subclass this to define your own // environment(s). // // An Environment object does the set-up and tear-down in virtual // methods SetUp() and TearDown() instead of the constructor and the // destructor, as: // // 1. You cannot safely throw from a destructor. This is a problem // as in some cases Google Test is used where exceptions are enabled, and // we may want to implement ASSERT_* using exceptions where they are // available. // 2. You cannot use ASSERT_* directly in a constructor or // destructor. class Environment { public: // The d'tor is virtual as we need to subclass Environment. virtual ~Environment() {} // Override this to define how to set up the environment. virtual void SetUp() {} // Override this to define how to tear down the environment. virtual void TearDown() {} private: // If you see an error about overriding the following function or // about it being private, you have mis-spelled SetUp() as Setup(). struct Setup_should_be_spelled_SetUp {}; virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. class TestEventListener { public: virtual ~TestEventListener() {} // Fired before any test activity starts. virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; // Fired before each iteration of tests starts. There may be more than // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration // index, starting from 0. virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration) = 0; // Fired before environment set-up for each iteration of tests starts. virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; // Fired after environment set-up for each iteration of tests ends. virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; // Fired before the test case starts. virtual void OnTestCaseStart(const TestCase& test_case) = 0; // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; // Fired after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. virtual void OnTestEnd(const TestInfo& test_info) = 0; // Fired after the test case ends. virtual void OnTestCaseEnd(const TestCase& test_case) = 0; // Fired before environment tear-down for each iteration of tests starts. virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; // Fired after environment tear-down for each iteration of tests ends. virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; // Fired after each iteration of tests finishes. virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration) = 0; // Fired after all test activities have ended. virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; }; // The convenience class for users who need to override just one or two // methods and are not concerned that a possible change to a signature of // the methods they override will not be caught during the build. For // comments about each method please see the definition of TestEventListener // above. class EmptyTestEventListener : public TestEventListener { public: virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} virtual void OnTestStart(const TestInfo& /*test_info*/) {} virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} virtual void OnTestEnd(const TestInfo& /*test_info*/) {} virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, int /*iteration*/) {} virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; // TestEventListeners lets users add listeners to track events in Google Test. class GTEST_API_ TestEventListeners { public: TestEventListeners(); ~TestEventListeners(); // Appends an event listener to the end of the list. Google Test assumes // the ownership of the listener (i.e. it will delete the listener when // the test program finishes). void Append(TestEventListener* listener); // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. TestEventListener* Release(TestEventListener* listener); // Returns the standard listener responsible for the default console // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the caller and makes this // function return NULL the next time. TestEventListener* default_result_printer() const { return default_result_printer_; } // Returns the standard listener responsible for the default XML output // controlled by the --gtest_output=xml flag. Can be removed from the // listeners list by users who want to shut down the default XML output // controlled by this flag and substitute it with custom one. Note that // removing this object from the listener list with Release transfers its // ownership to the caller and makes this function return NULL the next // time. TestEventListener* default_xml_generator() const { return default_xml_generator_; } private: friend class TestCase; friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all // subscribers. TestEventListener* repeater(); // Sets the default_result_printer attribute to the provided listener. // The listener is also added to the listener list and previous // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultResultPrinter(TestEventListener* listener); // Sets the default_xml_generator attribute to the provided listener. The // listener is also added to the listener list and previous // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. void SetDefaultXmlGenerator(TestEventListener* listener); // Controls whether events will be forwarded by the repeater to the // listeners in the list. bool EventForwardingEnabled() const; void SuppressEventForwarding(); // The actual list of listeners. internal::TestEventRepeater* repeater_; // Listener responsible for the standard result output. TestEventListener* default_result_printer_; // Listener responsible for the creation of the XML output file. TestEventListener* default_xml_generator_; // We disallow copying TestEventListeners. GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); }; // A UnitTest consists of a vector of TestCases. // // This is a singleton class. The only instance of UnitTest is // created when UnitTest::GetInstance() is first called. This // instance is never deleted. // // UnitTest is not copyable. // // This class is thread-safe as long as the methods are called // according to their specification. class GTEST_API_ UnitTest { public: // Gets the singleton UnitTest object. The first time this method // is called, a UnitTest object is constructed and returned. // Consecutive calls will return the same object. static UnitTest* GetInstance(); // Runs all tests in this UnitTest object and prints the result. // Returns 0 if successful, or 1 otherwise. // // This method can only be called from the main thread. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. int Run() GTEST_MUST_USE_RESULT_; // Returns the working directory when the first TEST() or TEST_F() // was executed. The UnitTest object owns the string. const char* original_working_dir() const; // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* current_test_info() const GTEST_LOCK_EXCLUDED_(mutex_); // Returns the random seed used at the start of the current test run. int random_seed() const; #if GTEST_HAS_PARAM_TEST // Returns the ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::ParameterizedTestCaseRegistry& parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST // Gets the number of successful test cases. int successful_test_case_count() const; // Gets the number of failed test cases. int failed_test_case_count() const; // Gets the number of all test cases. int total_test_case_count() const; // Gets the number of all test cases that contain at least one test // that should run. int test_case_to_run_count() const; // Gets the number of successful tests. int successful_test_count() const; // Gets the number of failed tests. int failed_test_count() const; // Gets the number of disabled tests that will be reported in the XML report. int reportable_disabled_test_count() const; // Gets the number of disabled tests. int disabled_test_count() const; // Gets the number of tests to be printed in the XML report. int reportable_test_count() const; // Gets the number of all tests. int total_test_count() const; // Gets the number of tests that should run. int test_to_run_count() const; // Gets the time of the test program start, in ms from the start of the // UNIX epoch. TimeInMillis start_timestamp() const; // Gets the elapsed time, in milliseconds. TimeInMillis elapsed_time() const; // Returns true iff the unit test passed (i.e. all test cases passed). bool Passed() const; // Returns true iff the unit test failed (i.e. some test case failed // or something outside of all tests failed). bool Failed() const; // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. const TestCase* GetTestCase(int i) const; // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. const TestResult& ad_hoc_test_result() const; // Returns the list of event listeners that can be used to track events // inside Google Test. TestEventListeners& listeners(); private: // Registers and returns a global test environment. When a test // program is run, all global test environments will be set-up in // the order they were registered. After all tests in the program // have finished, all global test environments will be torn-down in // the *reverse* order they were registered. // // The UnitTest object takes ownership of the given environment. // // This method can only be called from the main thread. Environment* AddEnvironment(Environment* env); // Adds a TestPartResult to the current TestResult object. All // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) // eventually call this to report their results. The user code // should use the assertion macros instead of calling this directly. void AddTestPartResult(TestPartResult::Type result_type, const char* file_name, int line_number, const std::string& message, const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_); // Adds a TestProperty to the current TestResult object when invoked from // inside a test, to current TestCase's ad_hoc_test_result_ when invoked // from SetUpTestCase or TearDownTestCase, or to the global property set // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void RecordProperty(const std::string& key, const std::string& value); // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. TestCase* GetMutableTestCase(int i); // Accessors for the implementation object. internal::UnitTestImpl* impl() { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; } // These classes and funcions are friends as they need to access private // members of UnitTest. friend class Test; friend class internal::AssertHelper; friend class internal::ScopedTrace; friend class internal::StreamingListenerTest; friend class internal::UnitTestRecordPropertyTestHelper; friend Environment* AddGlobalTestEnvironment(Environment* env); friend internal::UnitTestImpl* internal::GetUnitTestImpl(); friend void internal::ReportFailureInUnknownLocation( TestPartResult::Type result_type, const std::string& message); // Creates an empty UnitTest. UnitTest(); // D'tor virtual ~UnitTest(); // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void PushGTestTrace(const internal::TraceInfo& trace) GTEST_LOCK_EXCLUDED_(mutex_); // Pops a trace from the per-thread Google Test trace stack. void PopGTestTrace() GTEST_LOCK_EXCLUDED_(mutex_); // Protects mutable state in *impl_. This is mutable as some const // methods need to lock it too. mutable internal::Mutex mutex_; // Opaque implementation object. This field is never changed once // the object is constructed. We don't mark it as const here, as // doing so will cause a warning in the constructor of UnitTest. // Mutable state in *impl_ is protected by mutex_. internal::UnitTestImpl* impl_; // We disallow copying UnitTest. GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); }; // A convenient wrapper for adding an environment for the test // program. // // You should call this before RUN_ALL_TESTS() is called, probably in // main(). If you use gtest_main, you need to call this before main() // starts for it to take effect. For example, you can define a global // variable like this: // // testing::Environment* const foo_env = // testing::AddGlobalTestEnvironment(new FooEnvironment); // // However, we strongly recommend you to write your own main() and // call AddGlobalTestEnvironment() there, as relying on initialization // of global variables makes the code harder to read and may cause // problems when you register multiple environments from different // translation units and the environments have dependencies among them // (remember that the compiler doesn't guarantee the order in which // global variables from different translation units are initialized). inline Environment* AddGlobalTestEnvironment(Environment* env) { return UnitTest::GetInstance()->AddEnvironment(env); } // Initializes Google Test. This must be called before calling // RUN_ALL_TESTS(). In particular, it parses a command line for the // flags that Google Test recognizes. Whenever a Google Test flag is // seen, it is removed from argv, and *argc is decremented. // // No value is returned. Instead, the Google Test flag variables are // updated. // // Calling the function for the second time has no user-visible effect. GTEST_API_ void InitGoogleTest(int* argc, char** argv); // This overloaded version can be used in Windows programs compiled in // UNICODE mode. GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { // FormatForComparison::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in // the comparison, and is used to help determine the best way to // format the value. In particular, when the value is a C string // (char pointer) and the other operand is an STL string object, we // want to format the C string as a string, since we know it is // compared by value with the string object. If the value is a char // pointer but the other operand is not an STL string object, we don't // know whether the pointer is supposed to point to a NUL-terminated // string, and thus want to print it as a pointer to be safe. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // The default case. template class FormatForComparison { public: static ::std::string Format(const ToPrint& value) { return ::testing::PrintToString(value); } }; // Array. template class FormatForComparison { public: static ::std::string Format(const ToPrint* value) { return FormatForComparison::Format(value); } }; // By default, print C string as pointers to be safe, as we don't know // whether they actually point to a NUL-terminated string. #define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ template \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(static_cast(value)); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); #undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_ // If a C string is compared with an STL string object, we know it's meant // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ template <> \ class FormatForComparison { \ public: \ static ::std::string Format(CharType* value) { \ return ::testing::PrintToString(value); \ } \ } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); #if GTEST_HAS_GLOBAL_STRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string); #endif #if GTEST_HAS_GLOBAL_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring); #endif #if GTEST_HAS_STD_WSTRING GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); #endif #undef GTEST_IMPL_FORMAT_C_STRING_AS_STRING_ // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // operand to be used in a failure message. The type (but not value) // of the other operand may affect the format. This allows us to // print a char* as a raw pointer when it is compared against another // char* or void*, and print it as a C string when it is compared // against an std::string object, for example. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template std::string FormatForComparisonFailureMessage( const T1& value, const T2& /* other_operand */) { return FormatForComparison::Format(value); } // Separate the error generating code from the code path to reduce the stack // frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers // when calling EXPECT_* in a tight loop. template AssertionResult CmpHelperEQFailure(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { return EqFailure(expected_expression, actual_expression, FormatForComparisonFailureMessage(expected, actual), FormatForComparisonFailureMessage(actual, expected), false); } // The helper function for {ASSERT|EXPECT}_EQ. template AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */) if (expected == actual) { return AssertionSuccess(); } GTEST_DISABLE_MSC_WARNINGS_POP_() return CmpHelperEQFailure(expected_expression, actual_expression, expected, actual); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() // is a null pointer literal. The following default implementation is // for lhs_is_null_literal being false. template class EqHelper { public: // This templatized version is for the general case. template static AssertionResult Compare(const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous // enums can be implicitly cast to BiggestInt. // // Even though its body looks the same as the above version, we // cannot merge the two, as it will make anonymous enums unhappy. static AssertionResult Compare(const char* expected_expression, const char* actual_expression, BiggestInt expected, BiggestInt actual) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } }; // This specialization is used when the first argument to ASSERT_EQ() // is a null pointer literal, like NULL, false, or 0. template <> class EqHelper { public: // We define two overloaded versions of Compare(). The first // version will be picked when the second argument to ASSERT_EQ() is // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or // EXPECT_EQ(false, a_bool). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, const T1& expected, const T2& actual, // The following line prevents this overload from being considered if T2 // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) // expands to Compare("", "", NULL, my_ptr), which requires a conversion // to match the Secret* in the other overload, which would otherwise make // this template match better. typename EnableIf::value>::type* = 0) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } // This version will be picked when the second argument to ASSERT_EQ() is a // pointer, e.g. ASSERT_EQ(NULL, a_pointer). template static AssertionResult Compare( const char* expected_expression, const char* actual_expression, // We used to have a second template parameter instead of Secret*. That // template parameter would deduce to 'long', making this a better match // than the first overload even without the first overload's EnableIf. // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to // non-pointer argument" (even a deduced integral argument), so the old // implementation caused warnings in user code. Secret* /* expected (NULL) */, T* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, static_cast(NULL), actual); } }; // Separate the error generating code from the code path to reduce the stack // frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers // when calling EXPECT_OP in a tight loop. template AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, const T1& val1, const T2& val2, const char* op) { return AssertionFailure() << "Expected: (" << expr1 << ") " << op << " (" << expr2 << "), actual: " << FormatForComparisonFailureMessage(val1, val2) << " vs " << FormatForComparisonFailureMessage(val2, val1); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste // of similar code. // // For each templatized helper function, we also define an overloaded // version for BiggestInt in order to reduce code bloat and allow // anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ template \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ const T1& val1, const T2& val2) {\ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // Implements the helper function for {ASSERT|EXPECT}_NE GTEST_IMPL_CMP_HELPER_(NE, !=); // Implements the helper function for {ASSERT|EXPECT}_LE GTEST_IMPL_CMP_HELPER_(LE, <=); // Implements the helper function for {ASSERT|EXPECT}_LT GTEST_IMPL_CMP_HELPER_(LT, <); // Implements the helper function for {ASSERT|EXPECT}_GE GTEST_IMPL_CMP_HELPER_(GE, >=); // Implements the helper function for {ASSERT|EXPECT}_GT GTEST_IMPL_CMP_HELPER_(GT, >); #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, const char* actual_expression, const char* expected, const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, const char* s2_expression, const char* s1, const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, const char* actual_expression, const wchar_t* expected, const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, const char* s2_expression, const wchar_t* s1, const wchar_t* s2); } // namespace internal // IsSubstring() and IsNotSubstring() are intended to be used as the // first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by // themselves. They check whether needle is a substring of haystack // (NULL is considered a substring of itself only), and return an // appropriate error message when they fail. // // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::string& needle, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING GTEST_API_ AssertionResult IsSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); GTEST_API_ AssertionResult IsNotSubstring( const char* needle_expr, const char* haystack_expr, const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING namespace internal { // Helper template function for comparing floating-points. // // Template parameter: // // RawType: the raw floating-point type (either float or double) // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, const char* actual_expression, RawType expected, RawType actual) { const FloatingPoint lhs(expected), rhs(actual); if (lhs.AlmostEquals(rhs)) { return AssertionSuccess(); } ::std::stringstream expected_ss; expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) << expected; ::std::stringstream actual_ss; actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) << actual; return EqFailure(expected_expression, actual_expression, StringStreamToString(&expected_ss), StringStreamToString(&actual_ss), false); } // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, const char* expr2, const char* abs_error_expr, double val1, double val2, double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros class GTEST_API_ AssertHelper { public: // Constructor. AssertHelper(TestPartResult::Type type, const char* file, int line, const char* message); ~AssertHelper(); // Message assignment is a semantic trick to enable assertion // streaming; see the GTEST_MESSAGE_ macro below. void operator=(const Message& message) const; private: // We put our data in a struct so that the size of the AssertHelper class can // be as small as possible. This is important because gcc is incapable of // re-using stack space even for temporary variables, so every EXPECT_EQ // reserves stack space for another AssertHelper. struct AssertHelperData { AssertHelperData(TestPartResult::Type t, const char* srcfile, int line_num, const char* msg) : type(t), file(srcfile), line(line_num), message(msg) { } TestPartResult::Type const type; const char* const file; int const line; std::string const message; private: GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); }; AssertHelperData* const data_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal #if GTEST_HAS_PARAM_TEST // The pure interface class that all value-parameterized tests inherit from. // A value-parameterized class must inherit from both ::testing::Test and // ::testing::WithParamInterface. In most cases that just means inheriting // from ::testing::TestWithParam, but more complicated test hierarchies // may need to inherit from Test and WithParamInterface at different levels. // // This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), // Values(), ValuesIn(), Bool(), and Combine(). // // class FooTest : public ::testing::TestWithParam { // protected: // FooTest() { // // Can use GetParam() here. // } // virtual ~FooTest() { // // Can use GetParam() here. // } // virtual void SetUp() { // // Can use GetParam() here. // } // virtual void TearDown { // // Can use GetParam() here. // } // }; // TEST_P(FooTest, DoesBar) { // // Can use GetParam() method here. // Foo foo; // ASSERT_TRUE(foo.DoesBar(GetParam())); // } // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template class WithParamInterface { public: typedef T ParamType; virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's // constructor. This member function is non-static, even though it only // references static data, to reduce the opportunity for incorrect uses // like writing 'WithParamInterface::GetParam()' for a test that // uses a fixture whose parameter type is int. const ParamType& GetParam() const { GTEST_CHECK_(parameter_ != NULL) << "GetParam() can only be called inside a value-parameterized test " << "-- did you intend to write TEST_P instead of TEST_F?"; return *parameter_; } private: // Sets parameter value. The caller is responsible for making sure the value // remains alive and unchanged throughout the current test. static void SetParam(const ParamType* parameter) { parameter_ = parameter; } // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template const T* WithParamInterface::parameter_ = NULL; // Most value-parameterized classes can ignore the existence of // WithParamInterface, and can just inherit from ::testing::TestWithParam. template class TestWithParam : public Test, public WithParamInterface { }; #endif // GTEST_HAS_PARAM_TEST // Macros for indicating success/failure in test code. // ADD_FAILURE unconditionally adds a failure to the current test. // SUCCEED generates a success - it doesn't automatically make the // current test successful, as a test is only successful when it has // no failure. // // EXPECT_* verifies that a certain condition is satisfied. If not, // it behaves like ADD_FAILURE. In particular: // // EXPECT_TRUE verifies that a Boolean condition is true. // EXPECT_FALSE verifies that a Boolean condition is false. // // FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except // that they will also abort the current function on failure. People // usually want the fail-fast behavior of FAIL and ASSERT_*, but those // writing data-driven tests often find themselves using ADD_FAILURE // and EXPECT_* more. // Generates a nonfatal failure with a generic message. #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") // Generates a nonfatal failure at the given source file location with // a generic message. #define ADD_FAILURE_AT(file, line) \ GTEST_MESSAGE_AT_(file, line, "Failed", \ ::testing::TestPartResult::kNonFatalFailure) // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL # define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. #define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED # define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. // // * {ASSERT|EXPECT}_THROW(statement, expected_exception): // Tests that the statement throws the expected exception. // * {ASSERT|EXPECT}_NO_THROW(statement): // Tests that the statement doesn't throw any exception. // * {ASSERT|EXPECT}_ANY_THROW(statement): // Tests that the statement throws an exception. #define EXPECT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) #define EXPECT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define EXPECT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define ASSERT_THROW(statement, expected_exception) \ GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) #define ASSERT_NO_THROW(statement) \ GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) #define ASSERT_ANY_THROW(statement) \ GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. #define EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) #define EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) #define ASSERT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_FATAL_FAILURE_) #define ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) // Includes the auto-generated header that implements a family of // generic predicate assertion macros. #include "gtest/gtest_pred_impl.h" // Macros for testing equalities and inequalities. // // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 // * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 // * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 // * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 // * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 // // When they are not, Google Test prints both the tested expressions and // their actual values. The values must be compatible built-in types, // or you will get a compiler error. By "compatible" we mean that the // values can be compared by the respective operator. // // Note: // // 1. It is possible to make a user-defined type work with // {ASSERT|EXPECT}_??(), but that requires overloading the // comparison operators and is thus discouraged by the Google C++ // Usage Guide. Therefore, you are advised to use the // {ASSERT|EXPECT}_TRUE() macro to assert that two objects are // equal. // // 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on // pointers (in particular, C strings). Therefore, if you use it // with two C strings, you are testing how their locations in memory // are related, not how their content is related. To compare two C // strings by content, use {ASSERT|EXPECT}_STR*(). // // 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to // {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you // what the actual value is when it fails, and similarly for the // other comparisons. // // 4. Do not depend on the order in which {ASSERT|EXPECT}_??() // evaluate their arguments, which is undefined. // // 5. These macros evaluate their arguments exactly once. // // Examples: // // EXPECT_NE(5, Foo()); // EXPECT_EQ(NULL, a_pointer); // ASSERT_LT(i, array_size); // ASSERT_GT(records.size(), 0) << "There is no record left."; #define EXPECT_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define EXPECT_NE(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) #define EXPECT_LE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define EXPECT_LT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define EXPECT_GE(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define EXPECT_GT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) #define GTEST_ASSERT_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) #define GTEST_ASSERT_NE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) #define GTEST_ASSERT_LE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define GTEST_ASSERT_LT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define GTEST_ASSERT_GE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define GTEST_ASSERT_GT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) // Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ # define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE # define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE # define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT # define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE # define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT # define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string // as different. Two NULLs are equal. // // * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 // * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 // * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case // * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case // // For wide or narrow string objects, you can use the // {ASSERT|EXPECT}_??() macros. // // Don't depend on the order in which the arguments are evaluated, // which is undefined. // // These macros evaluate their arguments exactly once. #define EXPECT_STREQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define EXPECT_STRNE(s1, s2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(expected, actual) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define EXPECT_STRCASENE(s1, s2)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define ASSERT_STRNE(s1, s2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) #define ASSERT_STRCASENE(s1, s2)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. // // * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): // Tests that two float values are almost equal. // * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): // Tests that two double values are almost equal. // * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): // Tests that v1 and v2 are within the given distance to each other. // // Google Test uses ULP-based comparison to automatically pick a default // error bound that is appropriate for the operands. See the // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. #define EXPECT_FLOAT_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_DOUBLE_EQ(expected, actual)\ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_FLOAT_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define ASSERT_DOUBLE_EQ(expected, actual)\ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ expected, actual) #define EXPECT_NEAR(val1, val2, abs_error)\ EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) #define ASSERT_NEAR(val1, val2, abs_error)\ ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ val1, val2, abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. // // EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, float val1, float val2); GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, double val1, double val2); #if GTEST_OS_WINDOWS // Macros that test for HRESULT failure and success, these are only useful // on Windows, and rely on Windows SDK macros and APIs to compile. // // * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) // // When expr unexpectedly fails or succeeds, Google Test prints the // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. # define EXPECT_HRESULT_SUCCEEDED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define ASSERT_HRESULT_SUCCEEDED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) # define EXPECT_HRESULT_FAILED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) # define ASSERT_HRESULT_FAILED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS // Macros that execute statement and check that it doesn't generate new fatal // failures in the current thread. // // * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); // // Examples: // // EXPECT_NO_FATAL_FAILURE(Process()); // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure // message generated by code in the current scope. The effect is // undone when the control leaves the current scope. // // The message argument can be anything streamable to std::ostream. // // In the implementation, we include the current line number as part // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s // to appear in the same block - as long as they are on different // lines. #define SCOPED_TRACE(message) \ ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are // the same type. The value it returns is not interesting. // // Instead of making StaticAssertTypeEq a class template, we make it a // function template that invokes a helper class template. This // prevents a user from misusing StaticAssertTypeEq by // defining objects of that type. // // CAVEAT: // // When used inside a method of a class template, // StaticAssertTypeEq() is effective ONLY IF the method is // instantiated. For example, given: // // template class Foo { // public: // void Bar() { testing::StaticAssertTypeEq(); } // }; // // the code: // // void Test1() { Foo foo; } // // will NOT generate a compiler error, as Foo::Bar() is never // actually instantiated. Instead, you need: // // void Test2() { Foo foo; foo.Bar(); } // // to cause a compiler error. template bool StaticAssertTypeEq() { (void)internal::StaticAssertTypeEqHelper(); return true; } // Defines a test. // // The first parameter is the name of the test case, and the second // parameter is the name of the test within the test case. // // The convention is to end the test case name with "Test". For // example, a test case for the Foo class can be named FooTest. // // Test code should appear between braces after an invocation of // this macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo; // EXPECT_TRUE(foo.StatusIsOK()); // } // Note that we call GetTestTypeId() instead of GetTypeId< // ::testing::Test>() here to get the type ID of testing::Test. This // is to work around a suspected linker bug when using Google Test as // a framework on Mac OS X. The bug causes GetTypeId< // ::testing::Test>() to return different values depending on whether // the call is from the Google Test framework itself or from user test // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. #define GTEST_TEST(test_case_name, test_name)\ GTEST_TEST_(test_case_name, test_name, \ ::testing::Test, ::testing::internal::GetTestTypeId()) // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST # define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. // // The first parameter is the name of the test fixture class, which // also doubles as the test case name. The second parameter is the // name of the test within the test case. // // A test fixture class must be declared earlier. The user should put // his test code between braces after using this macro. Example: // // class FooTest : public testing::Test { // protected: // virtual void SetUp() { b_.AddElement(3); } // // Foo a_; // Foo b_; // }; // // TEST_F(FooTest, InitializesCorrectly) { // EXPECT_TRUE(a_.StatusIsOK()); // } // // TEST_F(FooTest, ReturnsElementCountCorrectly) { // EXPECT_EQ(0, a_.size()); // EXPECT_EQ(1, b_.size()); // } #define TEST_F(test_fixture, test_name)\ GTEST_TEST_(test_fixture, test_name, test_fixture, \ ::testing::internal::GetTypeId()) } // namespace testing // Use this function in main() to run all tests. It returns 0 if all // tests are successful, or 1 otherwise. // // RUN_ALL_TESTS() should be invoked after the command line has been // parsed by InitGoogleTest(). // // This function was formerly a macro; thus, it is in the global // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } #endif // GTEST_INCLUDE_GTEST_GTEST_H_ node-v4.2.6/deps/gtest/include/gtest/gtest_pred_impl.h000644 000766 000024 00000035451 12650222322 023136 0ustar00iojsstaff000000 000000 // Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // This file is AUTOMATICALLY GENERATED on 10/31/2011 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ # error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion // macros: // // ASSERT_PRED_FORMAT1(pred_format, v1) // ASSERT_PRED_FORMAT2(pred_format, v1, v2) // ... // // where pred_format is a function or functor that takes n (in the // case of ASSERT_PRED_FORMATn) values and their source expression // text, and returns a testing::AssertionResult. See the definition // of ASSERT_EQ in gtest.h for an example. // // If you don't care about formatting, you can use the more // restrictive version: // // ASSERT_PRED1(pred, v1) // ASSERT_PRED2(pred, v1, v2) // ... // // where pred is an n-ary function or functor that returns bool, // and the values v1, v2, ..., must support the << operator for // streaming to std::ostream. // // We also define the EXPECT_* variations. // // For now we only support predicates whose arity is at most 5. // Please email googletestframework@googlegroups.com if you need // support for higher arities. // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. #define GTEST_ASSERT_(expression, on_failure) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar = (expression)) \ ; \ else \ on_failure(gtest_ar.failure_message()) // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. template AssertionResult AssertPred1Helper(const char* pred_text, const char* e1, Pred pred, const T1& v1) { if (pred(v1)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ GTEST_ASSERT_(pred_format(#v1, v1), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. #define GTEST_PRED1_(pred, v1, on_failure)\ GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ #v1, \ pred, \ v1), on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) #define ASSERT_PRED1(pred, v1) \ GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. template AssertionResult AssertPred2Helper(const char* pred_text, const char* e1, const char* e2, Pred pred, const T1& v1, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. #define GTEST_PRED2_(pred, v1, v2, on_failure)\ GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ #v1, \ #v2, \ pred, \ v1, \ v2), on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) #define ASSERT_PRED2(pred, v1, v2) \ GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. template AssertionResult AssertPred3Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, Pred pred, const T1& v1, const T2& v2, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. #define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. #define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ #v1, \ #v2, \ #v3, \ pred, \ v1, \ v2, \ v3), on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) #define ASSERT_PRED3(pred, v1, v2, v3) \ GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. template AssertionResult AssertPred4Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. #define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. #define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ pred, \ v1, \ v2, \ v3, \ v4), on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. template AssertionResult AssertPred5Helper(const char* pred_text, const char* e1, const char* e2, const char* e3, const char* e4, const char* e5, Pred pred, const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); return AssertionFailure() << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4 << ", " << e5 << ") evaluates to false, where" << "\n" << e1 << " evaluates to " << v1 << "\n" << e2 << " evaluates to " << v2 << "\n" << e3 << " evaluates to " << v3 << "\n" << e4 << " evaluates to " << v4 << "\n" << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. #define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. #define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ #v1, \ #v2, \ #v3, \ #v4, \ #v5, \ pred, \ v1, \ v2, \ v3, \ v4, \ v5), on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ node-v4.2.6/deps/gtest/include/gtest/gtest_prod.h000644 000766 000024 00000004424 12650222322 022123 0ustar00iojsstaff000000 000000 // Copyright 2006, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // // Google C++ Testing Framework definitions useful in production code. #ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ #define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ // When you need to test the private or protected members of a class, // use the FRIEND_TEST macro to declare your tests as friends of the // class. For example: // // class MyClass { // private: // void MyMethod(); // FRIEND_TEST(MyClassTest, MyMethod); // }; // // class MyClassTest : public testing::Test { // // ... // }; // // TEST_F(MyClassTest, MyMethod) { // // Can call MyClass::MyMethod() here. // } #define FRIEND_TEST(test_case_name, test_name)\ friend class test_case_name##_##test_name##_Test #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ node-v4.2.6/deps/gtest/include/gtest/internal/000755 000766 000024 00000000000 12650222322 021410 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/gtest/include/gtest/internal/gtest-death-test-internal.h000644 000766 000024 00000032165 12650222322 026570 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file defines internal utilities needed for implementing // death tests. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #include "gtest/internal/gtest-internal.h" #include namespace testing { namespace internal { GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). const char kDeathTestStyleFlag[] = "death_test_style"; const char kDeathTestUseFork[] = "death_test_use_fork"; const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; #if GTEST_HAS_DEATH_TEST // DeathTest is a class that hides much of the complexity of the // GTEST_DEATH_TEST_ macro. It is abstract; its static Create method // returns a concrete class that depends on the prevailing death test // style, as defined by the --gtest_death_test_style and/or // --gtest_internal_run_death_test flags. // In describing the results of death tests, these terms are used with // the corresponding definitions: // // exit status: The integer exit information in the format specified // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() class GTEST_API_ DeathTest { public: // Create returns false if there was an error determining the // appropriate action to take for the current death test; for example, // if the gtest_death_test_style flag is set to an invalid value. // The LastMessage method will return a more detailed message in that // case. Otherwise, the DeathTest pointer pointed to by the "test" // argument is set. If the death test should be skipped, the pointer // is set to NULL; otherwise, it is set to the address of a new concrete // DeathTest object that controls the execution of the current test. static bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); DeathTest(); virtual ~DeathTest() { } // A helper class that aborts a death test when it's deleted. class ReturnSentinel { public: explicit ReturnSentinel(DeathTest* test) : test_(test) { } ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } private: DeathTest* const test_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); } GTEST_ATTRIBUTE_UNUSED_; // An enumeration of possible roles that may be taken when a death // test is encountered. EXECUTE means that the death test logic should // be executed immediately. OVERSEE means that the program should prepare // the appropriate environment for a child process to execute the death // test, then wait for it to complete. enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; // An enumeration of the three reasons that a test might be aborted. enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_THREW_EXCEPTION, TEST_DID_NOT_DIE }; // Assumes one of the above roles. virtual TestRole AssumeRole() = 0; // Waits for the death test to finish and returns its status. virtual int Wait() = 0; // Returns true if the death test passed; that is, the test process // exited during the test, its exit status matches a user-supplied // predicate, and its stderr output matches a user-supplied regular // expression. // The user-supplied predicate may be a macro expression rather // than a function pointer or functor, or else Wait and Passed could // be combined. virtual bool Passed(bool exit_status_ok) = 0; // Signals that the death test did not die as expected. virtual void Abort(AbortReason reason) = 0; // Returns a human-readable outcome message regarding the outcome of // the last death test. static const char* LastMessage(); static void set_last_death_test_message(const std::string& message); private: // A string containing a description of the outcome of the last death test. static std::string last_death_test_message_; GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; // Factory interface for death tests. May be mocked out for testing. class DeathTestFactory { public: virtual ~DeathTestFactory() { } virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test) = 0; }; // A concrete DeathTestFactory implementation for normal use. class DefaultDeathTestFactory : public DeathTestFactory { public: virtual bool Create(const char* statement, const RE* regex, const char* file, int line, DeathTest** test); }; // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. # if GTEST_HAS_EXCEPTIONS # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } catch (const ::std::exception& gtest_exception) { \ fprintf(\ stderr, \ "\n%s: Caught std::exception-derived exception escaping the " \ "death test statement. Exception message: %s\n", \ ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ gtest_exception.what()); \ fflush(stderr); \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } catch (...) { \ death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ } # else # define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) # endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. # define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ ::testing::internal::DeathTest* gtest_dt; \ if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ __FILE__, __LINE__, >est_dt)) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ if (gtest_dt != NULL) { \ ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ gtest_dt_ptr(gtest_dt); \ switch (gtest_dt->AssumeRole()) { \ case ::testing::internal::DeathTest::OVERSEE_TEST: \ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ } \ break; \ case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ default: \ break; \ } \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ fail(::testing::internal::DeathTest::LastMessage()) // The symbol "fail" here expands to something into which a message // can be streamed. // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // NDEBUG mode. In this case we need the statements to be executed, the regex is // ignored, and the macro must accept a streamed message even though the message // is never printed. # define GTEST_EXECUTE_STATEMENT_(statement, regex) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } else \ ::testing::Message() // A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. class InternalRunDeathTestFlag { public: InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index, int a_write_fd) : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} ~InternalRunDeathTestFlag() { if (write_fd_ >= 0) posix::Close(write_fd_); } const std::string& file() const { return file_; } int line() const { return line_; } int index() const { return index_; } int write_fd() const { return write_fd_; } private: std::string file_; int line_; int index_; int write_fd_; GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); #else // GTEST_HAS_DEATH_TEST // This macro is used for implementing macros such as // EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where // death tests are not supported. Those macros must compile on such systems // iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on // systems that support death tests. This allows one to write such a macro // on a system that does not support death tests and be sure that it will // compile on a death-test supporting system. // // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. This macro has to make sure this // statement is compiled but not executed, to ensure that // EXPECT_DEATH_IF_SUPPORTED compiles with a certain // parameter iff EXPECT_DEATH compiles with it. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. This parameter has to be // compiled but not evaluated by this macro, to ensure that // this macro only accepts expressions that a macro such as // EXPECT_DEATH would accept. // terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED // and a return statement for ASSERT_DEATH_IF_SUPPORTED. // This ensures that ASSERT_DEATH_IF_SUPPORTED will not // compile inside functions where ASSERT_DEATH doesn't // compile. // // The branch that has an always false condition is used to ensure that // statement and regex are compiled (and thus syntactically correct) but // never executed. The unreachable code macro protects the terminator // statement from generating an 'unreachable code' warning in case // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. # define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ << "Death tests are not supported on this platform.\n" \ << "Statement '" #statement "' cannot be verified."; \ } else if (::testing::internal::AlwaysFalse()) { \ ::testing::internal::RE::PartialMatch(".*", (regex)); \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ terminator; \ } else \ ::testing::Message() #endif // GTEST_HAS_DEATH_TEST } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-filepath.h000644 000766 000024 00000022603 12650222322 024504 0ustar00iojsstaff000000 000000 // Copyright 2008, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: keith.ray@gmail.com (Keith Ray) // // Google Test filepath utilities // // This header file declares classes and functions used internally by // Google Test. They are subject to change without notice. // // This file is #included in . // Do not include this header file separately! #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #include "gtest/internal/gtest-string.h" namespace testing { namespace internal { // FilePath - a class for file and directory pathname manipulation which // handles platform-specific conventions (like the pathname separator). // Used for helper functions for naming files in a directory for xml output. // Except for Set methods, all methods are const or static, which provides an // "immutable value object" -- useful for peace of mind. // A FilePath with a value ending in a path separator ("like/this/") represents // a directory, otherwise it is assumed to represent a file. In either case, // it may or may not represent an actual file or directory in the file system. // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. class GTEST_API_ FilePath { public: FilePath() : pathname_("") { } FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } explicit FilePath(const std::string& pathname) : pathname_(pathname) { Normalize(); } FilePath& operator=(const FilePath& rhs) { Set(rhs); return *this; } void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; } const std::string& string() const { return pathname_; } const char* c_str() const { return pathname_.c_str(); } // Returns the current working directory, or "" if unsuccessful. static FilePath GetCurrentDir(); // Given directory = "dir", base_name = "test", number = 0, // extension = "xml", returns "dir/test.xml". If number is greater // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. static FilePath MakeFileName(const FilePath& directory, const FilePath& base_name, int number, const char* extension); // Given directory = "dir", relative_path = "test.xml", // returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. static FilePath ConcatPaths(const FilePath& directory, const FilePath& relative_path); // Returns a pathname for a file that does not currently exist. The pathname // will be directory/base_name.extension or // directory/base_name_.extension if directory/base_name.extension // already exists. The number will be incremented until a pathname is found // that does not already exist. // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. static FilePath GenerateUniqueFileName(const FilePath& directory, const FilePath& base_name, const char* extension); // Returns true iff the path is "". bool IsEmpty() const { return pathname_.empty(); } // If input name has a trailing separator character, removes it and returns // the name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. FilePath RemoveTrailingPathSeparator() const; // Returns a copy of the FilePath with the directory part removed. // Example: FilePath("path/to/file").RemoveDirectoryName() returns // FilePath("file"). If there is no directory part ("just_a_file"), it returns // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveDirectoryName() const; // RemoveFileName returns the directory path with the filename removed. // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". // If the FilePath is "a_file" or "/a_file", RemoveFileName returns // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. FilePath RemoveFileName() const; // Returns a copy of the FilePath with the case-insensitive extension removed. // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. FilePath RemoveExtension(const char* extension) const; // Creates directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create // directories for any reason. Will also return false if the FilePath does // not represent a directory (that is, it doesn't end with a path separator). bool CreateDirectoriesRecursively() const; // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. bool CreateFolder() const; // Returns true if FilePath describes something in the file-system, // either a file, directory, or whatever, and that something exists. bool FileOrDirectoryExists() const; // Returns true if pathname describes a directory in the file-system // that exists. bool DirectoryExists() const; // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. bool IsDirectory() const; // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) bool IsRootDirectory() const; // Returns true if pathname describes an absolute path. bool IsAbsolutePath() const; private: // Replaces multiple consecutive separators with a single separator. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // // A pathname with multiple consecutive separators may occur either through // user error or as a result of some scripts or APIs that generate a pathname // with a trailing separator. On other platforms the same API or script // may NOT generate a pathname with a trailing "/". Then elsewhere that // pathname may have another "/" and pathname components added to it, // without checking for the separator already being there. // The script language and operating system may allow paths like "foo//bar" // but some of the functions in FilePath will not handle that correctly. In // particular, RemoveTrailingPathSeparator() only removes one separator, and // it is called in CreateDirectoriesRecursively() assuming that it will change // a pathname from directory syntax (trailing separator) to filename syntax. // // On Windows this method also replaces the alternate path separator '/' with // the primary path separator '\\', so that for example "bar\\/\\foo" becomes // "bar\\foo". void Normalize(); // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; std::string pathname_; }; // class FilePath } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-internal.h000644 000766 000024 00000130742 12650222322 024530 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares functions and macros used internally by // Google Test. They are subject to change without notice. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX # include # include # include # include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS # include #endif #include #include #include #include #include #include #include #include #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-filepath.h" #include "gtest/internal/gtest-type-util.h" // Due to C++ preprocessor weirdness, we need double indirection to // concatenate two tokens when one of them is __LINE__. Writing // // foo ## __LINE__ // // will result in the token foo__LINE__, instead of foo followed by // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar class ProtocolMessage; namespace proto2 { class Message; } namespace testing { // Forward declarations. class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. class Test; // Represents a test. class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. template ::std::string PrintToString(const T& value); namespace internal { struct TraceInfo; // Information about a trace point. class ScopedTrace; // Implements scoped trace. class TestInfoImpl; // Opaque implementation of TestInfo class UnitTestImpl; // Opaque implementation of UnitTest // How many times InitGoogleTest() has been called. GTEST_API_ extern int g_init_gtest_count; // The text used in failure messages to indicate the start of the // stack trace. GTEST_API_ extern const char kStackTraceMarker[]; // Two overloaded helpers for checking at compile time whether an // expression is a null pointer literal (i.e. NULL or any 0-valued // compile-time integral constant). Their return values have // different sizes, so we can use sizeof() to test which version is // picked by the compiler. These helpers have no implementations, as // we only need their signatures. // // Given IsNullLiteralHelper(x), the compiler will pick the first // version if x can be implicitly converted to Secret*, and pick the // second version otherwise. Since Secret is a secret and incomplete // type, the only expression a user can write that has type Secret* is // a null pointer literal. Therefore, we know that x is a null // pointer literal if and only if the first version is picked by the // compiler. char IsNullLiteralHelper(Secret* p); char (&IsNullLiteralHelper(...))[2]; // NOLINT // A compile-time bool constant that is true if and only if x is a // null pointer literal (i.e. NULL or any 0-valued compile-time // integral constant). #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_IS_NULL_LITERAL_(x) false #else # define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. GTEST_API_ std::string AppendUserMessage( const std::string& gtest_msg, const Message& user_msg); #if GTEST_HAS_EXCEPTIONS // This exception is thrown by (and only by) a failed Google Test // assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions // are enabled). We derive it from std::runtime_error, which is for // errors presumably detectable only at run time. Since // std::runtime_error inherits from std::exception, many testing // frameworks know how to extract and print the message inside it. class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { public: explicit GoogleTestFailureException(const TestPartResult& failure); }; #endif // GTEST_HAS_EXCEPTIONS // A helper class for creating scoped traces in user programs. class GTEST_API_ ScopedTrace { public: // The c'tor pushes the given source file location and message onto // a trace stack maintained by Google Test. ScopedTrace(const char* file, int line, const Message& message); // The d'tor pops the info pushed by the c'tor. // // Note that the d'tor is not virtual in order to be efficient. // Don't inherit from ScopedTrace! ~ScopedTrace(); private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. namespace edit_distance { // Returns the optimal edits to go from 'left' to 'right'. // All edits cost the same, with replace having lower priority than // add/remove. // Simple implementation of the Wagner–Fischer algorithm. // See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm enum EditType { kMatch, kAdd, kRemove, kReplace }; GTEST_API_ std::vector CalculateOptimalEdits( const std::vector& left, const std::vector& right); // Same as above, but the input is represented as strings. GTEST_API_ std::vector CalculateOptimalEdits( const std::vector& left, const std::vector& right); // Create a diff of the input strings in Unified diff format. GTEST_API_ std::string CreateUnifiedDiff(const std::vector& left, const std::vector& right, size_t context = 2); } // namespace edit_distance // Calculate the diff between 'left' and 'right' and return it in unified diff // format. // If not null, stores in 'total_line_count' the total number of lines found // in left + right. GTEST_API_ std::string DiffStrings(const std::string& left, const std::string& right, size_t* total_line_count); // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // // The first four parameters are the expressions used in the assertion // and their values, as strings. For example, for ASSERT_EQ(foo, bar) // where foo is 5 and bar is 6, we have: // // expected_expression: "foo" // actual_expression: "bar" // expected_value: "5" // actual_value: "6" // // The ignoring_case parameter is true iff the assertion is a // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. GTEST_API_ AssertionResult EqFailure(const char* expected_expression, const char* actual_expression, const std::string& expected_value, const std::string& actual_value, bool ignoring_case); // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( const AssertionResult& assertion_result, const char* expression_text, const char* actual_predicate_value, const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the // template parameters). // // The purpose of this class is to do more sophisticated number // comparison. (Due to round-off error, etc, it's very unlikely that // two floating-points will be equal exactly. Hence a naive // comparison by the == operation often doesn't work.) // // Format of IEEE floating-point: // // The most-significant bit being the leftmost, an IEEE // floating-point looks like // // sign_bit exponent_bits fraction_bits // // Here, sign_bit is a single bit that designates the sign of the // number. // // For float, there are 8 exponent bits and 23 fraction bits. // // For double, there are 11 exponent bits and 52 fraction bits. // // More details can be found at // http://en.wikipedia.org/wiki/IEEE_floating-point_standard. // // Template parameter: // // RawType: the raw floating-point type (either float or double) template class FloatingPoint { public: // Defines the unsigned integer type that has the same size as the // floating point number. typedef typename TypeWithSize::UInt Bits; // Constants. // # of bits in a number. static const size_t kBitCount = 8*sizeof(RawType); // # of fraction bits in a number. static const size_t kFractionBitCount = std::numeric_limits::digits - 1; // # of exponent bits in a number. static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; // The mask for the sign bit. static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); // The mask for the fraction bits. static const Bits kFractionBitMask = ~static_cast(0) >> (kExponentBitCount + 1); // The mask for the exponent bits. static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); // How many ULP's (Units in the Last Place) we want to tolerate when // comparing two numbers. The larger the value, the more error we // allow. A 0 value means that two numbers must be exactly the same // to be considered equal. // // The maximum error of a single floating-point operation is 0.5 // units in the last place. On Intel CPU's, all floating-point // calculations are done with 80-bit precision, while double has 64 // bits. Therefore, 4 should be enough for ordinary use. // // See the following article for more details on ULP: // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ static const size_t kMaxUlps = 4; // Constructs a FloatingPoint from a raw floating-point number. // // On an Intel CPU, passing a non-normalized NAN (Not a Number) // around may change its bits, although the new value is guaranteed // to be also a NAN. Therefore, don't expect this constructor to // preserve the bits in x when x is a NAN. explicit FloatingPoint(const RawType& x) { u_.value_ = x; } // Static methods // Reinterprets a bit pattern as a floating-point number. // // This function is needed to test the AlmostEquals() method. static RawType ReinterpretBits(const Bits bits) { FloatingPoint fp(0); fp.u_.bits_ = bits; return fp.u_.value_; } // Returns the floating-point number that represent positive infinity. static RawType Infinity() { return ReinterpretBits(kExponentBitMask); } // Returns the maximum representable finite floating-point number. static RawType Max(); // Non-static methods // Returns the bits that represents this number. const Bits &bits() const { return u_.bits_; } // Returns the exponent bits of this number. Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } // Returns the fraction bits of this number. Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } // Returns the sign bit of this number. Bits sign_bit() const { return kSignBitMask & u_.bits_; } // Returns true iff this is NAN (not a number). bool is_nan() const { // It's a NAN if the exponent bits are all ones and the fraction // bits are not entirely zeros. return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); } // Returns true iff this number is at most kMaxUlps ULP's away from // rhs. In particular, this function: // // - returns false if either number is (or both are) NAN. // - treats really large numbers as almost equal to infinity. // - thinks +0.0 and -0.0 are 0 DLP's apart. bool AlmostEquals(const FloatingPoint& rhs) const { // The IEEE standard says that any comparison operation involving // a NAN must return false. if (is_nan() || rhs.is_nan()) return false; return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= kMaxUlps; } private: // The data type used to store the actual floating-point number. union FloatingPointUnion { RawType value_; // The raw floating-point number. Bits bits_; // The bits that represent the number. }; // Converts an integer from the sign-and-magnitude representation to // the biased representation. More precisely, let N be 2 to the // power of (kBitCount - 1), an integer x is represented by the // unsigned number x + N. // // For instance, // // -N + 1 (the most negative number representable using // sign-and-magnitude) is represented by 1; // 0 is represented by N; and // N - 1 (the biggest number representable using // sign-and-magnitude) is represented by 2N - 1. // // Read http://en.wikipedia.org/wiki/Signed_number_representations // for more details on signed number representations. static Bits SignAndMagnitudeToBiased(const Bits &sam) { if (kSignBitMask & sam) { // sam represents a negative number. return ~sam + 1; } else { // sam represents a positive number. return kSignBitMask | sam; } } // Given two numbers in the sign-and-magnitude representation, // returns the distance between them as an unsigned number. static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, const Bits &sam2) { const Bits biased1 = SignAndMagnitudeToBiased(sam1); const Bits biased2 = SignAndMagnitudeToBiased(sam2); return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); } FloatingPointUnion u_; }; // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> inline float FloatingPoint::Max() { return FLT_MAX; } template <> inline double FloatingPoint::Max() { return DBL_MAX; } // Typedefs the instances of the FloatingPoint template class that we // care to use. typedef FloatingPoint Float; typedef FloatingPoint Double; // In order to catch the mistake of putting tests that use different // test fixture classes in the same test case, we need to assign // unique IDs to fixture classes and compare them. The TypeId type is // used to hold such IDs. The user should treat TypeId as an opaque // type: the only operation allowed on TypeId values is to compare // them for equality using the == operator. typedef const void* TypeId; template class TypeIdHelper { public: // dummy_ must not have a const type. Otherwise an overly eager // compiler (e.g. MSVC 7.1 & 8.0) may try to merge // TypeIdHelper::dummy_ for different Ts as an "optimization". static bool dummy_; }; template bool TypeIdHelper::dummy_ = false; // GetTypeId() returns the ID of type T. Different values will be // returned for different types. Calling the function twice with the // same type argument is guaranteed to return the same ID. template TypeId GetTypeId() { // The compiler is required to allocate a different // TypeIdHelper::dummy_ variable for each T used to instantiate // the template. Therefore, the address of dummy_ is guaranteed to // be unique. return &(TypeIdHelper::dummy_); } // Returns the type ID of ::testing::Test. Always call this instead // of GetTypeId< ::testing::Test>() to get the type ID of // ::testing::Test, as the latter may give the wrong result due to a // suspected linker bug when compiling Google Test as a Mac OS X // framework. GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. class TestFactoryBase { public: virtual ~TestFactoryBase() {} // Creates a test instance to run. The instance is both created and destroyed // within TestInfoImpl::Run() virtual Test* CreateTest() = 0; protected: TestFactoryBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); }; // This class provides implementation of TeastFactoryBase interface. // It is used in TEST and TEST_F macros. template class TestFactoryImpl : public TestFactoryBase { public: virtual Test* CreateTest() { return new TestClass; } }; #if GTEST_OS_WINDOWS // Predicate-formatters for implementing the HRESULT checking macros // {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, long hr); // NOLINT GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, long hr); // NOLINT #endif // GTEST_OS_WINDOWS // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // // Arguments: // // test_case_name: name of the test case // name: name of the test // type_param the name of the test's type parameter, or NULL if // this is not a typed or a type-parameterized test. // value_param text representation of the test's value parameter, // or NULL if this is not a type-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case // factory: pointer to the factory that creates a test object. // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, const char* type_param, const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory); // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. class GTEST_API_ TypedTestCasePState { public: TypedTestCasePState() : registered_(false) {} // Adds the given test name to defined_test_names_ and return true // if the test case hasn't been registered; otherwise aborts the // program. bool AddTestName(const char* file, int line, const char* case_name, const char* test_name) { if (registered_) { fprintf(stderr, "%s Test %s must be defined before " "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", FormatFileLocation(file, line).c_str(), test_name, case_name); fflush(stderr); posix::Abort(); } defined_test_names_.insert(test_name); return true; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* VerifyRegisteredTestNames( const char* file, int line, const char* registered_tests); private: bool registered_; ::std::set defined_test_names_; }; // Skips to the first non-space char after the first comma in 'str'; // returns NULL if no comma is found in 'str'. inline const char* SkipComma(const char* str) { const char* comma = strchr(str, ','); if (comma == NULL) { return NULL; } while (IsSpace(*(++comma))) {} return comma; } // Returns the prefix of 'str' before the first comma in it; returns // the entire string if it contains no comma. inline std::string GetPrefixUntilComma(const char* str) { const char* comma = strchr(str, ','); return comma == NULL ? str : std::string(str, comma); } // TypeParameterizedTest::Register() // registers a list of type-parameterized tests with Google Test. The // return value is insignificant - we just need to return something // such that we can call this function in a namespace scope. // // Implementation note: The GTEST_TEMPLATE_ macro declares a template // template parameter. It's defined in gtest-type-util.h. template class TypeParameterizedTest { public: // 'index' is the index of the test in the type list 'Types' // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, // Types). Valid values for 'index' are [0, N - 1] where N is the // length of Types. static bool Register(const char* prefix, const char* case_name, const char* test_names, int index) { typedef typename Types::Head Type; typedef Fixture FixtureClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass; // First, registers the first type-parameterized test in the type // list. MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName().c_str(), NULL, // No value parameter. GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, new TestFactoryImpl); // Next, recurses (at compile time) with the tail of the type list. return TypeParameterizedTest ::Register(prefix, case_name, test_names, index + 1); } }; // The base case for the compile time recursion. template class TypeParameterizedTest { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/, int /*index*/) { return true; } }; // TypeParameterizedTestCase::Register() // registers *all combinations* of 'Tests' and 'Types' with Google // Test. The return value is insignificant - we just need to return // something such that we can call this function in a namespace scope. template class TypeParameterizedTestCase { public: static bool Register(const char* prefix, const char* case_name, const char* test_names) { typedef typename Tests::Head Head; // First, register the first test in 'Test' for each type in 'Types'. TypeParameterizedTest::Register( prefix, case_name, test_names, 0); // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestCase ::Register(prefix, case_name, SkipComma(test_names)); } }; // The base case for the compile time recursion. template class TypeParameterizedTestCase { public: static bool Register(const char* /*prefix*/, const char* /*case_name*/, const char* /*test_names*/) { return true; } }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // Returns the current OS stack trace as an std::string. // // The maximum number of stack frames to be included is specified by // the gtest_stack_trace_depth flag. The skip_count parameter // specifies the number of top frames to be skipped, which doesn't // count against the number of frames to be included. // // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( UnitTest* unit_test, int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. // Always returns true. GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } // Helper for suppressing false warning from Clang on a const char* // variable declared in a conditional expression always being NULL in // the else branch. struct GTEST_API_ ConstCharPtr { ConstCharPtr(const char* str) : value(str) {} operator bool() const { return true; } const char* value; }; // A simple Linear Congruential Generator for generating random // numbers with a uniform distribution. Unlike rand() and srand(), it // doesn't use global state (and therefore can't interfere with user // code). Unlike rand_r(), it's portable. An LCG isn't very random, // but it's good enough for our purposes. class GTEST_API_ Random { public: static const UInt32 kMaxRange = 1u << 31; explicit Random(UInt32 seed) : state_(seed) {} void Reseed(UInt32 seed) { state_ = seed; } // Generates a random number from [0, range). Crashes if 'range' is // 0 or greater than kMaxRange. UInt32 Generate(UInt32 range); private: UInt32 state_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; // Defining a variable of type CompileAssertTypesEqual will cause a // compiler error iff T1 and T2 are different types. template struct CompileAssertTypesEqual; template struct CompileAssertTypesEqual { }; // Removes the reference from a type if it is a reference type, // otherwise leaves it unchanged. This is the same as // tr1::remove_reference, which is not widely available yet. template struct RemoveReference { typedef T type; }; // NOLINT template struct RemoveReference { typedef T type; }; // NOLINT // A handy wrapper around RemoveReference that works when the argument // T depends on template parameters. #define GTEST_REMOVE_REFERENCE_(T) \ typename ::testing::internal::RemoveReference::type // Removes const from a type if it is a const type, otherwise leaves // it unchanged. This is the same as tr1::remove_const, which is not // widely available yet. template struct RemoveConst { typedef T type; }; // NOLINT template struct RemoveConst { typedef T type; }; // NOLINT // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // definition to fail to remove the const in 'const int[3]' and 'const // char[3][4]'. The following specialization works around the bug. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #if defined(_MSC_VER) && _MSC_VER < 1400 // This is the only specialization that allows VC++ 7.1 to remove const in // 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC // and thus needs to be conditionally compiled. template struct RemoveConst { typedef typename RemoveConst::type type[N]; }; #endif // A handy wrapper around RemoveConst that works when the argument // T depends on template parameters. #define GTEST_REMOVE_CONST_(T) \ typename ::testing::internal::RemoveConst::type // Turns const U&, U&, const U, and U all into U. #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) // Adds reference to a type if it is not a reference type, // otherwise leaves it unchanged. This is the same as // tr1::add_reference, which is not widely available yet. template struct AddReference { typedef T& type; }; // NOLINT template struct AddReference { typedef T& type; }; // NOLINT // A handy wrapper around AddReference that works when the argument T // depends on template parameters. #define GTEST_ADD_REFERENCE_(T) \ typename ::testing::internal::AddReference::type // Adds a reference to const on top of T as necessary. For example, // it transforms // // char ==> const char& // const char ==> const char& // char& ==> const char& // const char& ==> const char& // // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. template class ImplicitlyConvertible { private: // We need the following helper functions only for their types. // They have no implementations. // MakeFrom() is an expression whose type is From. We cannot simply // use From(), as the type From may not have a public default // constructor. static typename AddReference::type MakeFrom(); // These two functions are overloaded. Given an expression // Helper(x), the compiler will pick the first version if x can be // implicitly converted to type To; otherwise it will pick the // second version. // // The first version returns a value of size 1, and the second // version returns a value of size 2. Therefore, by checking the // size of Helper(x), which can be done at compile time, we can tell // which version of Helper() is used, and hence whether x can be // implicitly converted to type To. static char Helper(To); static char (&Helper(...))[2]; // NOLINT // We have to put the 'public' section after the 'private' section, // or MSVC refuses to compile the code. public: #if defined(__BORLANDC__) // C++Builder cannot use member overload resolution during template // instantiation. The simplest workaround is to use its C++0x type traits // functions (C++Builder 2009 and above only). static const bool value = __is_convertible(From, To); #else // MSVC warns about implicitly converting from double to int for // possible loss of data, so we need to temporarily disable the // warning. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244) static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; GTEST_DISABLE_MSC_WARNINGS_POP_() #endif // __BORLANDC__ }; template const bool ImplicitlyConvertible::value; // IsAProtocolMessage::value is a compile-time bool constant that's // true iff T is type ProtocolMessage, proto2::Message, or a subclass // of those. template struct IsAProtocolMessage : public bool_constant< ImplicitlyConvertible::value || ImplicitlyConvertible::value> { }; // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest // will be viable (since both C::iterator* and C::const_iterator* are // valid types and NULL can be implicitly converted to them). It will // be picked over the second overload as 'int' is a perfect match for // the type of argument 0. If C::iterator or C::const_iterator is not // a valid type, the first overload is not viable, and the second // overload will be picked. Therefore, we can determine whether C is // a container class by checking the type of IsContainerTest(0). // The value of the expression is insignificant. // // Note that we look for both C::iterator and C::const_iterator. The // reason is that C++ injects the name of a class as a member of the // class itself (e.g. you can refer to class iterator as either // 'iterator' or 'iterator::iterator'). If we look for C::iterator // only, for example, we would mistakenly think that a class named // iterator is an STL container. // // Also note that the simpler approach of overloading // IsContainerTest(typename C::const_iterator*) and // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. typedef int IsContainer; template IsContainer IsContainerTest(int /* dummy */, typename C::iterator* /* it */ = NULL, typename C::const_iterator* /* const_it */ = NULL) { return 0; } typedef char IsNotContainer; template IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } // EnableIf::type is void when 'Cond' is true, and // undefined when 'Cond' is false. To use SFINAE to make a function // overload only apply when a particular expression is true, add // "typename EnableIf::type* = 0" as the last parameter. template struct EnableIf; template<> struct EnableIf { typedef void type; }; // NOLINT // Utilities for native arrays. // ArrayEq() compares two k-dimensional native arrays using the // elements' operator==, where k can be any integer >= 0. When k is // 0, ArrayEq() degenerates into comparing a single pair of values. template bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } // This overload is used when k >= 1. template inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { return internal::ArrayEq(lhs, N, rhs); } // This helper reduces code bloat. If we instead put its logic inside // the previous ArrayEq() function, arrays with different sizes would // lead to different copies of the template code. template bool ArrayEq(const T* lhs, size_t size, const U* rhs) { for (size_t i = 0; i != size; i++) { if (!internal::ArrayEq(lhs[i], rhs[i])) return false; } return true; } // Finds the first element in the iterator range [begin, end) that // equals elem. Element may be a native array type itself. template Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { for (Iter it = begin; it != end; ++it) { if (internal::ArrayEq(*it, elem)) return it; } return end; } // CopyArray() copies a k-dimensional native array using the elements' // operator=, where k can be any integer >= 0. When k is 0, // CopyArray() degenerates into copying a single value. template void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template inline void CopyArray(const T& from, U* to) { *to = from; } // This overload is used when k >= 1. template inline void CopyArray(const T(&from)[N], U(*to)[N]) { internal::CopyArray(from, N, *to); } // This helper reduces code bloat. If we instead put its logic inside // the previous CopyArray() function, arrays with different sizes // would lead to different copies of the template code. template void CopyArray(const T* from, size_t size, U* to) { for (size_t i = 0; i != size; i++) { internal::CopyArray(from[i], to + i); } } // The relation between an NativeArray object (see below) and the // native array it represents. // We use 2 different structs to allow non-copyable types to be used, as long // as RelationToSourceReference() is passed. struct RelationToSourceReference {}; struct RelationToSourceCopy {}; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements // members useful for Google Mock's container matchers. New members // should be added as needed. To simplify the implementation, we only // support Element being a raw type (i.e. having no top-level const or // reference modifier). It's the client's responsibility to satisfy // this requirement. Element can be an array type itself (hence // multi-dimensional arrays are supported). template class NativeArray { public: // STL-style container typedefs. typedef Element value_type; typedef Element* iterator; typedef const Element* const_iterator; // Constructs from a native array. References the source. NativeArray(const Element* array, size_t count, RelationToSourceReference) { InitRef(array, count); } // Constructs from a native array. Copies the source. NativeArray(const Element* array, size_t count, RelationToSourceCopy) { InitCopy(array, count); } // Copy constructor. NativeArray(const NativeArray& rhs) { (this->*rhs.clone_)(rhs.array_, rhs.size_); } ~NativeArray() { if (clone_ != &NativeArray::InitRef) delete[] array_; } // STL-style container methods. size_t size() const { return size_; } const_iterator begin() const { return array_; } const_iterator end() const { return array_ + size_; } bool operator==(const NativeArray& rhs) const { return size() == rhs.size() && ArrayEq(begin(), size(), rhs.begin()); } private: enum { kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper< Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value, }; // Initializes this object with a copy of the input. void InitCopy(const Element* array, size_t a_size) { Element* const copy = new Element[a_size]; CopyArray(array, a_size, copy); array_ = copy; size_ = a_size; clone_ = &NativeArray::InitCopy; } // Initializes this object with a reference of the input. void InitRef(const Element* array, size_t a_size) { array_ = array; size_ = a_size; clone_ = &NativeArray::InitRef; } const Element* array_; size_t size_; void (NativeArray::*clone_)(const Element*, size_t); GTEST_DISALLOW_ASSIGN_(NativeArray); }; } // namespace internal } // namespace testing #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ ::testing::internal::AssertHelper(result_type, file, line, message) \ = ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) #define GTEST_FATAL_FAILURE_(message) \ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ if (::testing::internal::AlwaysTrue()) { statement; } #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::ConstCharPtr gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (expected_exception const&) { \ gtest_caught_expected = true; \ } \ catch (...) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws a different type."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ if (!gtest_caught_expected) { \ gtest_msg.value = \ "Expected: " #statement " throws an exception of type " \ #expected_exception ".\n Actual: it throws nothing."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ fail("Expected: " #statement " doesn't throw an exception.\n" \ " Actual: it throws.") #define GTEST_TEST_ANY_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ bool gtest_caught_any = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ gtest_caught_any = true; \ } \ if (!gtest_caught_any) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ fail("Expected: " #statement " throws an exception.\n" \ " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // represenation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = \ ::testing::AssertionResult(expression)) \ ; \ else \ fail(::testing::internal::GetBoolAssertionFailureMessage(\ gtest_ar_, text, #actual, #expected).c_str()) #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ fail("Expected: " #statement " doesn't generate new fatal " \ "failures in the current thread.\n" \ " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ test_case_name##_##test_name##_Test // Helper macro for defining tests. #define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ public:\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ private:\ virtual void TestBody();\ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ \ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ new ::testing::internal::TestFactoryImpl<\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-linked_ptr.h000644 000766 000024 00000020350 12650222322 025040 0ustar00iojsstaff000000 000000 // Copyright 2003 Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: Dan Egnor (egnor@google.com) // // A "smart" pointer type with reference tracking. Every pointer to a // particular object is kept on a circular linked list. When the last pointer // to an object is destroyed or reassigned, the object is deleted. // // Used properly, this deletes the object when the last reference goes away. // There are several caveats: // - Like all reference counting schemes, cycles lead to leaks. // - Each smart pointer is actually two pointers (8 bytes instead of 4). // - Every time a pointer is assigned, the entire list of pointers to that // object is traversed. This class is therefore NOT SUITABLE when there // will often be more than two or three pointers to a particular object. // - References are only tracked as long as linked_ptr<> objects are copied. // If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS // will happen (double deletion). // // A good use of this class is storing object references in STL containers. // You can safely put linked_ptr<> in a vector<>. // Other uses may not be as good. // // Note: If you use an incomplete type with linked_ptr<>, the class // *containing* linked_ptr<> must have a constructor and destructor (even // if they do nothing!). // // Bill Gibbons suggested we use something like this. // // Thread Safety: // Unlike other linked_ptr implementations, in this implementation // a linked_ptr object is thread-safe in the sense that: // - it's safe to copy linked_ptr objects concurrently, // - it's safe to copy *from* a linked_ptr and read its underlying // raw pointer (e.g. via get()) concurrently, and // - it's safe to write to two linked_ptrs that point to the same // shared object concurrently. // TODO(wan@google.com): rename this to safe_linked_ptr to avoid // confusion with normal linked_ptr. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // Protects copying of all linked_ptr objects. GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // This is used internally by all instances of linked_ptr<>. It needs to be // a non-template class because different types of linked_ptr<> can refer to // the same object (linked_ptr(obj) vs linked_ptr(obj)). // So, it needs to be possible for different types of linked_ptr to participate // in the same circular linked list, so we need a single class type here. // // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. class linked_ptr_internal { public: // Create a new circle that includes only this instance. void join_new() { next_ = this; } // Many linked_ptr operations may change p.link_ for some linked_ptr // variable p in the same circle as this object. Therefore we need // to prevent two such operations from occurring concurrently. // // Note that different types of linked_ptr objects can coexist in a // circle (e.g. linked_ptr, linked_ptr, and // linked_ptr). Therefore we must use a single mutex to // protect all linked_ptr objects. This can create serious // contention in production code, but is acceptable in a testing // framework. // Join an existing circle. void join(linked_ptr_internal const* ptr) GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; while (p->next_ != ptr) { assert(p->next_ != this && "Trying to join() a linked ring we are already in. " "Is GMock thread safety enabled?"); p = p->next_; } p->next_ = this; next_ = ptr; } // Leave whatever circle we're part of. Returns true if we were the // last member of the circle. Once this is done, you can join() another. bool depart() GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { MutexLock lock(&g_linked_ptr_mutex); if (next_ == this) return true; linked_ptr_internal const* p = next_; while (p->next_ != this) { assert(p->next_ != next_ && "Trying to depart() a linked ring we are not in. " "Is GMock thread safety enabled?"); p = p->next_; } p->next_ = next_; return false; } private: mutable linked_ptr_internal const* next_; }; template class linked_ptr { public: typedef T element_type; // Take over ownership of a raw pointer. This should happen as soon as // possible after the object is created. explicit linked_ptr(T* ptr = NULL) { capture(ptr); } ~linked_ptr() { depart(); } // Copy an existing linked_ptr<>, adding ourselves to the list of references. template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } linked_ptr(linked_ptr const& ptr) { // NOLINT assert(&ptr != this); copy(&ptr); } // Assignment releases the old value and acquires the new. template linked_ptr& operator=(linked_ptr const& ptr) { depart(); copy(&ptr); return *this; } linked_ptr& operator=(linked_ptr const& ptr) { if (&ptr != this) { depart(); copy(&ptr); } return *this; } // Smart pointer members. void reset(T* ptr = NULL) { depart(); capture(ptr); } T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } bool operator==(T* p) const { return value_ == p; } bool operator!=(T* p) const { return value_ != p; } template bool operator==(linked_ptr const& ptr) const { return value_ == ptr.get(); } template bool operator!=(linked_ptr const& ptr) const { return value_ != ptr.get(); } private: template friend class linked_ptr; T* value_; linked_ptr_internal link_; void depart() { if (link_.depart()) delete value_; } void capture(T* ptr) { value_ = ptr; link_.join_new(); } template void copy(linked_ptr const* ptr) { value_ = ptr->get(); if (value_) link_.join(&ptr->link_); else link_.join_new(); } }; template inline bool operator==(T* ptr, const linked_ptr& x) { return ptr == x.get(); } template inline bool operator!=(T* ptr, const linked_ptr& x) { return ptr != x.get(); } // A function to convert T* into linked_ptr // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation // for linked_ptr >(new FooBarBaz(arg)) template linked_ptr make_linked_ptr(T* ptr) { return linked_ptr(ptr); } } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-param-util-generated.h000644 000766 000024 00000567207 12650222322 026735 0ustar00iojsstaff000000 000000 // This file was GENERATED by command: // pump.py gtest-param-util-generated.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. // This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently Google Test supports at most 50 arguments in Values, // and at most 10 arguments in Combine. Please contact // googletestframework@googlegroups.com if you need more. // Please note that the number of arguments to Combine is limited // by the maximum arity of the implementation of tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-param-util.h" #include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST namespace testing { // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( const Container& container); namespace internal { // Used in the Values() function to provide polymorphic capabilities. template class ValueArray1 { public: explicit ValueArray1(T1 v1) : v1_(v1) {} template operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray1& other); const T1 v1_; }; template class ValueArray2 { public: ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray2& other); const T1 v1_; const T2 v2_; }; template class ValueArray3 { public: ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray3& other); const T1 v1_; const T2 v2_; const T3 v3_; }; template class ValueArray4 { public: ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), v4_(v4) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray4& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; }; template class ValueArray5 { public: ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray5& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; }; template class ValueArray6 { public: ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray6& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; }; template class ValueArray7 { public: ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray7& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; }; template class ValueArray8 { public: ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray8& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; }; template class ValueArray9 { public: ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray9& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; }; template class ValueArray10 { public: ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray10& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; }; template class ValueArray11 { public: ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray11& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; }; template class ValueArray12 { public: ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray12& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; }; template class ValueArray13 { public: ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray13& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; }; template class ValueArray14 { public: ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray14& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; }; template class ValueArray15 { public: ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray15& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; }; template class ValueArray16 { public: ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray16& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; }; template class ValueArray17 { public: ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray17& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; }; template class ValueArray18 { public: ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray18& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; }; template class ValueArray19 { public: ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray19& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; }; template class ValueArray20 { public: ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray20& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; }; template class ValueArray21 { public: ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray21& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; }; template class ValueArray22 { public: ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray22& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; }; template class ValueArray23 { public: ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray23& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; }; template class ValueArray24 { public: ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray24& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; }; template class ValueArray25 { public: ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray25& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; }; template class ValueArray26 { public: ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray26& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; }; template class ValueArray27 { public: ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray27& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; }; template class ValueArray28 { public: ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray28& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; }; template class ValueArray29 { public: ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray29& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; }; template class ValueArray30 { public: ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray30& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; }; template class ValueArray31 { public: ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray31& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; }; template class ValueArray32 { public: ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray32& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; }; template class ValueArray33 { public: ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray33& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; }; template class ValueArray34 { public: ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray34& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; }; template class ValueArray35 { public: ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray35& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; }; template class ValueArray36 { public: ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray36& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; }; template class ValueArray37 { public: ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray37& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; }; template class ValueArray38 { public: ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray38& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; }; template class ValueArray39 { public: ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray39& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; }; template class ValueArray40 { public: ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray40& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; }; template class ValueArray41 { public: ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray41& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; }; template class ValueArray42 { public: ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray42& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; }; template class ValueArray43 { public: ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray43& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; }; template class ValueArray44 { public: ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray44& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; }; template class ValueArray45 { public: ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray45& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; }; template class ValueArray46 { public: ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray46& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; }; template class ValueArray47 { public: ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray47& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; }; template class ValueArray48 { public: ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray48& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; }; template class ValueArray49 { public: ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray49& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; }; template class ValueArray50 { public: ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} template operator ParamGenerator() const { const T array[] = {static_cast(v1_), static_cast(v2_), static_cast(v3_), static_cast(v4_), static_cast(v5_), static_cast(v6_), static_cast(v7_), static_cast(v8_), static_cast(v9_), static_cast(v10_), static_cast(v11_), static_cast(v12_), static_cast(v13_), static_cast(v14_), static_cast(v15_), static_cast(v16_), static_cast(v17_), static_cast(v18_), static_cast(v19_), static_cast(v20_), static_cast(v21_), static_cast(v22_), static_cast(v23_), static_cast(v24_), static_cast(v25_), static_cast(v26_), static_cast(v27_), static_cast(v28_), static_cast(v29_), static_cast(v30_), static_cast(v31_), static_cast(v32_), static_cast(v33_), static_cast(v34_), static_cast(v35_), static_cast(v36_), static_cast(v37_), static_cast(v38_), static_cast(v39_), static_cast(v40_), static_cast(v41_), static_cast(v42_), static_cast(v43_), static_cast(v44_), static_cast(v45_), static_cast(v46_), static_cast(v47_), static_cast(v48_), static_cast(v49_), static_cast(v50_)}; return ValuesIn(array); } private: // No implementation - assignment is unsupported. void operator=(const ValueArray50& other); const T1 v1_; const T2 v2_; const T3 v3_; const T4 v4_; const T5 v5_; const T6 v6_; const T7 v7_; const T8 v8_; const T9 v9_; const T10 v10_; const T11 v11_; const T12 v12_; const T13 v13_; const T14 v14_; const T15 v15_; const T16 v16_; const T17 v17_; const T18 v18_; const T19 v19_; const T20 v20_; const T21 v21_; const T22 v22_; const T23 v23_; const T24 v24_; const T25 v25_; const T26 v26_; const T27 v27_; const T28 v28_; const T29 v29_; const T30 v30_; const T31 v31_; const T32 v32_; const T33 v33_; const T34 v34_; const T35 v35_; const T36 v36_; const T37 v37_; const T38 v38_; const T39 v39_; const T40 v40_; const T41 v41_; const T42 v42_; const T43 v43_; const T44 v44_; const T45 v45_; const T46 v46_; const T47 v47_; const T48 v48_; const T49 v49_; const T50 v50_; }; # if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced // by the argument generators. // template class CartesianProductGenerator2 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator2(const ParamGenerator& g1, const ParamGenerator& g2) : g1_(g1), g2_(g2) {} virtual ~CartesianProductGenerator2() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current2_; if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; ParamType current_value_; }; // class CartesianProductGenerator2::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator2& other); const ParamGenerator g1_; const ParamGenerator g2_; }; // class CartesianProductGenerator2 template class CartesianProductGenerator3 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator3(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3) : g1_(g1), g2_(g2), g3_(g3) {} virtual ~CartesianProductGenerator3() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current3_; if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; ParamType current_value_; }; // class CartesianProductGenerator3::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator3& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; }; // class CartesianProductGenerator3 template class CartesianProductGenerator4 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator4(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} virtual ~CartesianProductGenerator4() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current4_; if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; ParamType current_value_; }; // class CartesianProductGenerator4::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator4& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; }; // class CartesianProductGenerator4 template class CartesianProductGenerator5 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator5(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} virtual ~CartesianProductGenerator5() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current5_; if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; ParamType current_value_; }; // class CartesianProductGenerator5::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator5& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; }; // class CartesianProductGenerator5 template class CartesianProductGenerator6 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator6(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} virtual ~CartesianProductGenerator6() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current6_; if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; ParamType current_value_; }; // class CartesianProductGenerator6::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator6& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; }; // class CartesianProductGenerator6 template class CartesianProductGenerator7 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator7(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} virtual ~CartesianProductGenerator7() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current7_; if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; ParamType current_value_; }; // class CartesianProductGenerator7::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator7& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; }; // class CartesianProductGenerator7 template class CartesianProductGenerator8 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator8(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} virtual ~CartesianProductGenerator8() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current8_; if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; ParamType current_value_; }; // class CartesianProductGenerator8::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator8& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; }; // class CartesianProductGenerator8 template class CartesianProductGenerator9 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator9(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} virtual ~CartesianProductGenerator9() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current9_; if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; ParamType current_value_; }; // class CartesianProductGenerator9::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator9& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; }; // class CartesianProductGenerator9 template class CartesianProductGenerator10 : public ParamGeneratorInterface< ::testing::tuple > { public: typedef ::testing::tuple ParamType; CartesianProductGenerator10(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, const ParamGenerator& g4, const ParamGenerator& g5, const ParamGenerator& g6, const ParamGenerator& g7, const ParamGenerator& g8, const ParamGenerator& g9, const ParamGenerator& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} virtual ~CartesianProductGenerator10() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, g8_.end(), g9_, g9_.end(), g10_, g10_.end()); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, const ParamGenerator& g1, const typename ParamGenerator::iterator& current1, const ParamGenerator& g2, const typename ParamGenerator::iterator& current2, const ParamGenerator& g3, const typename ParamGenerator::iterator& current3, const ParamGenerator& g4, const typename ParamGenerator::iterator& current4, const ParamGenerator& g5, const typename ParamGenerator::iterator& current5, const ParamGenerator& g6, const typename ParamGenerator::iterator& current6, const ParamGenerator& g7, const typename ParamGenerator::iterator& current7, const ParamGenerator& g8, const typename ParamGenerator::iterator& current8, const ParamGenerator& g9, const typename ParamGenerator::iterator& current9, const ParamGenerator& g10, const typename ParamGenerator::iterator& current10) : base_(base), begin1_(g1.begin()), end1_(g1.end()), current1_(current1), begin2_(g2.begin()), end2_(g2.end()), current2_(current2), begin3_(g3.begin()), end3_(g3.end()), current3_(current3), begin4_(g4.begin()), end4_(g4.end()), current4_(current4), begin5_(g5.begin()), end5_(g5.end()), current5_(current5), begin6_(g6.begin()), end6_(g6.end()), current6_(current6), begin7_(g7.begin()), end7_(g7.end()), current7_(current7), begin8_(g8.begin()), end8_(g8.end()), current8_(current8), begin9_(g9.begin()), end9_(g9.end()), current9_(current9), begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { ComputeCurrentValue(); } virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } // Advance should not be called on beyond-of-range iterators // so no component iterators must be beyond end of range, either. virtual void Advance() { assert(!AtEnd()); ++current10_; if (current10_ == end10_) { current10_ = begin10_; ++current9_; } if (current9_ == end9_) { current9_ = begin9_; ++current8_; } if (current8_ == end8_) { current8_ = begin8_; ++current7_; } if (current7_ == end7_) { current7_ = begin7_; ++current6_; } if (current6_ == end6_) { current6_ = begin6_; ++current5_; } if (current5_ == end5_) { current5_ = begin5_; ++current4_; } if (current4_ == end4_) { current4_ = begin4_; ++current3_; } if (current3_ == end3_) { current3_ = begin3_; ++current2_; } if (current2_ == end2_) { current2_ = begin2_; ++current1_; } ComputeCurrentValue(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const ParamType* Current() const { return ¤t_value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const Iterator* typed_other = CheckedDowncastToActualType(&other); // We must report iterators equal if they both point beyond their // respective ranges. That can happen in a variety of fashions, // so we have to consult AtEnd(). return (AtEnd() && typed_other->AtEnd()) || ( current1_ == typed_other->current1_ && current2_ == typed_other->current2_ && current3_ == typed_other->current3_ && current4_ == typed_other->current4_ && current5_ == typed_other->current5_ && current6_ == typed_other->current6_ && current7_ == typed_other->current7_ && current8_ == typed_other->current8_ && current9_ == typed_other->current9_ && current10_ == typed_other->current10_); } private: Iterator(const Iterator& other) : base_(other.base_), begin1_(other.begin1_), end1_(other.end1_), current1_(other.current1_), begin2_(other.begin2_), end2_(other.end2_), current2_(other.current2_), begin3_(other.begin3_), end3_(other.end3_), current3_(other.current3_), begin4_(other.begin4_), end4_(other.end4_), current4_(other.current4_), begin5_(other.begin5_), end5_(other.end5_), current5_(other.current5_), begin6_(other.begin6_), end6_(other.end6_), current6_(other.current6_), begin7_(other.begin7_), end7_(other.end7_), current7_(other.current7_), begin8_(other.begin8_), end8_(other.end8_), current8_(other.current8_), begin9_(other.begin9_), end9_(other.end9_), current9_(other.current9_), begin10_(other.begin10_), end10_(other.end10_), current10_(other.current10_) { ComputeCurrentValue(); } void ComputeCurrentValue() { if (!AtEnd()) current_value_ = ParamType(*current1_, *current2_, *current3_, *current4_, *current5_, *current6_, *current7_, *current8_, *current9_, *current10_); } bool AtEnd() const { // We must report iterator past the end of the range when either of the // component iterators has reached the end of its range. return current1_ == end1_ || current2_ == end2_ || current3_ == end3_ || current4_ == end4_ || current5_ == end5_ || current6_ == end6_ || current7_ == end7_ || current8_ == end8_ || current9_ == end9_ || current10_ == end10_; } // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. // current[i]_ is the actual traversing iterator. const typename ParamGenerator::iterator begin1_; const typename ParamGenerator::iterator end1_; typename ParamGenerator::iterator current1_; const typename ParamGenerator::iterator begin2_; const typename ParamGenerator::iterator end2_; typename ParamGenerator::iterator current2_; const typename ParamGenerator::iterator begin3_; const typename ParamGenerator::iterator end3_; typename ParamGenerator::iterator current3_; const typename ParamGenerator::iterator begin4_; const typename ParamGenerator::iterator end4_; typename ParamGenerator::iterator current4_; const typename ParamGenerator::iterator begin5_; const typename ParamGenerator::iterator end5_; typename ParamGenerator::iterator current5_; const typename ParamGenerator::iterator begin6_; const typename ParamGenerator::iterator end6_; typename ParamGenerator::iterator current6_; const typename ParamGenerator::iterator begin7_; const typename ParamGenerator::iterator end7_; typename ParamGenerator::iterator current7_; const typename ParamGenerator::iterator begin8_; const typename ParamGenerator::iterator end8_; typename ParamGenerator::iterator current8_; const typename ParamGenerator::iterator begin9_; const typename ParamGenerator::iterator end9_; typename ParamGenerator::iterator current9_; const typename ParamGenerator::iterator begin10_; const typename ParamGenerator::iterator end10_; typename ParamGenerator::iterator current10_; ParamType current_value_; }; // class CartesianProductGenerator10::Iterator // No implementation - assignment is unsupported. void operator=(const CartesianProductGenerator10& other); const ParamGenerator g1_; const ParamGenerator g2_; const ParamGenerator g3_; const ParamGenerator g4_; const ParamGenerator g5_; const ParamGenerator g6_; const ParamGenerator g7_; const ParamGenerator g8_; const ParamGenerator g9_; const ParamGenerator g10_; }; // class CartesianProductGenerator10 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow // casting CartesianProductGeneratorN to ParamGenerator if T is // convertible to U. // template class CartesianProductHolder2 { public: CartesianProductHolder2(const Generator1& g1, const Generator2& g2) : g1_(g1), g2_(g2) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator2( static_cast >(g1_), static_cast >(g2_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder2& other); const Generator1 g1_; const Generator2 g2_; }; // class CartesianProductHolder2 template class CartesianProductHolder3 { public: CartesianProductHolder3(const Generator1& g1, const Generator2& g2, const Generator3& g3) : g1_(g1), g2_(g2), g3_(g3) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator3( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder3& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; }; // class CartesianProductHolder3 template class CartesianProductHolder4 { public: CartesianProductHolder4(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator4( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder4& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; }; // class CartesianProductHolder4 template class CartesianProductHolder5 { public: CartesianProductHolder5(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator5( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder5& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; }; // class CartesianProductHolder5 template class CartesianProductHolder6 { public: CartesianProductHolder6(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator6( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder6& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; }; // class CartesianProductHolder6 template class CartesianProductHolder7 { public: CartesianProductHolder7(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator7( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder7& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; }; // class CartesianProductHolder7 template class CartesianProductHolder8 { public: CartesianProductHolder8(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator8( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder8& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; }; // class CartesianProductHolder8 template class CartesianProductHolder9 { public: CartesianProductHolder9(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator9( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder9& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; }; // class CartesianProductHolder9 template class CartesianProductHolder10 { public: CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4, const Generator5& g5, const Generator6& g6, const Generator7& g7, const Generator8& g8, const Generator9& g9, const Generator10& g10) : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} template operator ParamGenerator< ::testing::tuple >() const { return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator10( static_cast >(g1_), static_cast >(g2_), static_cast >(g3_), static_cast >(g4_), static_cast >(g5_), static_cast >(g6_), static_cast >(g7_), static_cast >(g8_), static_cast >(g9_), static_cast >(g10_))); } private: // No implementation - assignment is unsupported. void operator=(const CartesianProductHolder10& other); const Generator1 g1_; const Generator2 g2_; const Generator3 g3_; const Generator4 g4_; const Generator5 g5_; const Generator6 g6_; const Generator7 g7_; const Generator8 g8_; const Generator9 g9_; const Generator10 g10_; }; // class CartesianProductHolder10 # endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-param-util.h000644 000766 000024 00000057177 12650222322 025001 0ustar00iojsstaff000000 000000 // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: vladl@google.com (Vlad Losev) // Type and function utilities for implementing parameterized tests. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ #include #include #include // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-linked_ptr.h" #include "gtest/internal/gtest-port.h" #include "gtest/gtest-printers.h" #if GTEST_HAS_PARAM_TEST namespace testing { namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Outputs a message explaining invalid registration of different // fixture class for the same test case. This may happen when // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, const char* file, int line); template class ParamGeneratorInterface; template class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. template class ParamIteratorInterface { public: virtual ~ParamIteratorInterface() {} // A pointer to the base generator instance. // Used only for the purposes of iterator comparison // to make sure that two iterators belong to the same generator. virtual const ParamGeneratorInterface* BaseGenerator() const = 0; // Advances iterator to point to the next element // provided by the generator. The caller is responsible // for not calling Advance() on an iterator equal to // BaseGenerator()->End(). virtual void Advance() = 0; // Clones the iterator object. Used for implementing copy semantics // of ParamIterator. virtual ParamIteratorInterface* Clone() const = 0; // Dereferences the current iterator and provides (read-only) access // to the pointed value. It is the caller's responsibility not to call // Current() on an iterator equal to BaseGenerator()->End(). // Used for implementing ParamGenerator::operator*(). virtual const T* Current() const = 0; // Determines whether the given iterator and other point to the same // element in the sequence generated by the generator. // Used for implementing ParamGenerator::operator==(). virtual bool Equals(const ParamIteratorInterface& other) const = 0; }; // Class iterating over elements provided by an implementation of // ParamGeneratorInterface. It wraps ParamIteratorInterface // and implements the const forward iterator concept. template class ParamIterator { public: typedef T value_type; typedef const T& reference; typedef ptrdiff_t difference_type; // ParamIterator assumes ownership of the impl_ pointer. ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} ParamIterator& operator=(const ParamIterator& other) { if (this != &other) impl_.reset(other.impl_->Clone()); return *this; } const T& operator*() const { return *impl_->Current(); } const T* operator->() const { return impl_->Current(); } // Prefix version of operator++. ParamIterator& operator++() { impl_->Advance(); return *this; } // Postfix version of operator++. ParamIterator operator++(int /*unused*/) { ParamIteratorInterface* clone = impl_->Clone(); impl_->Advance(); return ParamIterator(clone); } bool operator==(const ParamIterator& other) const { return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); } bool operator!=(const ParamIterator& other) const { return !(*this == other); } private: friend class ParamGenerator; explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} scoped_ptr > impl_; }; // ParamGeneratorInterface is the binary interface to access generators // defined in other translation units. template class ParamGeneratorInterface { public: typedef T ParamType; virtual ~ParamGeneratorInterface() {} // Generator interface definition virtual ParamIteratorInterface* Begin() const = 0; virtual ParamIteratorInterface* End() const = 0; }; // Wraps ParamGeneratorInterface and provides general generator syntax // compatible with the STL Container concept. // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. template class ParamGenerator { public: typedef ParamIterator iterator; explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} ParamGenerator& operator=(const ParamGenerator& other) { impl_ = other.impl_; return *this; } iterator begin() const { return iterator(impl_->Begin()); } iterator end() const { return iterator(impl_->End()); } private: linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to // generate sequences of user-defined types that implement operator+() and // operator<(). // This class is used in the Range() function. template class RangeGenerator : public ParamGeneratorInterface { public: RangeGenerator(T begin, T end, IncrementT step) : begin_(begin), end_(end), step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} virtual ~RangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, begin_, 0, step_); } virtual ParamIteratorInterface* End() const { return new Iterator(this, end_, end_index_, step_); } private: class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, T value, int index, IncrementT step) : base_(base), value_(value), index_(index), step_(step) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { value_ = value_ + step_; index_++; } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } virtual const T* Current() const { return &value_; } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; const int other_index = CheckedDowncastToActualType(&other)->index_; return index_ == other_index; } private: Iterator(const Iterator& other) : ParamIteratorInterface(), base_(other.base_), value_(other.value_), index_(other.index_), step_(other.step_) {} // No implementation - assignment is unsupported. void operator=(const Iterator& other); const ParamGeneratorInterface* const base_; T value_; int index_; const IncrementT step_; }; // class RangeGenerator::Iterator static int CalculateEndIndex(const T& begin, const T& end, const IncrementT& step) { int end_index = 0; for (T i = begin; i < end; i = i + step) end_index++; return end_index; } // No implementation - assignment is unsupported. void operator=(const RangeGenerator& other); const T begin_; const T end_; const IncrementT step_; // The index for the end() iterator. All the elements in the generated // sequence are indexed (0-based) to aid iterator comparison. const int end_index_; }; // class RangeGenerator // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator // is likely to persist beyond that stack frame. template class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { public: template ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) : container_(begin, end) {} virtual ~ValuesInIteratorRangeGenerator() {} virtual ParamIteratorInterface* Begin() const { return new Iterator(this, container_.begin()); } virtual ParamIteratorInterface* End() const { return new Iterator(this, container_.end()); } private: typedef typename ::std::vector ContainerType; class Iterator : public ParamIteratorInterface { public: Iterator(const ParamGeneratorInterface* base, typename ContainerType::const_iterator iterator) : base_(base), iterator_(iterator) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { return base_; } virtual void Advance() { ++iterator_; value_.reset(); } virtual ParamIteratorInterface* Clone() const { return new Iterator(*this); } // We need to use cached value referenced by iterator_ because *iterator_ // can return a temporary object (and of type other then T), so just // having "return &*iterator_;" doesn't work. // value_ is updated here and not in Advance() because Advance() // can advance iterator_ beyond the end of the range, and we cannot // detect that fact. The client code, on the other hand, is // responsible for not calling Current() on an out-of-range iterator. virtual const T* Current() const { if (value_.get() == NULL) value_.reset(new T(*iterator_)); return value_.get(); } virtual bool Equals(const ParamIteratorInterface& other) const { // Having the same base generator guarantees that the other // iterator is of the same type and we can downcast. GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) << "The program attempted to compare iterators " << "from different generators." << std::endl; return iterator_ == CheckedDowncastToActualType(&other)->iterator_; } private: Iterator(const Iterator& other) // The explicit constructor call suppresses a false warning // emitted by gcc when supplied with the -Wextra option. : ParamIteratorInterface(), base_(other.base_), iterator_(other.iterator_) {} const ParamGeneratorInterface* const base_; typename ContainerType::const_iterator iterator_; // A cached value of *iterator_. We keep it here to allow access by // pointer in the wrapping iterator's operator->(). // value_ needs to be mutable to be accessed in Current(). // Use of scoped_ptr helps manage cached value's lifetime, // which is bound by the lifespan of the iterator itself. mutable scoped_ptr value_; }; // class ValuesInIteratorRangeGenerator::Iterator // No implementation - assignment is unsupported. void operator=(const ValuesInIteratorRangeGenerator& other); const ContainerType container_; }; // class ValuesInIteratorRangeGenerator // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Stores a parameter value and later creates tests parameterized with that // value. template class ParameterizedTestFactory : public TestFactoryBase { public: typedef typename TestClass::ParamType ParamType; explicit ParameterizedTestFactory(ParamType parameter) : parameter_(parameter) {} virtual Test* CreateTest() { TestClass::SetParam(¶meter_); return new TestClass(); } private: const ParamType parameter_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactoryBase is a base class for meta-factories that create // test factories for passing into MakeAndRegisterTestInfo function. template class TestMetaFactoryBase { public: virtual ~TestMetaFactoryBase() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // TestMetaFactory creates test factories for passing into // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives // ownership of test factory pointer, same factory object cannot be passed // into that method twice. But ParameterizedTestCaseInfo is going to call // it for each Test/Parameter value combination. Thus it needs meta factory // creator class. template class TestMetaFactory : public TestMetaFactoryBase { public: typedef typename TestCase::ParamType ParamType; TestMetaFactory() {} virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { return new ParameterizedTestFactory(parameter); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfoBase is a generic interface // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase // accumulates test information provided by TEST_P macro invocations // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations // and uses that information to register all resulting test instances // in RegisterTests method. The ParameterizeTestCaseRegistry class holds // a collection of pointers to the ParameterizedTestCaseInfo objects // and calls RegisterTests() on each of them when asked. class ParameterizedTestCaseInfoBase { public: virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. virtual const string& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this // test case right before running them in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. virtual void RegisterTests() = 0; protected: ParameterizedTestCaseInfoBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P // macro invocations for a particular test case and generators // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that // test case. It registers tests with all values generated by all // generators when asked. template class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { public: // ParamType and GeneratorCreationFunc are private types but are required // for declarations of public methods AddTestPattern() and // AddTestCaseInstantiation(). typedef typename TestCase::ParamType ParamType; // A function that returns an instance of appropriate generator type. typedef ParamGenerator(GeneratorCreationFunc)(); explicit ParameterizedTestCaseInfo(const char* name) : test_case_name_(name) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } // TEST_P macro uses AddTestPattern() to record information // about a single test in a LocalTestInfo structure. // test_case_name is the base name of the test case (without invocation // prefix). test_base_name is the name of an individual test without // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is // test case base name and DoBar is test base name. void AddTestPattern(const char* test_case_name, const char* test_base_name, TestMetaFactoryBase* meta_factory) { tests_.push_back(linked_ptr(new TestInfo(test_case_name, test_base_name, meta_factory))); } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, const char* /* file */, int /* line */) { instantiations_.push_back(::std::make_pair(instantiation_name, func)); return 0; // Return value used only to run this method in namespace scope. } // UnitTest class invokes this method to register tests in this test case // test cases right before running tests in RUN_ALL_TESTS macro. // This method should not be called more then once on any single // instance of a ParameterizedTestCaseInfoBase derived class. // UnitTest has a guard to prevent from calling this method more then once. virtual void RegisterTests() { for (typename TestInfoContainer::iterator test_it = tests_.begin(); test_it != tests_.end(); ++test_it) { linked_ptr test_info = *test_it; for (typename InstantiationContainer::iterator gen_it = instantiations_.begin(); gen_it != instantiations_.end(); ++gen_it) { const string& instantiation_name = gen_it->first; ParamGenerator generator((*gen_it->second)()); string test_case_name; if ( !instantiation_name.empty() ) test_case_name = instantiation_name + "/"; test_case_name += test_info->test_case_base_name; int i = 0; for (typename ParamGenerator::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; test_name_stream << test_info->test_base_name << "/" << i; MakeAndRegisterTestInfo( test_case_name.c_str(), test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, test_info->test_meta_factory->CreateTestFactory(*param_it)); } // for param_it } // for gen_it } // for test_it } // RegisterTests private: // LocalTestInfo structure keeps information about a single test registered // with TEST_P macro. struct TestInfo { TestInfo(const char* a_test_case_base_name, const char* a_test_base_name, TestMetaFactoryBase* a_test_meta_factory) : test_case_base_name(a_test_case_base_name), test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory) {} const string test_case_base_name; const string test_base_name; const scoped_ptr > test_meta_factory; }; typedef ::std::vector > TestInfoContainer; // Keeps pairs of // received from INSTANTIATE_TEST_CASE_P macros. typedef ::std::vector > InstantiationContainer; const string test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); }; // class ParameterizedTestCaseInfo // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // macros use it to locate their corresponding ParameterizedTestCaseInfo // descriptors. class ParameterizedTestCaseRegistry { public: ParameterizedTestCaseRegistry() {} ~ParameterizedTestCaseRegistry() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { delete *it; } } // Looks up or creates and returns a structure containing information about // tests and instantiations of a particular test case. template ParameterizedTestCaseInfo* GetTestCasePatternHolder( const char* test_case_name, const char* file, int line) { ParameterizedTestCaseInfo* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { if ((*it)->GetTestCaseName() == test_case_name) { if ((*it)->GetTestCaseTypeId() != GetTypeId()) { // Complain about incorrect usage of Google Test facilities // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); posix::Abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type // without further checks. typed_test_info = CheckedDowncastToActualType< ParameterizedTestCaseInfo >(*it); } break; } } if (typed_test_info == NULL) { typed_test_info = new ParameterizedTestCaseInfo(test_case_name); test_case_infos_.push_back(typed_test_info); } return typed_test_info; } void RegisterTests() { for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { (*it)->RegisterTests(); } } private: typedef ::std::vector TestCaseInfoContainer; TestCaseInfoContainer test_case_infos_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); }; } // namespace internal } // namespace testing #endif // GTEST_HAS_PARAM_TEST #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-port.h000644 000766 000024 00000253130 12650222322 023675 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan) // // Low-level types and utilities for porting Google Test to various // platforms. All macros ending with _ and symbols defined in an // internal namespace are subject to change without notice. Code // outside Google Test MUST NOT USE THEM DIRECTLY. Macros that don't // end with _ are part of Google Test's public API and can be used by // code outside Google Test. // // This file is fundamental to Google Test. All other Google Test source // files are expected to #include this. Therefore, it cannot #include // any other Google Test header. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ // Environment-describing macros // ----------------------------- // // Google Test can be used in many different environments. Macros in // this section tell Google Test what kind of environment it is being // used in, such that Google Test can provide environment-specific // features and implementations. // // Google Test tries to automatically detect the properties of its // environment, so users usually don't need to worry about these // macros. However, the automatic detection is not perfect. // Sometimes it's necessary for a user to define some of the following // macros in the build script to override Google Test's decisions. // // If the user doesn't define a macro in the list, Google Test will // provide a default definition. After this header is #included, all // macros in this list will be defined to either 1 or 0. // // Notes to maintainers: // - Each macro here is a user-tweakable knob; do not grow the list // lightly. // - Use #if to key off these macros. Don't use #ifdef or "#if // defined(...)", which will not work as these macros are ALWAYS // defined. // // GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) // is/isn't available. // GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions // are enabled. // GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::string, which is different to std::string). // GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::wstring, which is different to std::wstring). // GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular // expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't // enabled. // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). // GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple // is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". // GTEST_HAS_STREAM_REDIRECTION // - Define it to 1/0 to indicate whether the // platform supports I/O stream redirection using // dup() and dup2(). // GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google // Test's own tr1 tuple implementation should be // used. Unused when the user sets // GTEST_HAS_TR1_TUPLE to 0. // GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test // is building in C++11/C++98 mode. // GTEST_LINKED_AS_SHARED_LIBRARY // - Define to 1 when compiling tests that use // Google Test as a shared library (known as // DLL on Windows). // GTEST_CREATE_SHARED_LIBRARY // - Define to 1 when compiling Google Test itself // as a shared library. // Platform-indicating macros // -------------------------- // // Macros indicating the platform on which Google Test is being used // (a macro is defined to 1 if compiled on the given platform; // otherwise UNDEFINED -- it's never defined to 0.). Google Test // defines these macros automatically. Code outside Google Test MUST // NOT define them. // // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin // GTEST_OS_FREEBSD - FreeBSD // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile // GTEST_OS_WINDOWS_PHONE - Windows Phone // GTEST_OS_WINDOWS_RT - Windows Store App/WinRT // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the // most stable support. Since core members of the Google Test project // don't have access to other platforms, support for them may be less // stable. If you notice any problems on your platform, please notify // googletestframework@googlegroups.com (patches for fixing them are // even more welcome!). // // It is possible that none of the GTEST_OS_* macros are defined. // Feature-indicating macros // ------------------------- // // Macros indicating which Google Test features are available (a macro // is defined to 1 if the corresponding feature is supported; // otherwise UNDEFINED -- it's never defined to 0.). Google Test // defines these macros automatically. Code outside Google Test MUST // NOT define them. // // These macros are public so that portable tests can be written. // Such tests typically surround code using a feature with an #if // which controls that code. For example: // // #if GTEST_HAS_DEATH_TEST // EXPECT_DEATH(DoSomethingDeadly()); // #endif // // GTEST_HAS_COMBINE - the Combine() function (for value-parameterized // tests) // GTEST_HAS_DEATH_TEST - death tests // GTEST_HAS_PARAM_TEST - value-parameterized tests // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_IS_THREADSAFE - Google Test is thread-safe. // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; // the above two are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). // Misc public macros // ------------------ // // GTEST_FLAG(flag_name) - references the variable corresponding to // the given Google Test flag. // Internal utilities // ------------------ // // The following macros and utilities are for Google Test's INTERNAL // use only. Code outside Google Test MUST NOT USE THEM DIRECTLY. // // Macros for basic C++ coding: // GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. // GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a // variable don't have to be used. // GTEST_DISALLOW_ASSIGN_ - disables operator=. // GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. // GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. // GTEST_INTENTIONAL_CONST_COND_PUSH_ - start code section where MSVC C4127 is // suppressed (constant conditional). // GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127 // is suppressed. // // C++11 feature wrappers: // // testing::internal::move - portability wrapper for std::move. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() // - synchronization primitives. // // Template meta programming: // is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. // IteratorTraits - partial implementation of std::iterator_traits, which // is not available in libCstd when compiled with Sun C++. // // Smart pointers: // scoped_ptr - as in TR2. // // Regular expressions: // RE - a simple regular expression class using the POSIX // Extended Regular Expression syntax on UNIX-like // platforms, or a reduced regular exception syntax on // other platforms, including Windows. // // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. // // Stdout and stderr capturing: // CaptureStdout() - starts capturing stdout. // GetCapturedStdout() - stops capturing stdout and returns the captured // string. // CaptureStderr() - starts capturing stderr. // GetCapturedStderr() - stops capturing stderr and returns the captured // string. // // Integer types: // TypeWithSize - maps an integer to a int type. // Int32, UInt32, Int64, UInt64, TimeInMillis // - integers of known sizes. // BiggestInt - the biggest signed integer type. // // Command-line utilities: // GTEST_DECLARE_*() - declares a flag. // GTEST_DEFINE_*() - defines a flag. // GetInjectableArgvs() - returns the command line as a vector of strings. // // Environment variable utilities: // GetEnv() - gets the value of an environment variable. // BoolFromGTestEnv() - parses a bool environment variable. // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. #include // for isspace, etc #include // for ptrdiff_t #include #include #include #ifndef _WIN32_WCE # include # include #endif // !_WIN32_WCE #if defined __APPLE__ # include # include #endif #include // NOLINT #include // NOLINT #include // NOLINT #include // NOLINT #include #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_FLAG_PREFIX_ "gtest_" #define GTEST_FLAG_PREFIX_DASH_ "gtest-" #define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" #define GTEST_NAME_ "Google Test" #define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. # define GTEST_GCC_VER_ \ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ # define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ # define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 # define GTEST_OS_WINDOWS 1 # ifdef _WIN32_WCE # define GTEST_OS_WINDOWS_MOBILE 1 # elif defined(__MINGW__) || defined(__MINGW32__) # define GTEST_OS_WINDOWS_MINGW 1 # elif defined(WINAPI_FAMILY) # include # if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) # define GTEST_OS_WINDOWS_DESKTOP 1 # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) # define GTEST_OS_WINDOWS_PHONE 1 # elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) # define GTEST_OS_WINDOWS_RT 1 # else // WINAPI_FAMILY defined but no known partition matched. // Default to desktop. # define GTEST_OS_WINDOWS_DESKTOP 1 # endif # else # define GTEST_OS_WINDOWS_DESKTOP 1 # endif // _WIN32_WCE #elif defined __APPLE__ # define GTEST_OS_MAC 1 # if TARGET_OS_IPHONE # define GTEST_OS_IOS 1 # endif #elif defined __FreeBSD__ # define GTEST_OS_FREEBSD 1 #elif defined __linux__ # define GTEST_OS_LINUX 1 # if defined __ANDROID__ # define GTEST_OS_LINUX_ANDROID 1 # endif #elif defined __MVS__ # define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) # define GTEST_OS_SOLARIS 1 #elif defined(_AIX) # define GTEST_OS_AIX 1 #elif defined(__hpux) # define GTEST_OS_HPUX 1 #elif defined __native_client__ # define GTEST_OS_NACL 1 #elif defined __OpenBSD__ # define GTEST_OS_OPENBSD 1 #elif defined __QNX__ # define GTEST_OS_QNX 1 #endif // __CYGWIN__ // Macros for disabling Microsoft Visual C++ warnings. // // GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) // /* code that triggers warnings C4800 and C4385 */ // GTEST_DISABLE_MSC_WARNINGS_POP_() #if _MSC_VER >= 1500 # define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ __pragma(warning(push)) \ __pragma(warning(disable: warnings)) # define GTEST_DISABLE_MSC_WARNINGS_POP_() \ __pragma(warning(pop)) #else // Older versions of MSVC don't have __pragma. # define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) # define GTEST_DISABLE_MSC_WARNINGS_POP_() #endif #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a // value for __cplusplus, and recent versions of clang, gcc, and // probably other compilers set that too in C++11 mode. # if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L // Compiling in at least C++11 mode. # define GTEST_LANG_CXX11 1 # else # define GTEST_LANG_CXX11 0 # endif #endif // Distinct from C++11 language support, some environments don't provide // proper C++11 library support. Notably, it's possible to build in // C++11 mode when targeting Mac OS X 10.6, which has an old libstdc++ // with no C++11 support. // // libstdc++ has sufficient C++11 support as of GCC 4.6.0, __GLIBCXX__ // 20110325, but maintenance releases in the 4.4 and 4.5 series followed // this date, so check for those versions by their date stamps. // https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning #if GTEST_LANG_CXX11 && \ (!defined(__GLIBCXX__) || ( \ __GLIBCXX__ >= 20110325ul && /* GCC >= 4.6.0 */ \ /* Blacklist of patch releases of older branches: */ \ __GLIBCXX__ != 20110416ul && /* GCC 4.4.6 */ \ __GLIBCXX__ != 20120313ul && /* GCC 4.4.7 */ \ __GLIBCXX__ != 20110428ul && /* GCC 4.5.3 */ \ __GLIBCXX__ != 20120702ul)) /* GCC 4.5.4 */ # define GTEST_STDLIB_CXX11 1 #endif // Only use C++11 library features if the library provides them. #if GTEST_STDLIB_CXX11 # define GTEST_HAS_STD_BEGIN_AND_END_ 1 # define GTEST_HAS_STD_FORWARD_LIST_ 1 # define GTEST_HAS_STD_FUNCTION_ 1 # define GTEST_HAS_STD_INITIALIZER_LIST_ 1 # define GTEST_HAS_STD_MOVE_ 1 # define GTEST_HAS_STD_UNIQUE_PTR_ 1 #endif // C++11 specifies that provides std::tuple. // Some platforms still might not have it, however. #if GTEST_LANG_CXX11 # define GTEST_HAS_STD_TUPLE_ 1 # if defined(__clang__) // Inspired by http://clang.llvm.org/docs/LanguageExtensions.html#__has_include # if defined(__has_include) && !__has_include() # undef GTEST_HAS_STD_TUPLE_ # endif # elif defined(_MSC_VER) // Inspired by boost/config/stdlib/dinkumware.hpp # if defined(_CPPLIB_VER) && _CPPLIB_VER < 520 # undef GTEST_HAS_STD_TUPLE_ # endif # elif defined(__GLIBCXX__) // Inspired by boost/config/stdlib/libstdcpp3.hpp, // http://gcc.gnu.org/gcc-4.2/changes.html and // http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x # if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) # undef GTEST_HAS_STD_TUPLE_ # endif # endif #endif // Brings in definitions for functions used in the testing::internal::posix // namespace (read, write, close, chdir, isatty, stat). We do not currently // use them on Windows Mobile. #if GTEST_OS_WINDOWS # if !GTEST_OS_WINDOWS_MOBILE # include # include # endif // In order to avoid having to include , use forward declaration // assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. // This assumption is verified by // WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. struct _RTL_CRITICAL_SECTION; #else // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. # include # include #endif // GTEST_OS_WINDOWS #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. # include // NOLINT #endif // Defines this to true iff Google Test can use POSIX regular expressions. #ifndef GTEST_HAS_POSIX_RE # if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # else # define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) # endif #endif #if GTEST_HAS_POSIX_RE // On some platforms, needs someone to define size_t, and // won't compile otherwise. We can #include it here as we already // included , which is guaranteed to define size_t through // . # include // NOLINT # define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS // is not available on Windows. Use our own simple regex // implementation instead. # define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 #endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. # ifndef _HAS_EXCEPTIONS # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS # elif defined(__clang__) // clang defines __EXCEPTIONS iff exceptions are enabled before clang 220714, // but iff cleanups are enabled after that. In Obj-C++ files, there can be // cleanups for ObjC exceptions which also need cleanups, even if C++ exceptions // are disabled. clang has __has_feature(cxx_exceptions) which checks for C++ // exceptions starting at clang r206352, but which checked for cleanups prior to // that. To reliably check for C++ exception availability with clang, check for // __EXCEPTIONS && __has_feature(cxx_exceptions). # define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 # elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. # define GTEST_HAS_EXCEPTIONS 1 # else // For other compilers, we assume exceptions are disabled to be // conservative. # define GTEST_HAS_EXCEPTIONS 0 # endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. # define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. # error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING #ifndef GTEST_HAS_STD_WSTRING // The user didn't tell us whether ::std::wstring is available, so we need // to figure it out. // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). # define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. # define GTEST_HAS_GLOBAL_WSTRING \ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. # ifdef _MSC_VER # ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) # ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ !defined(__EXCEPTIONS) # define GTEST_HAS_RTTI 0 # else # define GTEST_HAS_RTTI 1 # endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS # else # define GTEST_HAS_RTTI 0 # endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. # elif defined(__clang__) # define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. # elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) # ifdef __RTTI_ALL__ # define GTEST_HAS_RTTI 1 # else # define GTEST_HAS_RTTI 0 # endif # else // For all other compilers, we assume RTTI is enabled. # define GTEST_HAS_RTTI 1 # endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI # include #endif // Determines whether Google Test can use the pthreads library. #ifndef GTEST_HAS_PTHREAD // The user didn't tell us explicitly, so we make reasonable assumptions about // which platforms have pthreads support. // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. # define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NACL) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. # include // NOLINT // For timespec and nanosleep, used below. # include // NOLINT #endif // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE # if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) // STLport, provided with the Android NDK, has neither or . # define GTEST_HAS_TR1_TUPLE 0 # else // The user didn't tell us not to do it, so we assume it's OK. # define GTEST_HAS_TR1_TUPLE 1 # endif #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation // should be used. #ifndef GTEST_USE_OWN_TR1_TUPLE // The user didn't tell us, so we need to figure it out. // We use our own TR1 tuple if we aren't sure the user has an // implementation of it already. At this time, libstdc++ 4.0.0+ and // MSVC 2010 are the only mainstream standard libraries that come // with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler // pretends to be GCC by defining __GNUC__ and friends, but cannot // compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1 // tuple in a 323 MB Feature Pack download, which we cannot assume the // user has. QNX's QCC compiler is a modified GCC but it doesn't // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, // and it can be used with some compilers that define __GNUC__. # if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 # define GTEST_ENV_HAS_TR1_TUPLE_ 1 # endif // C++11 specifies that provides std::tuple. Use that if gtest is used // in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 // can build with clang but need to use gcc4.2's libstdc++). # if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) # define GTEST_ENV_HAS_STD_TUPLE_ 1 # endif # if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ # define GTEST_USE_OWN_TR1_TUPLE 0 # else # define GTEST_USE_OWN_TR1_TUPLE 1 # endif #endif // GTEST_USE_OWN_TR1_TUPLE // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing // tuple. #if GTEST_HAS_STD_TUPLE_ # include // IWYU pragma: export # define GTEST_TUPLE_NAMESPACE_ ::std #endif // GTEST_HAS_STD_TUPLE_ // We include tr1::tuple even if std::tuple is available to define printers for // them. #if GTEST_HAS_TR1_TUPLE # ifndef GTEST_TUPLE_NAMESPACE_ # define GTEST_TUPLE_NAMESPACE_ ::std::tr1 # endif // GTEST_TUPLE_NAMESPACE_ # if GTEST_USE_OWN_TR1_TUPLE # include "gtest/internal/gtest-tuple.h" // IWYU pragma: export // NOLINT # elif GTEST_ENV_HAS_STD_TUPLE_ # include // C++11 puts its tuple into the ::std namespace rather than // ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. // This causes undefined behavior, but supported compilers react in // the way we intend. namespace std { namespace tr1 { using ::std::get; using ::std::make_tuple; using ::std::tuple; using ::std::tuple_element; using ::std::tuple_size; } } # elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. # ifdef BOOST_HAS_TR1_TUPLE # undef BOOST_HAS_TR1_TUPLE # endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED # include // IWYU pragma: export // NOLINT # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . # if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. # define _TR1_FUNCTIONAL 1 # include # undef _TR1_FUNCTIONAL // Allows the user to #include // if he chooses to. # else # include // NOLINT # endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. # include // IWYU pragma: export // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE // Determines whether clone(2) is supported. // Usually it will only be available on Linux, excluding // Linux on the Itanium architecture. // Also see http://linux.die.net/man/2/clone. #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. # if GTEST_OS_LINUX && !defined(__ia64__) # if GTEST_OS_LINUX_ANDROID // On Android, clone() is only available on ARM starting with Gingerbread. # if defined(__arm__) && __ANDROID_API__ >= 9 # define GTEST_HAS_CLONE 1 # else # define GTEST_HAS_CLONE 0 # endif # else # define GTEST_HAS_CLONE 1 # endif # else # define GTEST_HAS_CLONE 0 # endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support stream redirection. This is used to test // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. # if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \ GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 # endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (GTEST_OS_MAC && !GTEST_OS_IOS) || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD) # define GTEST_HAS_DEATH_TEST 1 # include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore // all the compilers we care about are adequate for supporting // value-parameterized tests. #define GTEST_HAS_PARAM_TEST 1 // Determines whether to support type-driven tests. // Typed tests need and variadic macros, which GCC, VC++ 8.0, // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ defined(__IBMCPP__) || defined(__HP_aCC) # define GTEST_HAS_TYPED_TEST 1 # define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when // value-parameterized tests are enabled. The implementation doesn't // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) # define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX # define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. // The GNU compiler emits a warning if nested "if" statements are followed by // an "else" statement and braces are not used to explicitly disambiguate the // "else" binding. This leads to problems with code like: // // if (gate) // ASSERT_*(condition) << "Some message"; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else # define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to // prevent the compiler from optimizing away instances that are never // used. This is useful when all interesting logic happens inside the // c'tor and / or d'tor. Example: // // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED_; // // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #elif defined(__clang__) # if __has_attribute(unused) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) # endif #endif #ifndef GTEST_ATTRIBUTE_UNUSED_ # define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_ASSIGN_(type)\ void operator=(type const &) // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ type(type const &);\ GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations // following the argument list: // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) # define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) #else # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // MS C++ compiler emits warning when a conditional expression is compile time // constant. In some contexts this warning is false positive and needs to be // suppressed. Use the following two macros in such cases: // // GTEST_INTENTIONAL_CONST_COND_PUSH_() // while (true) { // GTEST_INTENTIONAL_CONST_COND_POP_() // } # define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) # define GTEST_INTENTIONAL_CONST_COND_POP_() \ GTEST_DISABLE_MSC_WARNINGS_POP_() // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally // does not exist on any other system. #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. # if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. # define GTEST_HAS_SEH 1 # else // Assume no SEH. # define GTEST_HAS_SEH 0 # endif #define GTEST_IS_THREADSAFE \ (0 \ || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \ || GTEST_HAS_PTHREAD) #endif // GTEST_HAS_SEH #ifdef _MSC_VER # if GTEST_LINKED_AS_SHARED_LIBRARY # define GTEST_API_ __declspec(dllimport) # elif GTEST_CREATE_SHARED_LIBRARY # define GTEST_API_ __declspec(dllexport) # endif #endif // _MSC_VER #ifndef GTEST_API_ # define GTEST_API_ #endif #ifdef __GNUC__ // Ask the compiler to never inline a given function. # define GTEST_NO_INLINE_ __attribute__((noinline)) #else # define GTEST_NO_INLINE_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) # define GTEST_HAS_CXXABI_H_ 1 #else # define GTEST_HAS_CXXABI_H_ 0 #endif // A function level attribute to disable checking for use of uninitialized // memory when built with MemorySanitizer. #if defined(__clang__) # if __has_feature(memory_sanitizer) # define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ \ __attribute__((no_sanitize_memory)) # else # define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ # endif // __has_feature(memory_sanitizer) #else # define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ #endif // __clang__ // A function level attribute to disable AddressSanitizer instrumentation. #if defined(__clang__) # if __has_feature(address_sanitizer) # define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ __attribute__((no_sanitize_address)) # else # define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ # endif // __has_feature(address_sanitizer) #else # define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ #endif // __clang__ // A function level attribute to disable ThreadSanitizer instrumentation. #if defined(__clang__) # if __has_feature(thread_sanitizer) # define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ __attribute__((no_sanitize_thread)) # else # define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ # endif // __has_feature(thread_sanitizer) #else # define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ #endif // __clang__ namespace testing { class Message; #if defined(GTEST_TUPLE_NAMESPACE_) // Import tuple and friends into the ::testing namespace. // It is part of our interface, having them in ::testing allows us to change // their types as needed. using GTEST_TUPLE_NAMESPACE_::get; using GTEST_TUPLE_NAMESPACE_::make_tuple; using GTEST_TUPLE_NAMESPACE_::tuple; using GTEST_TUPLE_NAMESPACE_::tuple_size; using GTEST_TUPLE_NAMESPACE_::tuple_element; #endif // defined(GTEST_TUPLE_NAMESPACE_) namespace internal { // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a // Secret object, which is what we want. class Secret; // The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time // expression is true. For example, you could use it to verify the // size of a static array: // // GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES, // names_incorrect_size); // // or to make sure a struct is smaller than a certain size: // // GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); // // The second argument to the macro is the name of the variable. If // the expression is false, most compilers will issue a warning/error // containing the name of the variable. #if GTEST_LANG_CXX11 # define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) #else // !GTEST_LANG_CXX11 template struct CompileAssert { }; # define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ #endif // !GTEST_LANG_CXX11 // Implementation details of GTEST_COMPILE_ASSERT_: // // (In C++11, we simply use static_assert instead of the following) // // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // // - The simpler definition // // #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] // // does not work, as gcc supports variable-length arrays whose sizes // are determined at run-time (this is gcc's extension and not part // of the C++ standard). As a result, gcc fails to reject the // following code with the simple definition: // // int foo; // GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is // // not a compile-time constant. // // - By using the type CompileAssert<(bool(expr))>, we ensures that // expr is a compile-time constant. (Template arguments must be // determined at compile-time.) // // - The outter parentheses in CompileAssert<(bool(expr))> are necessary // to work around a bug in gcc 3.4.4 and 4.0.1. If we had written // // CompileAssert // // instead, these compilers will refuse to compile // // GTEST_COMPILE_ASSERT_(5 > 0, some_message); // // (They seem to think the ">" in "5 > 0" marks the end of the // template argument list.) // // - The array size is (bool(expr) ? 1 : -1), instead of simply // // ((expr) ? 1 : -1). // // This is to avoid running into a bug in MS VC 7.1, which // causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. // StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. // // This template is declared, but intentionally undefined. template struct StaticAssertTypeEqHelper; template struct StaticAssertTypeEqHelper { enum { value = true }; }; // Evaluates to the number of elements in 'array'. #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) #if GTEST_HAS_GLOBAL_STRING typedef ::string string; #else typedef ::std::string string; #endif // GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_WSTRING typedef ::wstring wstring; #elif GTEST_HAS_STD_WSTRING typedef ::std::wstring wstring; #endif // GTEST_HAS_GLOBAL_WSTRING // A helper for suppressing warnings on constant condition. It just // returns 'condition'. GTEST_API_ bool IsTrue(bool condition); // Defines scoped_ptr. // This implementation of scoped_ptr is PARTIAL - it only contains // enough stuff to satisfy Google Test's need. template class scoped_ptr { public: typedef T element_type; explicit scoped_ptr(T* p = NULL) : ptr_(p) {} ~scoped_ptr() { reset(); } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } T* release() { T* const ptr = ptr_; ptr_ = NULL; return ptr; } void reset(T* p = NULL) { if (p != ptr_) { if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. delete ptr_; } ptr_ = p; } } friend void swap(scoped_ptr& a, scoped_ptr& b) { using std::swap; swap(a.ptr_, b.ptr_); } private: T* ptr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; // Defines RE. // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. class GTEST_API_ RE { public: // A copy constructor is required by the Standard to initialize object // references from r-values. RE(const RE& other) { Init(other.pattern()); } // Constructs an RE from a string. RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT #endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT ~RE(); // Returns the string representation of the regex. const char* pattern() const { return pattern_; } // FullMatch(str, re) returns true iff regular expression re matches // the entire str. // PartialMatch(str, re) returns true iff regular expression re // matches a substring of str (including str itself). // // TODO(wan@google.com): make FullMatch() and PartialMatch() work // when str contains NUL characters. static bool FullMatch(const ::std::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::std::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #if GTEST_HAS_GLOBAL_STRING static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } #endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re); private: void Init(const char* regex); // We use a const char* instead of an std::string, as Google Test used to be // used where std::string is not available. TODO(wan@google.com): change to // std::string. const char* pattern_; bool is_valid_; #if GTEST_USES_POSIX_RE regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). #else // GTEST_USES_SIMPLE_RE const char* full_pattern_; // For FullMatch(); #endif GTEST_DISALLOW_ASSIGN_(RE); }; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); // Formats a file location for compiler-independent XML output. // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, int line); // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. enum GTestLogSeverity { GTEST_INFO, GTEST_WARNING, GTEST_ERROR, GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of // scope. class GTEST_API_ GTestLog { public: GTestLog(GTestLogSeverity severity, const char* file, int line); // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. ~GTestLog(); ::std::ostream& GetStream() { return ::std::cerr; } private: const GTestLogSeverity severity_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; #define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition // is not satisfied. // Synopsys: // GTEST_CHECK_(boolean_condition); // or // GTEST_CHECK_(boolean_condition) << "Additional message"; // // This checks the condition and if the condition is not satisfied // it prints message about the condition violation, including the // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. #define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this // doesn't expand to a balanced 'if' statement, so enclose the macro // in {} if you need to use it as the only statement in an 'if' // branch. #define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ if (const int gtest_error = (posix_call)) \ GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error #if GTEST_HAS_STD_MOVE_ using std::move; #else // GTEST_HAS_STD_MOVE_ template const T& move(const T& t) { return t; } #endif // GTEST_HAS_STD_MOVE_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in // the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a // const Foo*). When you use ImplicitCast_, the compiler checks that // the cast is safe. Such explicit ImplicitCast_s are necessary in // surprisingly many situations where C++ demands an exact type match // instead of an argument type convertable to a target type. // // The syntax for using ImplicitCast_ is the same as for static_cast: // // ImplicitCast_(expr) // // ImplicitCast_ would have been part of the C++ standard library, // but the proposal was submitted too late. It will probably make // its way into the language in the future. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. template inline To ImplicitCast_(To x) { return ::testing::internal::move(x); } // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts // always succeed. When you downcast (that is, cast a pointer from // type Foo to type SubclassOfFoo), static_cast<> isn't safe, because // how do you know the pointer is really of type SubclassOfFoo? It // could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, // when you downcast, you should use this macro. In debug mode, we // use dynamic_cast<> to double-check the downcast is legal (we die // if it's not). In normal mode, we do the efficient static_cast<> // instead. Thus, it's important to test in debug mode to make sure // the cast is legal! // This is the only place in the code we should use dynamic_cast<>. // In particular, you SHOULDN'T be using dynamic_cast<> in order to // do RTTI (eg code like this: // if (dynamic_cast(foo)) HandleASubclass1Object(foo); // if (dynamic_cast(foo)) HandleASubclass2Object(foo); // You should design the code some other way not to need this. // // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. template // use like this: DownCast_(foo); inline To DownCast_(From* f) { // so we only accept pointers // Ensures that To is a sub-type of From *. This test is here only // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. GTEST_INTENTIONAL_CONST_COND_PUSH_() if (false) { GTEST_INTENTIONAL_CONST_COND_POP_() const To to = NULL; ::testing::internal::ImplicitCast_(to); } #if GTEST_HAS_RTTI // RTTI: debug mode only! GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); #endif return static_cast(f); } // Downcasts the pointer of type Base to Derived. // Derived must be a subclass of Base. The parameter MUST // point to a class of type Derived, not any subclass of it. // When RTTI is available, the function performs a runtime // check to enforce this. template Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); return dynamic_cast(base); // NOLINT #else return static_cast(base); // Poor man's downcast. #endif } #if GTEST_HAS_STREAM_REDIRECTION // Defines the stderr capturer: // CaptureStdout - starts capturing stdout. // GetCapturedStdout - stops capturing stdout and returns the captured string. // CaptureStderr - starts capturing stderr. // GetCapturedStderr - stops capturing stderr and returns the captured string. // GTEST_API_ void CaptureStdout(); GTEST_API_ std::string GetCapturedStdout(); GTEST_API_ void CaptureStderr(); GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* new_argvs); // A copy of all command line arguments. Set by InitGoogleTest(). extern ::std::vector g_argvs; #endif // GTEST_HAS_DEATH_TEST // Defines synchronization primitives. #if GTEST_IS_THREADSAFE # if GTEST_HAS_PTHREAD // Sleeps for (roughly) n milliseconds. This function is only for testing // Google Test's own constructs. Don't use it in user tests, either // directly or indirectly. inline void SleepMilliseconds(int n) { const timespec time = { 0, // 0 seconds. n * 1000L * 1000L, // And n ms. }; nanosleep(&time, NULL); } # endif // GTEST_HAS_PTHREAD # if 0 // OS detection # elif GTEST_HAS_PTHREAD // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. class Notification { public: Notification() : notified_(false) { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); } ~Notification() { pthread_mutex_destroy(&mutex_); } // Notifies all threads created with this notification to start. Must // be called from the controller thread. void Notify() { pthread_mutex_lock(&mutex_); notified_ = true; pthread_mutex_unlock(&mutex_); } // Blocks until the controller thread notifies. Must be called from a test // thread. void WaitForNotification() { for (;;) { pthread_mutex_lock(&mutex_); const bool notified = notified_; pthread_mutex_unlock(&mutex_); if (notified) break; SleepMilliseconds(10); } } private: pthread_mutex_t mutex_; bool notified_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; # elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT GTEST_API_ void SleepMilliseconds(int n); // Provides leak-safe Windows kernel handle ownership. // Used in death tests and in threading support. class GTEST_API_ AutoHandle { public: // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to // avoid including in this header file. Including is // undesirable because it defines a lot of symbols and macros that tend to // conflict with client code. This assumption is verified by // WindowsTypesTest.HANDLEIsVoidStar. typedef void* Handle; AutoHandle(); explicit AutoHandle(Handle handle); ~AutoHandle(); Handle Get() const; void Reset(); void Reset(Handle handle); private: // Returns true iff the handle is a valid handle object that can be closed. bool IsCloseable() const; Handle handle_; GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); }; // Allows a controller thread to pause execution of newly created // threads until notified. Instances of this class must be created // and destroyed in the controller thread. // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. class GTEST_API_ Notification { public: Notification(); void Notify(); void WaitForNotification(); private: AutoHandle event_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; # endif // OS detection // On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD // defined, but we don't want to use MinGW's pthreads implementation, which // has conformance problems with some versions of the POSIX standard. # if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. // Consequently, it cannot select a correct instantiation of ThreadWithParam // in order to call its Run(). Introducing ThreadWithParamBase as a // non-templated base class for ThreadWithParam allows us to bypass this // problem. class ThreadWithParamBase { public: virtual ~ThreadWithParamBase() {} virtual void Run() = 0; }; // pthread_create() accepts a pointer to a function type with the C linkage. // According to the Standard (7.5/1), function types with different linkages // are different even if they are otherwise identical. Some compilers (for // example, SunStudio) treat them as different types. Since class methods // cannot be defined with C-linkage we need to define a free C-function to // pass into pthread_create(). extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { static_cast(thread)->Run(); return NULL; } // Helper class for testing Google Test's multi-threading constructs. // To use it, write: // // void ThreadFunc(int param) { /* Do things with param */ } // Notification thread_can_start; // ... // // The thread_can_start parameter is optional; you can supply NULL. // ThreadWithParam thread(&ThreadFunc, 5, &thread_can_start); // thread_can_start.Notify(); // // These classes are only for testing Google Test's own constructs. Do // not use them in user tests, either directly or indirectly. template class ThreadWithParam : public ThreadWithParamBase { public: typedef void UserThreadFunc(T); ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), finished_(false) { ThreadWithParamBase* const base = this; // The thread can be created only after all fields except thread_ // have been initialized. GTEST_CHECK_POSIX_SUCCESS_( pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); } ~ThreadWithParam() { Join(); } void Join() { if (!finished_) { GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); finished_ = true; } } virtual void Run() { if (thread_can_start_ != NULL) thread_can_start_->WaitForNotification(); func_(param_); } private: UserThreadFunc* const func_; // User-supplied thread function. const T param_; // User-supplied parameter to the thread function. // When non-NULL, used to block execution until the controller thread // notifies. Notification* const thread_can_start_; bool finished_; // true iff we know that the thread function has finished. pthread_t thread_; // The native thread object. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; # endif // GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW # if 0 // OS detection # elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Mutex implements mutex on Windows platforms. It is used in conjunction // with class MutexLock: // // Mutex mutex; // ... // MutexLock lock(&mutex); // Acquires the mutex and releases it at the // // end of the current scope. // // A static Mutex *must* be defined or declared using one of the following // macros: // GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // // (A non-static Mutex is defined/declared in the usual way). class GTEST_API_ Mutex { public: enum MutexType { kStatic = 0, kDynamic = 1 }; // We rely on kStaticMutex being 0 as it is to what the linker initializes // type_ in static mutexes. critical_section_ will be initialized lazily // in ThreadSafeLazyInit(). enum StaticConstructorSelector { kStaticMutex = 0 }; // This constructor intentionally does nothing. It relies on type_ being // statically initialized to 0 (effectively setting it to kStatic) and on // ThreadSafeLazyInit() to lazily initialize the rest of the members. explicit Mutex(StaticConstructorSelector /*dummy*/) {} Mutex(); ~Mutex(); void Lock(); void Unlock(); // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void AssertHeld(); private: // Initializes owner_thread_id_ and critical_section_ in static mutexes. void ThreadSafeLazyInit(); // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx, // we assume that 0 is an invalid value for thread IDs. unsigned int owner_thread_id_; // For static mutexes, we rely on these members being initialized to zeros // by the linker. MutexType type_; long critical_section_init_phase_; // NOLINT _RTL_CRITICAL_SECTION* critical_section_; GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) // We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. That macro is used as a defensive measure to prevent against // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(Mutex* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: Mutex* const mutex_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; // Base class for ValueHolder. Allows a caller to hold and delete a value // without knowing its type. class ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; // Provides a way for a thread to send notifications to a ThreadLocal // regardless of its parameter type. class ThreadLocalBase { public: // Creates a new ValueHolder object holding a default value passed to // this ThreadLocal's constructor and returns it. It is the caller's // responsibility not to call this when the ThreadLocal instance already // has a value on the current thread. virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; protected: ThreadLocalBase() {} virtual ~ThreadLocalBase() {} private: GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); }; // Maps a thread to a set of ThreadLocals that have values instantiated on that // thread and notifies them when the thread exits. A ThreadLocal instance is // expected to persist until all threads it has values on have terminated. class GTEST_API_ ThreadLocalRegistry { public: // Registers thread_local_instance as having value on the current thread. // Returns a value that can be used to identify the thread from other threads. static ThreadLocalValueHolderBase* GetValueOnCurrentThread( const ThreadLocalBase* thread_local_instance); // Invoked when a ThreadLocal instance is destroyed. static void OnThreadLocalDestroyed( const ThreadLocalBase* thread_local_instance); }; class GTEST_API_ ThreadWithParamBase { public: void Join(); protected: class Runnable { public: virtual ~Runnable() {} virtual void Run() = 0; }; ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); virtual ~ThreadWithParamBase(); private: AutoHandle thread_; }; // Helper class for testing Google Test's multi-threading constructs. template class ThreadWithParam : public ThreadWithParamBase { public: typedef void UserThreadFunc(T); ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { } virtual ~ThreadWithParam() {} private: class RunnableImpl : public Runnable { public: RunnableImpl(UserThreadFunc* func, T param) : func_(func), param_(param) { } virtual ~RunnableImpl() {} virtual void Run() { func_(param_); } private: UserThreadFunc* const func_; const T param_; GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); }; GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; // Implements thread-local storage on Windows systems. // // // Thread 1 // ThreadLocal tl(100); // 100 is the default value for each thread. // // // Thread 2 // tl.set(150); // Changes the value for thread 2 only. // EXPECT_EQ(150, tl.get()); // // // Thread 1 // EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. // tl.set(200); // EXPECT_EQ(200, tl.get()); // // The template type argument T must have a public copy constructor. // In addition, the default ThreadLocal constructor requires T to have // a public default constructor. // // The users of a TheadLocal instance have to make sure that all but one // threads (including the main one) using that instance have exited before // destroying it. Otherwise, the per-thread objects managed for them by the // ThreadLocal instance are not guaranteed to be destroyed on all platforms. // // Google Test only uses global ThreadLocal objects. That means they // will die after main() has returned. Therefore, no per-thread // object managed by Google Test will be leaked as long as all threads // using Google Test have exited when main() returns. template class ThreadLocal : public ThreadLocalBase { public: ThreadLocal() : default_() {} explicit ThreadLocal(const T& value) : default_(value) {} ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } const T& get() const { return *pointer(); } void set(const T& value) { *pointer() = value; } private: // Holds a value of T. Can be deleted via its base class without the caller // knowing the type of T. class ValueHolder : public ThreadLocalValueHolderBase { public: explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } private: T value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); }; T* GetOrCreateValue() const { return static_cast( ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); } virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { return new ValueHolder(default_); } const T default_; // The default value for each thread. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; # elif GTEST_HAS_PTHREAD // MutexBase and Mutex implement mutex on pthreads-based platforms. class MutexBase { public: // Acquires this mutex. void Lock() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); owner_ = pthread_self(); has_owner_ = true; } // Releases this mutex. void Unlock() { // Since the lock is being released the owner_ field should no longer be // considered valid. We don't protect writing to has_owner_ here, as it's // the caller's responsibility to ensure that the current thread holds the // mutex when this is called. has_owner_ = false; GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); } // Does nothing if the current thread holds the mutex. Otherwise, crashes // with high probability. void AssertHeld() const { GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) << "The current thread is not holding the mutex @" << this; } // A static mutex may be used before main() is entered. It may even // be used before the dynamic initialization stage. Therefore we // must be able to initialize a static mutex object at link time. // This means MutexBase has to be a POD and its member variables // have to be public. public: pthread_mutex_t mutex_; // The underlying pthread mutex. // has_owner_ indicates whether the owner_ field below contains a valid thread // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All // accesses to the owner_ field should be protected by a check of this field. // An alternative might be to memset() owner_ to all zeros, but there's no // guarantee that a zero'd pthread_t is necessarily invalid or even different // from pthread_self(). bool has_owner_; pthread_t owner_; // The thread holding the mutex. }; // Forward-declares a static mutex. # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, // instead relying on default initialization for the unspecified fields. In // particular, the owner_ field (a pthread_t) is not explicitly initialized. // This allows initialization to work whether pthread_t is a scalar or struct. // The flag -Wmissing-field-initializers must not be specified for this to work. # define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. class Mutex : public MutexBase { public: Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); has_owner_ = false; } ~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); } private: GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; // We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. That macro is used as a defensive measure to prevent against // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) : mutex_(mutex) { mutex_->Lock(); } ~GTestMutexLock() { mutex_->Unlock(); } private: MutexBase* const mutex_; GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; // Helpers for ThreadLocal. // pthread_key_create() requires DeleteThreadLocalValue() to have // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. class ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; // Called by pthread to delete thread-local data stored by // pthread_setspecific(). extern "C" inline void DeleteThreadLocalValue(void* value_holder) { delete static_cast(value_holder); } // Implements thread-local storage on pthreads-based systems. template class ThreadLocal { public: ThreadLocal() : key_(CreateKey()), default_() {} explicit ThreadLocal(const T& value) : key_(CreateKey()), default_(value) {} ~ThreadLocal() { // Destroys the managed object for the current thread, if any. DeleteThreadLocalValue(pthread_getspecific(key_)); // Releases resources associated with the key. This will *not* // delete managed objects for other threads. GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); } T* pointer() { return GetOrCreateValue(); } const T* pointer() const { return GetOrCreateValue(); } const T& get() const { return *pointer(); } void set(const T& value) { *pointer() = value; } private: // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } private: T value_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); }; static pthread_key_t CreateKey() { pthread_key_t key; // When a thread exits, DeleteThreadLocalValue() will be called on // the object managed for that thread. GTEST_CHECK_POSIX_SUCCESS_( pthread_key_create(&key, &DeleteThreadLocalValue)); return key; } T* GetOrCreateValue() const { ThreadLocalValueHolderBase* const holder = static_cast(pthread_getspecific(key_)); if (holder != NULL) { return CheckedDowncastToActualType(holder)->pointer(); } ValueHolder* const new_holder = new ValueHolder(default_); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; const T default_; // The default value for each thread. GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; # endif // OS detection #else // GTEST_IS_THREADSAFE // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where // mutex is not supported - using Google Test in multiple threads is not // supported on such platforms. class Mutex { public: Mutex() {} void Lock() {} void Unlock() {} void AssertHeld() const {} }; # define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex // We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. That macro is used as a defensive measure to prevent against // inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than // "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT }; typedef GTestMutexLock MutexLock; template class ThreadLocal { public: ThreadLocal() : value_() {} explicit ThreadLocal(const T& value) : value_(value) {} T* pointer() { return &value_; } const T* pointer() const { return &value_; } const T& get() const { return value_; } void set(const T& value) { value_ = value; } private: T value_; }; #endif // GTEST_IS_THREADSAFE // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. GTEST_API_ size_t GetThreadCount(); // Passing non-POD classes through ellipsis (...) crashes the ARM // compiler and generates a warning in Sun Studio. The Nokia Symbian // and the IBM XL C/C++ compiler try to instantiate a copy constructor // for objects passed through ellipsis (...), failing for uncopyable // objects. We define this to ensure that only POD is passed through // ellipsis on these systems. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). # define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else # define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between // const T& and const T* in a function template. These compilers // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) # define GTEST_NEEDS_IS_POINTER_ 1 #endif template struct bool_constant { typedef bool_constant type; static const bool value = bool_value; }; template const bool bool_constant::value; typedef bool_constant false_type; typedef bool_constant true_type; template struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; template struct IteratorTraits { typedef typename Iterator::value_type value_type; }; template struct IteratorTraits { typedef T value_type; }; template struct IteratorTraits { typedef T value_type; }; #if GTEST_OS_WINDOWS # define GTEST_PATH_SEP_ "\\" # define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else # define GTEST_PATH_SEP_ "/" # define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS // Utilities for char. // isspace(int ch) and friends accept an unsigned char or EOF. char // may be signed, depending on the compiler (or compiler flags). // Therefore we need to cast a char to unsigned char before calling // isspace(), etc. inline bool IsAlpha(char ch) { return isalpha(static_cast(ch)) != 0; } inline bool IsAlNum(char ch) { return isalnum(static_cast(ch)) != 0; } inline bool IsDigit(char ch) { return isdigit(static_cast(ch)) != 0; } inline bool IsLower(char ch) { return islower(static_cast(ch)) != 0; } inline bool IsSpace(char ch) { return isspace(static_cast(ch)) != 0; } inline bool IsUpper(char ch) { return isupper(static_cast(ch)) != 0; } inline bool IsXDigit(char ch) { return isxdigit(static_cast(ch)) != 0; } inline bool IsXDigit(wchar_t ch) { const unsigned char low_byte = static_cast(ch); return ch == low_byte && isxdigit(low_byte) != 0; } inline char ToLower(char ch) { return static_cast(tolower(static_cast(ch))); } inline char ToUpper(char ch) { return static_cast(toupper(static_cast(ch))); } inline std::string StripTrailingSpaces(std::string str) { std::string::iterator it = str.end(); while (it != str.begin() && IsSpace(*--it)) it = str.erase(it); return str; } // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these // standard functions as macros, the wrapper cannot have the same name // as the wrapped function. namespace posix { // Functions with a different name on Windows. #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; # ifdef __BORLANDC__ inline int IsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } # else inline int IsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } # endif // __BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. # else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } # endif // GTEST_OS_WINDOWS_MOBILE #else typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } inline int IsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS // Functions deprecated by MSVC 8.0. GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); } // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. #if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); } #if !GTEST_OS_WINDOWS_MOBILE inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif inline int FClose(FILE* fp) { return fclose(fp); } #if !GTEST_OS_WINDOWS_MOBILE inline int Read(int fd, void* buf, unsigned int count) { return static_cast(read(fd, buf, count)); } inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT // We are on Windows CE, which has no environment variables. static_cast(name); // To prevent 'unused argument' warning. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the // empty string rather than unset (NULL). Handle that case. const char* const env = getenv(name); return (env != NULL && env[0] != '\0') ? env : NULL; #else return getenv(name); #endif } GTEST_DISABLE_MSC_WARNINGS_POP_() #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in // several places in Google Test. This implementation provides a reasonable // imitation of standard behaviour. void Abort(); #else inline void Abort() { abort(); } #endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix // MSVC "deprecates" snprintf and issues warnings wherever it is used. In // order to avoid these warnings, we need to use _snprintf or _snprintf_s on // MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate // function in order to achieve that. We use macro definition here because // snprintf is a variadic function. #if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. # define GTEST_SNPRINTF_(buffer, size, format, ...) \ _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't // complain about _snprintf. # define GTEST_SNPRINTF_ _snprintf #else # define GTEST_SNPRINTF_ snprintf #endif // The maximum number a BiggestInt can represent. This definition // works no matter BiggestInt is represented in one's complement or // two's complement. // // We cannot rely on numeric_limits in STL, as __int64 and long long // are not part of standard C++ and numeric_limits doesn't need to be // defined for them. const BiggestInt kMaxBiggestInt = ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that // size. e.g. // // TypeWithSize<4>::UInt // // is typedef-ed to be unsigned int (unsigned integer made up of 4 // bytes). // // Such functionality should belong to STL, but I cannot find it // there. // // Google Test uses this class in the implementation of floating-point // comparison. // // For now it only handles UInt (unsigned int) as that's all Google Test // needs. Other types can be easily added in the future if need // arises. template class TypeWithSize { public: // This prevents the user from using TypeWithSize with incorrect // values of N. typedef void UInt; }; // The specialization for size 4. template <> class TypeWithSize<4> { public: // unsigned int has size 4 in both gcc and MSVC. // // As base/basictypes.h doesn't compile on Windows, we cannot use // uint32, uint64, and etc here. typedef int Int; typedef unsigned int UInt; }; // The specialization for size 8. template <> class TypeWithSize<8> { public: #if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; #else typedef long long Int; // NOLINT typedef unsigned long long UInt; // NOLINT #endif // GTEST_OS_WINDOWS }; // Integer types of known sizes. typedef TypeWithSize<4>::Int Int32; typedef TypeWithSize<4>::UInt UInt32; typedef TypeWithSize<8>::Int Int64; typedef TypeWithSize<8>::UInt UInt64; typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Utilities for command line flags and environment variables. // Macro for referencing flags. #define GTEST_FLAG(name) FLAGS_gtest_##name // Macros for declaring flags. #define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) // Thread annotations #define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) #define GTEST_LOCK_EXCLUDED_(locks) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns // false. // TODO(chandlerc): Find a better way to refactor flag and environment parsing // out of both gtest-port.cc and gtest.cc to avoid exporting this utility // function. bool ParseInt32(const Message& src_text, const char* str, Int32* value); // Parses a bool/Int32/string from the environment variable // corresponding to the given Google Test flag. bool BoolFromGTestEnv(const char* flag, bool default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-string.h000644 000766 000024 00000015470 12650222322 024222 0ustar00iojsstaff000000 000000 // Copyright 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) // // The Google C++ Testing Framework (Google Test) // // This header file declares the String class and functions used internally by // Google Test. They are subject to change without notice. They should not used // by code external to Google Test. // // This header file is #included by . // It should not be #included by other files. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. # include #endif #include #include #include "gtest/internal/gtest-port.h" namespace testing { namespace internal { // String - an abstract class holding static string utilities. class GTEST_API_ String { public: // Static utility methods // Clones a 0-terminated C string, allocating memory using new. The // caller is responsible for deleting the return value using // delete[]. Returns the cloned string, or NULL if the input is // NULL. // // This is different from strdup() in string.h, which allocates // memory using malloc(). static const char* CloneCString(const char* c_str); #if GTEST_OS_WINDOWS_MOBILE // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be // able to pass strings to Win32 APIs on CE we need to convert them // to 'Unicode', UTF-16. // Creates a UTF-16 wide string from the given ANSI string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. // // The wide string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static LPCWSTR AnsiToUtf16(const char* c_str); // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. // // The returned string is created using the ANSI codepage (CP_ACP) to // match the behaviour of the ANSI versions of Win32 calls and the // C runtime. static const char* Utf16ToAnsi(LPCWSTR utf16_str); #endif // Compares two C strings. Returns true iff they have the same content. // // Unlike strcmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CStringEquals(const char* lhs, const char* rhs); // Converts a wide C string to a String using the UTF-8 encoding. // NULL will be converted to "(null)". If an error occurred during // the conversion, "(failed to convert from wide string)" is // returned. static std::string ShowWideCString(const wchar_t* wide_c_str); // Compares two wide C strings. Returns true iff they have the same // content. // // Unlike wcscmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Compares two C strings, ignoring case. Returns true iff they // have the same content. // // Unlike strcasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL C string, // including the empty string. static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs); // Compares two wide C strings, ignoring case. Returns true iff they // have the same content. // // Unlike wcscasecmp(), this function can handle NULL argument(s). // A NULL C string is considered different to any non-NULL wide C string, // including the empty string. // NB: The implementations on different platforms slightly differ. // On windows, this method uses _wcsicmp which compares according to LC_CTYPE // environment variable. On GNU platform this method uses wcscasecmp // which compares according to LC_CTYPE category of the current locale. // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the // current locale. static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); // Returns true iff the given string ends with the given suffix, ignoring // case. Any string is considered to end with an empty suffix. static bool EndsWithCaseInsensitive( const std::string& str, const std::string& suffix); // Formats an int value as "%02d". static std::string FormatIntWidth2(int value); // "%02d" for width == 2 // Formats an int value as "%X". static std::string FormatHexInt(int value); // Formats a byte as "%02X". static std::string FormatByte(unsigned char value); private: String(); // Not meant to be instantiated. }; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". GTEST_API_ std::string StringStreamToString(::std::stringstream* stream); } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-tuple.h000644 000766 000024 00000067711 12650222322 024052 0ustar00iojsstaff000000 000000 // This file was GENERATED by command: // pump.py gtest-tuple.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2009 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Implements a subset of TR1 tuple needed by Google Test and Google Mock. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ #include // For ::std::pair. // The compiler used in Symbian has a bug that prevents us from declaring the // tuple template as a friend (it complains that tuple is redefined). This // hack bypasses the bug by declaring the members that should otherwise be // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) # define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else # define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif // Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict // with our own definitions. Therefore using our own tuple does not work on // those compilers. #if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */ # error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \ GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers." #endif // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> #define GTEST_1_TUPLE_(T) tuple #define GTEST_2_TUPLE_(T) tuple #define GTEST_3_TUPLE_(T) tuple #define GTEST_4_TUPLE_(T) tuple #define GTEST_5_TUPLE_(T) tuple #define GTEST_6_TUPLE_(T) tuple #define GTEST_7_TUPLE_(T) tuple #define GTEST_8_TUPLE_(T) tuple #define GTEST_9_TUPLE_(T) tuple #define GTEST_10_TUPLE_(T) tuple // GTEST_n_TYPENAMES_(T) declares a list of n typenames. #define GTEST_0_TYPENAMES_(T) #define GTEST_1_TYPENAMES_(T) typename T##0 #define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 #define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 #define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3 #define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4 #define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5 #define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6 #define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 #define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8 #define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ typename T##3, typename T##4, typename T##5, typename T##6, \ typename T##7, typename T##8, typename T##9 // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. namespace std { namespace tr1 { template class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. namespace gtest_internal { // ByRef::type is T if T is a reference; otherwise it's const T&. template struct ByRef { typedef const T& type; }; // NOLINT template struct ByRef { typedef T& type; }; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template struct AddRef { typedef T& type; }; // NOLINT template struct AddRef { typedef T& type; }; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). template class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. template struct TupleElement; template struct TupleElement { typedef T0 type; }; template struct TupleElement { typedef T1 type; }; template struct TupleElement { typedef T2 type; }; template struct TupleElement { typedef T3 type; }; template struct TupleElement { typedef T4 type; }; template struct TupleElement { typedef T5 type; }; template struct TupleElement { typedef T6 type; }; template struct TupleElement { typedef T7 type; }; template struct TupleElement { typedef T8 type; }; template struct TupleElement { typedef T9 type; }; } // namespace gtest_internal template <> class tuple<> { public: tuple() {} tuple(const tuple& /* t */) {} tuple& operator=(const tuple& /* t */) { return *this; } }; template class GTEST_1_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_() {} explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} tuple(const tuple& t) : f0_(t.f0_) {} template tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_1_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { f0_ = t.f0_; return *this; } T0 f0_; }; template class GTEST_2_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), f1_(f1) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} template tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_2_TUPLE_(U)& t) { return CopyFrom(t); } template tuple& operator=(const ::std::pair& p) { f0_ = p.first; f1_ = p.second; return *this; } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; return *this; } T0 f0_; T1 f1_; }; template class GTEST_3_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} template tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_3_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; return *this; } T0 f0_; T1 f1_; T2 f2_; }; template class GTEST_4_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), f3_(f3) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} template tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_4_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; }; template class GTEST_5_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} template tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_5_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; }; template class GTEST_6_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} template tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_6_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; }; template class GTEST_7_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} template tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_7_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; }; template class GTEST_8_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} template tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_8_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; }; template class GTEST_9_TUPLE_(T) { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} template tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_9_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; }; template class tuple { public: template friend class gtest_internal::Get; tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), f9_() {} explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} template tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} tuple& operator=(const tuple& t) { return CopyFrom(t); } template tuple& operator=(const GTEST_10_TUPLE_(U)& t) { return CopyFrom(t); } GTEST_DECLARE_TUPLE_AS_FRIEND_ template tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { f0_ = t.f0_; f1_ = t.f1_; f2_ = t.f2_; f3_ = t.f3_; f4_ = t.f4_; f5_ = t.f5_; f6_ = t.f6_; f7_ = t.f7_; f8_ = t.f8_; f9_ = t.f9_; return *this; } T0 f0_; T1 f1_; T2 f2_; T3 f3_; T4 f4_; T5 f5_; T6 f6_; T7 f7_; T8 f8_; T9 f9_; }; // 6.1.3.2 Tuple creation functions. // Known limitations: we don't support passing an // std::tr1::reference_wrapper to make_tuple(). And we don't // implement tie(). inline tuple<> make_tuple() { return tuple<>(); } template inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { return GTEST_1_TUPLE_(T)(f0); } template inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { return GTEST_2_TUPLE_(T)(f0, f1); } template inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { return GTEST_3_TUPLE_(T)(f0, f1, f2); } template inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3) { return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); } template inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4) { return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); } template inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5) { return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); } template inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6) { return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); } template inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); } template inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8) { return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); } template inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, const T8& f8, const T9& f9) { return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); } // 6.1.3.3 Tuple helper classes. template struct tuple_size; template struct tuple_size { static const int value = 0; }; template struct tuple_size { static const int value = 1; }; template struct tuple_size { static const int value = 2; }; template struct tuple_size { static const int value = 3; }; template struct tuple_size { static const int value = 4; }; template struct tuple_size { static const int value = 5; }; template struct tuple_size { static const int value = 6; }; template struct tuple_size { static const int value = 7; }; template struct tuple_size { static const int value = 8; }; template struct tuple_size { static const int value = 9; }; template struct tuple_size { static const int value = 10; }; template struct tuple_element { typedef typename gtest_internal::TupleElement< k < (tuple_size::value), k, Tuple>::type type; }; #define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. namespace gtest_internal { template <> class Get<0> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) Field(Tuple& t) { return t.f0_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) ConstField(const Tuple& t) { return t.f0_; } }; template <> class Get<1> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) Field(Tuple& t) { return t.f1_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) ConstField(const Tuple& t) { return t.f1_; } }; template <> class Get<2> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) Field(Tuple& t) { return t.f2_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) ConstField(const Tuple& t) { return t.f2_; } }; template <> class Get<3> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) Field(Tuple& t) { return t.f3_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) ConstField(const Tuple& t) { return t.f3_; } }; template <> class Get<4> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) Field(Tuple& t) { return t.f4_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) ConstField(const Tuple& t) { return t.f4_; } }; template <> class Get<5> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) Field(Tuple& t) { return t.f5_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) ConstField(const Tuple& t) { return t.f5_; } }; template <> class Get<6> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) Field(Tuple& t) { return t.f6_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) ConstField(const Tuple& t) { return t.f6_; } }; template <> class Get<7> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) Field(Tuple& t) { return t.f7_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) ConstField(const Tuple& t) { return t.f7_; } }; template <> class Get<8> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) Field(Tuple& t) { return t.f8_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) ConstField(const Tuple& t) { return t.f8_; } }; template <> class Get<9> { public: template static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) Field(Tuple& t) { return t.f9_; } // NOLINT template static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) ConstField(const Tuple& t) { return t.f9_; } }; } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::Field(t); } template GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) get(const GTEST_10_TUPLE_(T)& t) { return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. namespace gtest_internal { // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if // k1 != k2. template struct SameSizeTuplePrefixComparator; template <> struct SameSizeTuplePrefixComparator<0, 0> { template static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { return true; } }; template struct SameSizeTuplePrefixComparator { template static bool Eq(const Tuple1& t1, const Tuple2& t2) { return SameSizeTuplePrefixComparator::Eq(t1, t2) && ::std::tr1::get(t1) == ::std::tr1::get(t2); } }; } // namespace gtest_internal template inline bool operator==(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return gtest_internal::SameSizeTuplePrefixComparator< tuple_size::value, tuple_size::value>::Eq(t, u); } template inline bool operator!=(const GTEST_10_TUPLE_(T)& t, const GTEST_10_TUPLE_(U)& u) { return !(t == u); } // 6.1.4 Pairs. // Unimplemented. } // namespace tr1 } // namespace std #undef GTEST_0_TUPLE_ #undef GTEST_1_TUPLE_ #undef GTEST_2_TUPLE_ #undef GTEST_3_TUPLE_ #undef GTEST_4_TUPLE_ #undef GTEST_5_TUPLE_ #undef GTEST_6_TUPLE_ #undef GTEST_7_TUPLE_ #undef GTEST_8_TUPLE_ #undef GTEST_9_TUPLE_ #undef GTEST_10_TUPLE_ #undef GTEST_0_TYPENAMES_ #undef GTEST_1_TYPENAMES_ #undef GTEST_2_TYPENAMES_ #undef GTEST_3_TYPENAMES_ #undef GTEST_4_TYPENAMES_ #undef GTEST_5_TYPENAMES_ #undef GTEST_6_TYPENAMES_ #undef GTEST_7_TYPENAMES_ #undef GTEST_8_TYPENAMES_ #undef GTEST_9_TYPENAMES_ #undef GTEST_10_TYPENAMES_ #undef GTEST_DECLARE_TUPLE_AS_FRIEND_ #undef GTEST_BY_REF_ #undef GTEST_ADD_REF_ #undef GTEST_TUPLE_ELEMENT_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ node-v4.2.6/deps/gtest/include/gtest/internal/gtest-type-util.h000644 000766 000024 00000552502 12650222322 024652 0ustar00iojsstaff000000 000000 // This file was GENERATED by command: // pump.py gtest-type-util.h.pump // DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: wan@google.com (Zhanyong Wan) // Type utilities needed for implementing typed and type-parameterized // tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! // // Currently we support at most 50 types in a list, and at most 50 // type-parameterized tests in one type-parameterized test case. // Please contact googletestframework@googlegroups.com if you need // more. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). # if GTEST_HAS_CXXABI_H_ # include # elif defined(__HP_aCC) # include # endif // GTEST_HASH_CXXABI_H_ namespace testing { namespace internal { // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template std::string GetTypeName() { # if GTEST_HAS_RTTI const char* const name = typeid(T).name(); # if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) int status = 0; // gcc's implementation of typeid(T).name() mangles the type name, // so we have to demangle it. # if GTEST_HAS_CXXABI_H_ using abi::__cxa_demangle; # endif // GTEST_HAS_CXXABI_H_ char* const readable_name = __cxa_demangle(name, 0, 0, &status); const std::string name_str(status == 0 ? readable_name : name); free(readable_name); return name_str; # else return name; # endif // GTEST_HAS_CXXABI_H_ || __HP_aCC # else return ""; # endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. template struct AssertTypeEq; template struct AssertTypeEq { typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. struct None {}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN // represents a type list with N types (T1, T2, ..., and TN) in it. // Except for Types0, every struct in the family has two member types: // Head for the first type in the list, and Tail for the rest of the // list. // The empty type list. struct Types0 {}; // Type lists of length 1, 2, 3, and so on. template struct Types1 { typedef T1 Head; typedef Types0 Tail; }; template struct Types2 { typedef T1 Head; typedef Types1 Tail; }; template struct Types3 { typedef T1 Head; typedef Types2 Tail; }; template struct Types4 { typedef T1 Head; typedef Types3 Tail; }; template struct Types5 { typedef T1 Head; typedef Types4 Tail; }; template struct Types6 { typedef T1 Head; typedef Types5 Tail; }; template struct Types7 { typedef T1 Head; typedef Types6 Tail; }; template struct Types8 { typedef T1 Head; typedef Types7 Tail; }; template struct Types9 { typedef T1 Head; typedef Types8 Tail; }; template struct Types10 { typedef T1 Head; typedef Types9 Tail; }; template struct Types11 { typedef T1 Head; typedef Types10 Tail; }; template struct Types12 { typedef T1 Head; typedef Types11 Tail; }; template struct Types13 { typedef T1 Head; typedef Types12 Tail; }; template struct Types14 { typedef T1 Head; typedef Types13 Tail; }; template struct Types15 { typedef T1 Head; typedef Types14 Tail; }; template struct Types16 { typedef T1 Head; typedef Types15 Tail; }; template struct Types17 { typedef T1 Head; typedef Types16 Tail; }; template struct Types18 { typedef T1 Head; typedef Types17 Tail; }; template struct Types19 { typedef T1 Head; typedef Types18 Tail; }; template struct Types20 { typedef T1 Head; typedef Types19 Tail; }; template struct Types21 { typedef T1 Head; typedef Types20 Tail; }; template struct Types22 { typedef T1 Head; typedef Types21 Tail; }; template struct Types23 { typedef T1 Head; typedef Types22 Tail; }; template struct Types24 { typedef T1 Head; typedef Types23 Tail; }; template struct Types25 { typedef T1 Head; typedef Types24 Tail; }; template struct Types26 { typedef T1 Head; typedef Types25 Tail; }; template struct Types27 { typedef T1 Head; typedef Types26 Tail; }; template struct Types28 { typedef T1 Head; typedef Types27 Tail; }; template struct Types29 { typedef T1 Head; typedef Types28 Tail; }; template struct Types30 { typedef T1 Head; typedef Types29 Tail; }; template struct Types31 { typedef T1 Head; typedef Types30 Tail; }; template struct Types32 { typedef T1 Head; typedef Types31 Tail; }; template struct Types33 { typedef T1 Head; typedef Types32 Tail; }; template struct Types34 { typedef T1 Head; typedef Types33 Tail; }; template struct Types35 { typedef T1 Head; typedef Types34 Tail; }; template struct Types36 { typedef T1 Head; typedef Types35 Tail; }; template struct Types37 { typedef T1 Head; typedef Types36 Tail; }; template struct Types38 { typedef T1 Head; typedef Types37 Tail; }; template struct Types39 { typedef T1 Head; typedef Types38 Tail; }; template struct Types40 { typedef T1 Head; typedef Types39 Tail; }; template struct Types41 { typedef T1 Head; typedef Types40 Tail; }; template struct Types42 { typedef T1 Head; typedef Types41 Tail; }; template struct Types43 { typedef T1 Head; typedef Types42 Tail; }; template struct Types44 { typedef T1 Head; typedef Types43 Tail; }; template struct Types45 { typedef T1 Head; typedef Types44 Tail; }; template struct Types46 { typedef T1 Head; typedef Types45 Tail; }; template struct Types47 { typedef T1 Head; typedef Types46 Tail; }; template struct Types48 { typedef T1 Head; typedef Types47 Tail; }; template struct Types49 { typedef T1 Head; typedef Types48 Tail; }; template struct Types50 { typedef T1 Head; typedef Types49 Tail; }; } // namespace internal // We don't want to require the users to write TypesN<...> directly, // as that would require them to count the length. Types<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Types // will appear as Types in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Types, and Google Test will translate // that to TypesN internally to make error messages // readable. The translation is done by the 'type' member of the // Types template. template struct Types { typedef internal::Types50 type; }; template <> struct Types { typedef internal::Types0 type; }; template struct Types { typedef internal::Types1 type; }; template struct Types { typedef internal::Types2 type; }; template struct Types { typedef internal::Types3 type; }; template struct Types { typedef internal::Types4 type; }; template struct Types { typedef internal::Types5 type; }; template struct Types { typedef internal::Types6 type; }; template struct Types { typedef internal::Types7 type; }; template struct Types { typedef internal::Types8 type; }; template struct Types { typedef internal::Types9 type; }; template struct Types { typedef internal::Types10 type; }; template struct Types { typedef internal::Types11 type; }; template struct Types { typedef internal::Types12 type; }; template struct Types { typedef internal::Types13 type; }; template struct Types { typedef internal::Types14 type; }; template struct Types { typedef internal::Types15 type; }; template struct Types { typedef internal::Types16 type; }; template struct Types { typedef internal::Types17 type; }; template struct Types { typedef internal::Types18 type; }; template struct Types { typedef internal::Types19 type; }; template struct Types { typedef internal::Types20 type; }; template struct Types { typedef internal::Types21 type; }; template struct Types { typedef internal::Types22 type; }; template struct Types { typedef internal::Types23 type; }; template struct Types { typedef internal::Types24 type; }; template struct Types { typedef internal::Types25 type; }; template struct Types { typedef internal::Types26 type; }; template struct Types { typedef internal::Types27 type; }; template struct Types { typedef internal::Types28 type; }; template struct Types { typedef internal::Types29 type; }; template struct Types { typedef internal::Types30 type; }; template struct Types { typedef internal::Types31 type; }; template struct Types { typedef internal::Types32 type; }; template struct Types { typedef internal::Types33 type; }; template struct Types { typedef internal::Types34 type; }; template struct Types { typedef internal::Types35 type; }; template struct Types { typedef internal::Types36 type; }; template struct Types { typedef internal::Types37 type; }; template struct Types { typedef internal::Types38 type; }; template struct Types { typedef internal::Types39 type; }; template struct Types { typedef internal::Types40 type; }; template struct Types { typedef internal::Types41 type; }; template struct Types { typedef internal::Types42 type; }; template struct Types { typedef internal::Types43 type; }; template struct Types { typedef internal::Types44 type; }; template struct Types { typedef internal::Types45 type; }; template struct Types { typedef internal::Types46 type; }; template struct Types { typedef internal::Types47 type; }; template struct Types { typedef internal::Types48 type; }; template struct Types { typedef internal::Types49 type; }; namespace internal { # define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type // parameter, as a type. TemplateSel::Bind::type is defined // as the type Tmpl. This allows us to actually instantiate the // template "selected" by TemplateSel. // // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template struct TemplateSel { template struct Bind { typedef Tmpl type; }; }; # define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template struct NoneT {}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN represents a list of N templates (T1, T2, ..., and TN). Except // for Templates0, every struct in the family has two member types: // Head for the selector of the first template in the list, and Tail // for the rest of the list. // The empty template list. struct Templates0 {}; // Template lists of length 1, 2, 3, and so on. template struct Templates1 { typedef TemplateSel Head; typedef Templates0 Tail; }; template struct Templates2 { typedef TemplateSel Head; typedef Templates1 Tail; }; template struct Templates3 { typedef TemplateSel Head; typedef Templates2 Tail; }; template struct Templates4 { typedef TemplateSel Head; typedef Templates3 Tail; }; template struct Templates5 { typedef TemplateSel Head; typedef Templates4 Tail; }; template struct Templates6 { typedef TemplateSel Head; typedef Templates5 Tail; }; template struct Templates7 { typedef TemplateSel Head; typedef Templates6 Tail; }; template struct Templates8 { typedef TemplateSel Head; typedef Templates7 Tail; }; template struct Templates9 { typedef TemplateSel Head; typedef Templates8 Tail; }; template struct Templates10 { typedef TemplateSel Head; typedef Templates9 Tail; }; template struct Templates11 { typedef TemplateSel Head; typedef Templates10 Tail; }; template struct Templates12 { typedef TemplateSel Head; typedef Templates11 Tail; }; template struct Templates13 { typedef TemplateSel Head; typedef Templates12 Tail; }; template struct Templates14 { typedef TemplateSel Head; typedef Templates13 Tail; }; template struct Templates15 { typedef TemplateSel Head; typedef Templates14 Tail; }; template struct Templates16 { typedef TemplateSel Head; typedef Templates15 Tail; }; template struct Templates17 { typedef TemplateSel Head; typedef Templates16 Tail; }; template struct Templates18 { typedef TemplateSel Head; typedef Templates17 Tail; }; template struct Templates19 { typedef TemplateSel Head; typedef Templates18 Tail; }; template struct Templates20 { typedef TemplateSel Head; typedef Templates19 Tail; }; template struct Templates21 { typedef TemplateSel Head; typedef Templates20 Tail; }; template struct Templates22 { typedef TemplateSel Head; typedef Templates21 Tail; }; template struct Templates23 { typedef TemplateSel Head; typedef Templates22 Tail; }; template struct Templates24 { typedef TemplateSel Head; typedef Templates23 Tail; }; template struct Templates25 { typedef TemplateSel Head; typedef Templates24 Tail; }; template struct Templates26 { typedef TemplateSel Head; typedef Templates25 Tail; }; template struct Templates27 { typedef TemplateSel Head; typedef Templates26 Tail; }; template struct Templates28 { typedef TemplateSel Head; typedef Templates27 Tail; }; template struct Templates29 { typedef TemplateSel Head; typedef Templates28 Tail; }; template struct Templates30 { typedef TemplateSel Head; typedef Templates29 Tail; }; template struct Templates31 { typedef TemplateSel Head; typedef Templates30 Tail; }; template struct Templates32 { typedef TemplateSel Head; typedef Templates31 Tail; }; template struct Templates33 { typedef TemplateSel Head; typedef Templates32 Tail; }; template struct Templates34 { typedef TemplateSel Head; typedef Templates33 Tail; }; template struct Templates35 { typedef TemplateSel Head; typedef Templates34 Tail; }; template struct Templates36 { typedef TemplateSel Head; typedef Templates35 Tail; }; template struct Templates37 { typedef TemplateSel Head; typedef Templates36 Tail; }; template struct Templates38 { typedef TemplateSel Head; typedef Templates37 Tail; }; template struct Templates39 { typedef TemplateSel Head; typedef Templates38 Tail; }; template struct Templates40 { typedef TemplateSel Head; typedef Templates39 Tail; }; template struct Templates41 { typedef TemplateSel Head; typedef Templates40 Tail; }; template struct Templates42 { typedef TemplateSel Head; typedef Templates41 Tail; }; template struct Templates43 { typedef TemplateSel Head; typedef Templates42 Tail; }; template struct Templates44 { typedef TemplateSel Head; typedef Templates43 Tail; }; template struct Templates45 { typedef TemplateSel Head; typedef Templates44 Tail; }; template struct Templates46 { typedef TemplateSel Head; typedef Templates45 Tail; }; template struct Templates47 { typedef TemplateSel Head; typedef Templates46 Tail; }; template struct Templates48 { typedef TemplateSel Head; typedef Templates47 Tail; }; template struct Templates49 { typedef TemplateSel Head; typedef Templates48 Tail; }; template struct Templates50 { typedef TemplateSel Head; typedef Templates49 Tail; }; // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a // compiler error, as gcc insists on printing out each template // argument, even if it has the default value (this means Templates // will appear as Templates in the compiler // errors). // // Our solution is to combine the best part of the two approaches: a // user would write Templates, and Google Test will translate // that to TemplatesN internally to make error messages // readable. The translation is done by the 'type' member of the // Templates template. template struct Templates { typedef Templates50 type; }; template <> struct Templates { typedef Templates0 type; }; template struct Templates { typedef Templates1 type; }; template struct Templates { typedef Templates2 type; }; template struct Templates { typedef Templates3 type; }; template struct Templates { typedef Templates4 type; }; template struct Templates { typedef Templates5 type; }; template struct Templates { typedef Templates6 type; }; template struct Templates { typedef Templates7 type; }; template struct Templates { typedef Templates8 type; }; template struct Templates { typedef Templates9 type; }; template struct Templates { typedef Templates10 type; }; template struct Templates { typedef Templates11 type; }; template struct Templates { typedef Templates12 type; }; template struct Templates { typedef Templates13 type; }; template struct Templates { typedef Templates14 type; }; template struct Templates { typedef Templates15 type; }; template struct Templates { typedef Templates16 type; }; template struct Templates { typedef Templates17 type; }; template struct Templates { typedef Templates18 type; }; template struct Templates { typedef Templates19 type; }; template struct Templates { typedef Templates20 type; }; template struct Templates { typedef Templates21 type; }; template struct Templates { typedef Templates22 type; }; template struct Templates { typedef Templates23 type; }; template struct Templates { typedef Templates24 type; }; template struct Templates { typedef Templates25 type; }; template struct Templates { typedef Templates26 type; }; template struct Templates { typedef Templates27 type; }; template struct Templates { typedef Templates28 type; }; template struct Templates { typedef Templates29 type; }; template struct Templates { typedef Templates30 type; }; template struct Templates { typedef Templates31 type; }; template struct Templates { typedef Templates32 type; }; template struct Templates { typedef Templates33 type; }; template struct Templates { typedef Templates34 type; }; template struct Templates { typedef Templates35 type; }; template struct Templates { typedef Templates36 type; }; template struct Templates { typedef Templates37 type; }; template struct Templates { typedef Templates38 type; }; template struct Templates { typedef Templates39 type; }; template struct Templates { typedef Templates40 type; }; template struct Templates { typedef Templates41 type; }; template struct Templates { typedef Templates42 type; }; template struct Templates { typedef Templates43 type; }; template struct Templates { typedef Templates44 type; }; template struct Templates { typedef Templates45 type; }; template struct Templates { typedef Templates46 type; }; template struct Templates { typedef Templates47 type; }; template struct Templates { typedef Templates48 type; }; template struct Templates { typedef Templates49 type; }; // The TypeList template makes it possible to use either a single type // or a Types<...> list in TYPED_TEST_CASE() and // INSTANTIATE_TYPED_TEST_CASE_P(). template struct TypeList { typedef Types1 type; }; template struct TypeList > { typedef typename Types::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P } // namespace internal } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ node-v4.2.6/deps/cares/.gitignore000644 000766 000024 00000000255 12650222322 016764 0ustar00iojsstaff000000 000000 /Debug/ /build/gyp /out/ /Release/ /cares.Makefile /cares.target.mk /*.opensdf /*.sdf /*.sln /*.suo /*.vcxproj /*.vcxproj.filters /*.vcxproj.user *.so *.[oa] .buildstamp node-v4.2.6/deps/cares/android-configure000755 000766 000024 00000001034 12650222322 020315 0ustar00iojsstaff000000 000000 #!/bin/bash export TOOLCHAIN=$PWD/android-toolchain mkdir -p $TOOLCHAIN $1/build/tools/make-standalone-toolchain.sh \ --toolchain=arm-linux-androideabi-4.7 \ --arch=arm \ --install-dir=$TOOLCHAIN \ --platform=android-9 export PATH=$TOOLCHAIN/bin:$PATH export AR=arm-linux-androideabi-ar export CC=arm-linux-androideabi-gcc export CXX=arm-linux-androideabi-g++ export LINK=arm-linux-androideabi-g++ export PLATFORM=android export OS=android if [ $2 -a $2 == 'gyp' ] then ./gyp_cares -DOS=android -Dtarget_arch=arm fi node-v4.2.6/deps/cares/build/000755 000766 000024 00000000000 12650222322 016071 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/build.mk000644 000766 000024 00000007621 12650222322 016430 0ustar00iojsstaff000000 000000 # 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. OS ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') OBJS= \ src/ares_cancel.o \ src/ares__close_sockets.o \ src/ares_create_query.o \ src/ares_data.o \ src/ares_destroy.o \ src/ares_expand_name.o \ src/ares_expand_string.o \ src/ares_fds.o \ src/ares_free_hostent.o \ src/ares_free_string.o \ src/ares_gethostbyaddr.o \ src/ares_gethostbyname.o \ src/ares__get_hostent.o \ src/ares_getnameinfo.o \ src/ares_getopt.o \ src/ares_getsock.o \ src/ares_init.o \ src/ares_library_init.o \ src/ares_llist.o \ src/ares_mkquery.o \ src/ares_nowarn.o \ src/ares_options.o \ src/ares_parse_aaaa_reply.o \ src/ares_parse_a_reply.o \ src/ares_parse_mx_reply.o \ src/ares_parse_naptr_reply.o \ src/ares_parse_ns_reply.o \ src/ares_parse_ptr_reply.o \ src/ares_parse_soa_reply.o \ src/ares_parse_srv_reply.o \ src/ares_parse_txt_reply.o \ src/ares_process.o \ src/ares_query.o \ src/ares__read_line.o \ src/ares_search.o \ src/ares_send.o \ src/ares_strcasecmp.o \ src/ares_strdup.o \ src/ares_strerror.o \ src/ares_timeout.o \ src/ares__timeval.o \ src/ares_version.o \ src/ares_writev.o \ src/bitncmp.o \ src/inet_net_pton.o \ src/inet_ntop.o \ CFLAGS += -I. -I$(SRCDIR)/include -DHAVE_CONFIG_H ARES_CONFIG_OS = $(OS) SOEXT = so # if on windows ifneq (,$(findstring mingw,$(OS))) ARES_CONFIG_OS = win32 OBJS += src/windows_port.o OBJS += src/ares_getenv.o OBJS += src/ares_platform.o LDFLAGS += -lws2_32.lib -liphlpapi.lib else # else a posix system CFLAGS += -g --std=gnu89 -pedantic CFLAGS += -Wall -Wextra -Wno-unused-parameter CFLAGS += -D_LARGEFILE_SOURCE CFLAGS += -D_FILE_OFFSET_BITS=64 endif ifneq (,$(findstring cygwin,$(OS))) ARES_CONFIG_OS = cygwin CFLAGS += -D_GNU_SOURCE endif ifeq (dragonflybsd,$(OS)) ARES_CONFIG_OS = freebsd endif ifeq (darwin,$(OS)) CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 LDFLAGS += -dynamiclib -install_name "@rpath/libcares.dylib" SOEXT = dylib endif ifeq (linux,$(OS)) CFLAGS += -D_GNU_SOURCE endif ifeq (android,$(OS)) CFLAGS += -D_GNU_SOURCE endif ifeq (sunos,$(OS)) LDFLAGS += -lsocket -lnsl CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 endif CFLAGS += -I$(SRCDIR)/config/$(ARES_CONFIG_OS) ifneq (,$(findstring libcares.$(SOEXT),$(MAKECMDGOALS))) CFLAGS += -DCARES_BUILDING_LIBRARY else CFLAGS += -DCARES_STATICLIB endif all: libcares.a src/.buildstamp: mkdir -p $(dir $@) touch $@ libcares.a: $(OBJS) $(AR) rcs $@ $^ libcares.$(SOEXT): override CFLAGS += -fPIC libcares.$(SOEXT): $(OBJS:%.o=%.pic.o) $(CC) -shared -o $@ $^ $(LDFLAGS) src/%.o src/%.pic.o: src/%.c include/ares.h include/ares_version.h \ include/nameser.h src/.buildstamp \ $(SRCDIR)/config/$(ARES_CONFIG_OS)/ares_config.h $(CC) $(CFLAGS) -c $< -o $@ .PHONY: clean clean: $(RM) -f libcares.a libcares.$(SOEXT) src/*.o src/.buildstamp node-v4.2.6/deps/cares/cares.gyp000644 000766 000024 00000011327 12650222322 016614 0ustar00iojsstaff000000 000000 { 'target_defaults': { 'conditions': [ ['OS!="win"', { 'defines': [ '_DARWIN_USE_64_BIT_INODE=1', '_LARGEFILE_SOURCE', '_FILE_OFFSET_BITS=64', '_GNU_SOURCE' ] }], [ 'OS=="aix"', { 'include_dirs': [ 'config/aix' ], 'sources': [ 'config/aix/ares_config.h' ], }], ['OS=="solaris"', { 'defines': [ '__EXTENSIONS__', '_XOPEN_SOURCE=500' ] }] ] }, 'targets': [ { 'target_name': 'cares', 'type': '<(library)', 'include_dirs': [ 'include', 'src' ], 'direct_dependent_settings': { 'include_dirs': [ 'include' ] }, 'sources': [ 'common.gypi', 'include/ares.h', 'include/ares_version.h', 'include/nameser.h', 'src/ares_cancel.c', 'src/ares__close_sockets.c', 'src/ares_create_query.c', 'src/ares_data.c', 'src/ares_data.h', 'src/ares_destroy.c', 'src/ares_dns.h', 'src/ares_expand_name.c', 'src/ares_expand_string.c', 'src/ares_fds.c', 'src/ares_free_hostent.c', 'src/ares_free_string.c', 'src/ares_getenv.h', 'src/ares_gethostbyaddr.c', 'src/ares_gethostbyname.c', 'src/ares__get_hostent.c', 'src/ares_getnameinfo.c', 'src/ares_getopt.c', 'src/ares_getopt.h', 'src/ares_getsock.c', 'src/ares_init.c', 'src/ares_ipv6.h', 'src/ares_library_init.c', 'src/ares_library_init.h', 'src/ares_llist.c', 'src/ares_llist.h', 'src/ares_mkquery.c', 'src/ares_nowarn.c', 'src/ares_nowarn.h', 'src/ares_options.c', 'src/ares_parse_aaaa_reply.c', 'src/ares_parse_a_reply.c', 'src/ares_parse_mx_reply.c', 'src/ares_parse_naptr_reply.c', 'src/ares_parse_ns_reply.c', 'src/ares_parse_ptr_reply.c', 'src/ares_parse_soa_reply.c', 'src/ares_parse_srv_reply.c', 'src/ares_parse_txt_reply.c', 'src/ares_platform.h', 'src/ares_private.h', 'src/ares_process.c', 'src/ares_query.c', 'src/ares__read_line.c', 'src/ares_rules.h', 'src/ares_search.c', 'src/ares_send.c', 'src/ares_setup.h', 'src/ares_strcasecmp.c', 'src/ares_strcasecmp.h', 'src/ares_strdup.c', 'src/ares_strdup.h', 'src/ares_strerror.c', 'src/ares_timeout.c', 'src/ares__timeval.c', 'src/ares_version.c', 'src/ares_writev.c', 'src/ares_writev.h', 'src/bitncmp.c', 'src/bitncmp.h', 'src/inet_net_pton.c', 'src/inet_ntop.c', 'src/ares_inet_net_pton.h', 'src/setup_once.h', ], 'conditions': [ [ 'library=="static_library"', { 'defines': [ 'CARES_STATICLIB' ] }, { 'defines': [ 'CARES_BUILDING_LIBRARY' ] }], [ 'OS=="win"', { 'include_dirs': [ 'config/win32' ], 'sources': [ 'src/config-win32.h', 'src/windows_port.c', 'src/ares_getenv.c', 'src/ares_iphlpapi.h', 'src/ares_platform.c' ], 'libraries': [ '-lws2_32.lib', '-liphlpapi.lib' ], }, { # Not Windows i.e. POSIX 'cflags': [ '-g', '-pedantic', '-Wall', '-Wextra', '-Wno-unused-parameter' ], 'defines': [ 'HAVE_CONFIG_H' ], }], [ 'OS not in "win android"', { 'cflags': [ '--std=gnu89' ], }], [ 'OS=="linux"', { 'include_dirs': [ 'config/linux' ], 'sources': [ 'config/linux/ares_config.h' ] }], [ 'OS=="mac"', { 'include_dirs': [ 'config/darwin' ], 'sources': [ 'config/darwin/ares_config.h' ] }], [ 'OS=="freebsd" or OS=="dragonflybsd"', { 'include_dirs': [ 'config/freebsd' ], 'sources': [ 'config/freebsd/ares_config.h' ] }], [ 'OS=="openbsd"', { 'include_dirs': [ 'config/openbsd' ], 'sources': [ 'config/openbsd/ares_config.h' ] }], [ 'OS=="android"', { 'include_dirs': [ 'config/android' ], 'sources': [ 'config/android/ares_config.h' ], }], [ 'OS=="solaris"', { 'include_dirs': [ 'config/sunos' ], 'sources': [ 'config/sunos/ares_config.h' ], 'direct_dependent_settings': { 'libraries': [ '-lsocket', '-lnsl' ] } }] ] } ] } node-v4.2.6/deps/cares/common.gypi000644 000766 000024 00000012715 12650222322 017162 0ustar00iojsstaff000000 000000 { 'variables': { 'visibility%': 'hidden', 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds 'component%': 'static_library', 'host_arch%': '', 'target_arch%': '' }, 'target_defaults': { 'default_configuration': 'Debug', 'configurations': { 'Debug': { 'defines': [ 'DEBUG', '_DEBUG' ], 'cflags': [ '-g', '-O0' ], 'msvs_settings': { 'VCCLCompilerTool': { 'target_conditions': [ ['library=="static_library"', { 'RuntimeLibrary': 1 # static debug }, { 'RuntimeLibrary': 3 # DLL debug }] ], 'Optimization': 0, # /Od, no optimization 'MinimalRebuild': 'false', 'OmitFramePointers': 'false', 'BasicRuntimeChecks': 3 # /RTC1 }, 'VCLinkerTool': { 'LinkIncremental': 2 # enable incremental linking } }, 'xcode_settings': { 'GCC_OPTIMIZATION_LEVEL': '0' } }, 'Release': { 'defines': [ 'NDEBUG' ], 'cflags': [ '-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections' ], 'msvs_settings': { 'VCCLCompilerTool': { 'target_conditions': [ ['library=="static_library"', { 'RuntimeLibrary': 0, # static release }, { 'RuntimeLibrary': 2, # debug release }], ], 'Optimization': 3, # /Ox, full optimization 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible 'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG 'OmitFramePointers': 'true', 'EnableFunctionLevelLinking': 'true', 'EnableIntrinsicFunctions': 'true' }, 'VCLibrarianTool': { 'AdditionalOptions': [ '/LTCG' # link time code generation ] }, 'VCLinkerTool': { 'LinkTimeCodeGeneration': 1, # link-time code generation 'OptimizeReferences': 2, # /OPT:REF 'EnableCOMDATFolding': 2, # /OPT:ICF 'LinkIncremental': 1 # disable incremental linking }, }, } }, 'msvs_settings': { 'VCCLCompilerTool': { 'StringPooling': 'true', # pool string literals 'DebugInformationFormat': 3, # Generate a PDB 'WarningLevel': 3, 'BufferSecurityCheck': 'true', 'ExceptionHandling': 1, # /EHsc 'SuppressStartupBanner': 'true', 'WarnAsError': 'false', 'AdditionalOptions': [ '/MP', # compile across multiple CPUs ], }, 'VCLinkerTool': { 'GenerateDebugInformation': 'true', 'RandomizedBaseAddress': 2, # enable ASLR 'DataExecutionPrevention': 2, # enable DEP 'AllowIsolation': 'true', 'SuppressStartupBanner': 'true', 'target_conditions': [ ['_type=="executable"', { 'SubSystem': 1, # console executable }], ], }, }, 'xcode_settings': { 'ALWAYS_SEARCH_USER_PATHS': 'NO', 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES', 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof 'PREBINDING': 'NO', # No -Wl,-prebind 'USE_HEADERMAP': 'NO', 'WARNING_CFLAGS': [ '-Wall', '-Wendif-labels', '-W', '-Wno-unused-parameter' ] }, 'conditions': [ ['OS == "win"', { 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin 'defines': [ 'WIN32', # we don't want VC++ warning us about how dangerous C functions are. '_CRT_SECURE_NO_DEPRECATE', # ... or that C implementations shouldn't use POSIX names '_CRT_NONSTDC_NO_DEPRECATE' ], }], [ 'OS in "linux freebsd openbsd solaris android aix"', { 'variables': { 'gcc_version%': ')' }, 'cflags': [ '-Wall' ], 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ], 'conditions': [ [ 'host_arch != target_arch and target_arch=="ia32"', { 'cflags': [ '-m32' ], 'ldflags': [ '-m32' ] }], [ 'OS=="linux"', { 'cflags': [ '-ansi' ] }], [ 'visibility=="hidden" and gcc_version >= "4.0.0"', { 'cflags': [ '-fvisibility=hidden' ] }], ] }] ], 'target_conditions': [ ['_type!="static_library"', { 'cflags': [ '-fPIC' ], 'xcode_settings': { 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic # (Equivalent to -fPIC) 'OTHER_LDFLAGS': [ '-Wl,-search_paths_first' ] } }] ] } } node-v4.2.6/deps/cares/config/000755 000766 000024 00000000000 12650222322 016237 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/gyp_cares000755 000766 000024 00000005775 12650222322 016712 0ustar00iojsstaff000000 000000 #!/usr/bin/env python import glob import platform import os import subprocess import sys CC = os.environ.get('CC', 'cc') script_dir = os.path.dirname(__file__) cares_root = os.path.normpath(script_dir) output_dir = os.path.join(os.path.abspath(cares_root), 'out') sys.path.insert(0, os.path.join(cares_root, 'build', 'gyp', 'pylib')) try: import gyp except ImportError: print('You need to install gyp in build/gyp first. See the README.') sys.exit(42) def host_arch(): machine = platform.machine() if machine == 'i386': return 'ia32' if machine == 'x86_64': return 'x64' if machine.startswith('arm'): return 'arm' return machine # Return as-is and hope for the best. def compiler_version(): proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE) is_clang = 'clang' in proc.communicate()[0].split('\n')[0] proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE) version = proc.communicate()[0].split('.') version = map(int, version[:2]) version = tuple(version) return (version, is_clang) def run_gyp(args): rc = gyp.main(args) if rc != 0: print 'Error running GYP' sys.exit(rc) if __name__ == '__main__': args = sys.argv[1:] # GYP bug. # On msvs it will crash if it gets an absolute path. # On Mac/make it will crash if it doesn't get an absolute path. if sys.platform == 'win32': args.append(os.path.join(cares_root, 'cares.gyp')) common_fn = os.path.join(cares_root, 'common.gypi') options_fn = os.path.join(cares_root, 'options.gypi') # we force vs 2010 over 2008 which would otherwise be the default for gyp if not os.environ.get('GYP_MSVS_VERSION'): os.environ['GYP_MSVS_VERSION'] = '2010' else: args.append(os.path.join(os.path.abspath(cares_root), 'cares.gyp')) common_fn = os.path.join(os.path.abspath(cares_root), 'common.gypi') options_fn = os.path.join(os.path.abspath(cares_root), 'options.gypi') if os.path.exists(common_fn): args.extend(['-I', common_fn]) if os.path.exists(options_fn): args.extend(['-I', options_fn]) args.append('--depth=' + cares_root) # There's a bug with windows which doesn't allow this feature. if sys.platform != 'win32': if '-f' not in args: args.extend('-f make'.split()) if 'ninja' not in args: args.extend(['-Goutput_dir=' + output_dir]) args.extend(['--generator-output', output_dir]) (major, minor), is_clang = compiler_version() args.append('-Dgcc_version=%d' % (10 * major + minor)) args.append('-Dclang=%d' % int(is_clang)) if not any(a.startswith('-Dhost_arch=') for a in args): args.append('-Dhost_arch=%s' % host_arch()) if not any(a.startswith('-Dtarget_arch=') for a in args): args.append('-Dtarget_arch=%s' % host_arch()) if not any(a.startswith('-Dlibrary=') for a in args): args.append('-Dlibrary=static_library') if not any(a.startswith('-Dcomponent=') for a in args): args.append('-Dcomponent=static_library') gyp_args = list(args) print gyp_args run_gyp(gyp_args) node-v4.2.6/deps/cares/include/000755 000766 000024 00000000000 12650222322 016415 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/Makefile000644 000766 000024 00000003354 12650222322 016437 0ustar00iojsstaff000000 000000 # 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. SRCDIR ?= $(CURDIR) ifeq (,$(builddir_name)) VPATH := $(SRCDIR) include $(SRCDIR)/build.mk else # Out of tree build. # Drop all built-in rules. .SUFFIXES: .PHONY: $(builddir_name) $(builddir_name): $(builddir_name)/.buildstamp $(MAKE) -C $@ -f $(CURDIR)/Makefile $(MAKECMDGOALS) \ SRCDIR=$(CURDIR) builddir_name= $(builddir_name)/.buildstamp: mkdir -p $(dir $@) touch $@ # Add no-op rules for Makefiles to stop make from trying to rebuild them. Makefile:: ; %.mk:: ; # Turn everything else into a no-op rule that depends on the build directory. %:: $(builddir_name) ; .PHONY: clean clean: $(RM) -fr $(builddir_name) endif node-v4.2.6/deps/cares/src/000755 000766 000024 00000000000 12650222322 015561 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/src/ares__close_sockets.c000644 000766 000024 00000003623 12650222322 021742 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_private.h" void ares__close_sockets(ares_channel channel, struct server_state *server) { struct send_request *sendreq; /* Free all pending output buffers. */ while (server->qhead) { /* Advance server->qhead; pull out query as we go. */ sendreq = server->qhead; server->qhead = sendreq->next; if (sendreq->data_storage != NULL) free(sendreq->data_storage); free(sendreq); } server->qtail = NULL; /* Reset any existing input buffer. */ if (server->tcp_buffer) free(server->tcp_buffer); server->tcp_buffer = NULL; server->tcp_lenbuf_pos = 0; /* Reset brokenness */ server->is_broken = 0; /* Close the TCP and UDP sockets. */ if (server->tcp_socket != ARES_SOCKET_BAD) { SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0); sclose(server->tcp_socket); server->tcp_socket = ARES_SOCKET_BAD; server->tcp_connection_generation = ++channel->tcp_connection_generation; } if (server->udp_socket != ARES_SOCKET_BAD) { SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0); sclose(server->udp_socket); server->udp_socket = ARES_SOCKET_BAD; } } node-v4.2.6/deps/cares/src/ares__get_hostent.c000644 000766 000024 00000015253 12650222322 021427 0ustar00iojsstaff000000 000000 /* Copyright 1998, 2011 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #include "ares.h" #include "ares_inet_net_pton.h" #include "ares_nowarn.h" #include "ares_private.h" int ares__get_hostent(FILE *fp, int family, struct hostent **host) { char *line = NULL, *p, *q, **alias; char *txtaddr, *txthost, *txtalias; int status; size_t addrlen, linesize, naliases; struct ares_addr addr; struct hostent *hostent = NULL; *host = NULL; /* Assume failure */ /* Validate family */ switch (family) { case AF_INET: case AF_INET6: case AF_UNSPEC: break; default: return ARES_EBADFAMILY; } while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { /* Trim line comment. */ p = line; while (*p && (*p != '#')) p++; *p = '\0'; /* Trim trailing whitespace. */ q = p - 1; while ((q >= line) && ISSPACE(*q)) q--; *++q = '\0'; /* Skip leading whitespace. */ p = line; while (*p && ISSPACE(*p)) p++; if (!*p) /* Ignore line if empty. */ continue; /* Pointer to start of IPv4 or IPv6 address part. */ txtaddr = p; /* Advance past address part. */ while (*p && !ISSPACE(*p)) p++; if (!*p) /* Ignore line if reached end of line. */ continue; /* Null terminate address part. */ *p = '\0'; /* Advance to host name */ p++; while (*p && ISSPACE(*p)) p++; if (!*p) /* Ignore line if reached end of line. */ continue; /* Pointer to start of host name. */ txthost = p; /* Advance past host name. */ while (*p && !ISSPACE(*p)) p++; /* Pointer to start of first alias. */ txtalias = NULL; if (*p) { q = p + 1; while (*q && ISSPACE(*q)) q++; if (*q) txtalias = q; } /* Null terminate host name. */ *p = '\0'; /* find out number of aliases. */ naliases = 0; if (txtalias) { p = txtalias; while (*p) { while (*p && !ISSPACE(*p)) p++; while (*p && ISSPACE(*p)) p++; naliases++; } } /* Convert address string to network address for the requested family. */ addrlen = 0; addr.family = AF_UNSPEC; addr.addrV4.s_addr = INADDR_NONE; if ((family == AF_INET) || (family == AF_UNSPEC)) { addr.addrV4.s_addr = inet_addr(txtaddr); if (addr.addrV4.s_addr != INADDR_NONE) { /* Actual network address family and length. */ addr.family = AF_INET; addrlen = sizeof(addr.addrV4); } } if ((family == AF_INET6) || ((family == AF_UNSPEC) && (!addrlen))) { if (ares_inet_pton(AF_INET6, txtaddr, &addr.addrV6) > 0) { /* Actual network address family and length. */ addr.family = AF_INET6; addrlen = sizeof(addr.addrV6); } } if (!addrlen) /* Ignore line if invalid address string for the requested family. */ continue; /* ** Actual address family possible values are AF_INET and AF_INET6 only. */ /* Allocate memory for the hostent structure. */ hostent = malloc(sizeof(struct hostent)); if (!hostent) break; /* Initialize fields for out of memory condition. */ hostent->h_aliases = NULL; hostent->h_addr_list = NULL; /* Copy official host name. */ hostent->h_name = strdup(txthost); if (!hostent->h_name) break; /* Copy network address. */ hostent->h_addr_list = malloc(2 * sizeof(char *)); if (!hostent->h_addr_list) break; hostent->h_addr_list[1] = NULL; hostent->h_addr_list[0] = malloc(addrlen); if (!hostent->h_addr_list[0]) break; if (addr.family == AF_INET) memcpy(hostent->h_addr_list[0], &addr.addrV4, sizeof(addr.addrV4)); else memcpy(hostent->h_addr_list[0], &addr.addrV6, sizeof(addr.addrV6)); /* Copy aliases. */ hostent->h_aliases = malloc((naliases + 1) * sizeof(char *)); if (!hostent->h_aliases) break; alias = hostent->h_aliases; while (naliases) *(alias + naliases--) = NULL; *alias = NULL; while (txtalias) { p = txtalias; while (*p && !ISSPACE(*p)) p++; q = p; while (*q && ISSPACE(*q)) q++; *p = '\0'; if ((*alias = strdup(txtalias)) == NULL) break; alias++; txtalias = *q ? q : NULL; } if (txtalias) /* Alias memory allocation failure. */ break; /* Copy actual network address family and length. */ hostent->h_addrtype = aresx_sitoss(addr.family); hostent->h_length = aresx_uztoss(addrlen); /* Free line buffer. */ free(line); /* Return hostent successfully */ *host = hostent; return ARES_SUCCESS; } /* If allocated, free line buffer. */ if (line) free(line); if (status == ARES_SUCCESS) { /* Memory allocation failure; clean up. */ if (hostent) { if (hostent->h_name) free((char *) hostent->h_name); if (hostent->h_aliases) { for (alias = hostent->h_aliases; *alias; alias++) free(*alias); free(hostent->h_aliases); } if (hostent->h_addr_list) { if (hostent->h_addr_list[0]) free(hostent->h_addr_list[0]); free(hostent->h_addr_list); } free(hostent); } return ARES_ENOMEM; } return status; } node-v4.2.6/deps/cares/src/ares__read_line.c000644 000766 000024 00000004152 12650222322 021022 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_nowarn.h" #include "ares_private.h" /* This is an internal function. Its contract is to read a line from * a file into a dynamically allocated buffer, zeroing the trailing * newline if there is one. The calling routine may call * ares__read_line multiple times with the same buf and bufsize * pointers; *buf will be reallocated and *bufsize adjusted as * appropriate. The initial value of *buf should be NULL. After the * calling routine is done reading lines, it should free *buf. */ int ares__read_line(FILE *fp, char **buf, size_t *bufsize) { char *newbuf; size_t offset = 0; size_t len; if (*buf == NULL) { *buf = malloc(128); if (!*buf) return ARES_ENOMEM; *bufsize = 128; } for (;;) { int bytestoread = aresx_uztosi(*bufsize - offset); if (!fgets(*buf + offset, bytestoread, fp)) return (offset != 0) ? 0 : (ferror(fp)) ? ARES_EFILE : ARES_EOF; len = offset + strlen(*buf + offset); if ((*buf)[len - 1] == '\n') { (*buf)[len - 1] = 0; break; } offset = len; if(len < *bufsize - 1) continue; /* Allocate more space. */ newbuf = realloc(*buf, *bufsize * 2); if (!newbuf) { free(*buf); return ARES_ENOMEM; } *buf = newbuf; *bufsize *= 2; } return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares__timeval.c000644 000766 000024 00000006025 12650222322 020542 0ustar00iojsstaff000000 000000 /* Copyright (C) 2008 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_private.h" #if defined(WIN32) && !defined(MSDOS) struct timeval ares__tvnow(void) { /* ** GetTickCount() is available on _all_ Windows versions from W95 up ** to nowadays. Returns milliseconds elapsed since last system boot, ** increases monotonically and wraps once 49.7 days have elapsed. */ struct timeval now; DWORD milliseconds = GetTickCount(); now.tv_sec = milliseconds / 1000; now.tv_usec = (milliseconds % 1000) * 1000; return now; } #elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) struct timeval ares__tvnow(void) { /* ** clock_gettime() is granted to be increased monotonically when the ** monotonic clock is queried. Time starting point is unspecified, it ** could be the system start-up time, the Epoch, or something else, ** in any case the time starting point does not change once that the ** system has started up. */ struct timeval now; struct timespec tsnow; if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { now.tv_sec = tsnow.tv_sec; now.tv_usec = tsnow.tv_nsec / 1000; } /* ** Even when the configure process has truly detected monotonic clock ** availability, it might happen that it is not actually available at ** run-time. When this occurs simply fallback to other time source. */ #ifdef HAVE_GETTIMEOFDAY else (void)gettimeofday(&now, NULL); #else else { now.tv_sec = (long)time(NULL); now.tv_usec = 0; } #endif return now; } #elif defined(HAVE_GETTIMEOFDAY) struct timeval ares__tvnow(void) { /* ** gettimeofday() is not granted to be increased monotonically, due to ** clock drifting and external source time synchronization it can jump ** forward or backward in time. */ struct timeval now; (void)gettimeofday(&now, NULL); return now; } #else struct timeval ares__tvnow(void) { /* ** time() returns the value of time in seconds since the Epoch. */ struct timeval now; now.tv_sec = (long)time(NULL); now.tv_usec = 0; return now; } #endif #if 0 /* Not used */ /* * Make sure that the first argument is the more recent time, as otherwise * we'll get a weird negative time-diff back... * * Returns: the time difference in number of milliseconds. */ long ares__tvdiff(struct timeval newer, struct timeval older) { return (newer.tv_sec-older.tv_sec)*1000+ (newer.tv_usec-older.tv_usec)/1000; } #endif node-v4.2.6/deps/cares/src/ares_cancel.c000644 000766 000024 00000004265 12650222322 020173 0ustar00iojsstaff000000 000000 /* Copyright (C) 2004 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include #include "ares.h" #include "ares_private.h" /* * ares_cancel() cancels all ongoing requests/resolves that might be going on * on the given channel. It does NOT kill the channel, use ares_destroy() for * that. */ void ares_cancel(ares_channel channel) { struct query *query; struct list_node list_head_copy; struct list_node* list_head; struct list_node* list_node; int i; if (!ares__is_list_empty(&(channel->all_queries))) { /* Swap list heads, so that only those queries which were present on entry * into this function are cancelled. New queries added by callbacks of * queries being cancelled will not be cancelled themselves. */ list_head = &(channel->all_queries); list_head_copy.prev = list_head->prev; list_head_copy.next = list_head->next; list_head_copy.prev->next = &list_head_copy; list_head_copy.next->prev = &list_head_copy; list_head->prev = list_head; list_head->next = list_head; for (list_node = list_head_copy.next; list_node != &list_head_copy; ) { query = list_node->data; list_node = list_node->next; /* since we're deleting the query */ query->callback(query->arg, ARES_ECANCELLED, 0, NULL, 0); ares__free_query(query); } } if (!(channel->flags & ARES_FLAG_STAYOPEN) && ares__is_list_empty(&(channel->all_queries))) { if (channel->servers) { for (i = 0; i < channel->nservers; i++) ares__close_sockets(channel, &channel->servers[i]); } } } node-v4.2.6/deps/cares/src/ares_create_query.c000644 000766 000024 00000015157 12650222322 021440 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_private.h" #ifndef T_OPT # define T_OPT 41 /* EDNS0 option (meta-RR) */ #endif /* Header format, from RFC 1035: * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ID | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * |QR| Opcode |AA|TC|RD|RA| Z | RCODE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QDCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ANCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | NSCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ARCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * AA, TC, RA, and RCODE are only set in responses. Brief description * of the remaining fields: * ID Identifier to match responses with queries * QR Query (0) or response (1) * Opcode For our purposes, always QUERY * RD Recursion desired * Z Reserved (zero) * QDCOUNT Number of queries * ANCOUNT Number of answers * NSCOUNT Number of name server records * ARCOUNT Number of additional records * * Question format, from RFC 1035: * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | | * / QNAME / * / / * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QTYPE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QCLASS | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * The query name is encoded as a series of labels, each represented * as a one-byte length (maximum 63) followed by the text of the * label. The list is terminated by a label of length zero (which can * be thought of as the root domain). */ int ares_create_query(const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen, int max_udp_size) { int len; unsigned char *q; const char *p; /* Set our results early, in case we bail out early with an error. */ *buflen = 0; *buf = NULL; /* Compute the length of the encoded name so we can check buflen. * Start counting at 1 for the zero-length label at the end. */ len = 1; for (p = name; *p; p++) { if (*p == '\\' && *(p + 1) != 0) p++; len++; } /* If there are n periods in the name, there are n + 1 labels, and * thus n + 1 length fields, unless the name is empty or ends with a * period. So add 1 unless name is empty or ends with a period. */ if (*name && *(p - 1) != '.') len++; /* Immediately reject names that are longer than the maximum of 255 * bytes that's specified in RFC 1035 ("To simplify implementations, * the total length of a domain name (i.e., label octets and label * length octets) is restricted to 255 octets or less."). We aren't * doing this just to be a stickler about RFCs. For names that are * too long, 'dnscache' closes its TCP connection to us immediately * (when using TCP) and ignores the request when using UDP, and * BIND's named returns ServFail (TCP or UDP). Sending a request * that we know will cause 'dnscache' to close the TCP connection is * painful, since that makes any other outstanding requests on that * connection fail. And sending a UDP request that we know * 'dnscache' will ignore is bad because resources will be tied up * until we time-out the request. */ if (len > MAXCDNAME) return ARES_EBADNAME; *buflen = len + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0); *buf = malloc(*buflen); if (!*buf) return ARES_ENOMEM; /* Set up the header. */ q = *buf; memset(q, 0, HFIXEDSZ); DNS_HEADER_SET_QID(q, id); DNS_HEADER_SET_OPCODE(q, QUERY); if (rd) { DNS_HEADER_SET_RD(q, 1); } else { DNS_HEADER_SET_RD(q, 0); } DNS_HEADER_SET_QDCOUNT(q, 1); if (max_udp_size) { DNS_HEADER_SET_ARCOUNT(q, 1); } /* A name of "." is a screw case for the loop below, so adjust it. */ if (strcmp(name, ".") == 0) name++; /* Start writing out the name after the header. */ q += HFIXEDSZ; while (*name) { if (*name == '.') return ARES_EBADNAME; /* Count the number of bytes in this label. */ len = 0; for (p = name; *p && *p != '.'; p++) { if (*p == '\\' && *(p + 1) != 0) p++; len++; } if (len > MAXLABEL) return ARES_EBADNAME; /* Encode the length and copy the data. */ *q++ = (unsigned char)len; for (p = name; *p && *p != '.'; p++) { if (*p == '\\' && *(p + 1) != 0) p++; *q++ = *p; } /* Go to the next label and repeat, unless we hit the end. */ if (!*p) break; name = p + 1; } /* Add the zero-length label at the end. */ *q++ = 0; /* Finish off the question with the type and class. */ DNS_QUESTION_SET_TYPE(q, type); DNS_QUESTION_SET_CLASS(q, dnsclass); if (max_udp_size) { q += QFIXEDSZ; memset(q, 0, EDNSFIXEDSZ); q++; DNS_RR_SET_TYPE(q, T_OPT); DNS_RR_SET_CLASS(q, max_udp_size); } return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_data.c000644 000766 000024 00000012760 12650222322 017656 0ustar00iojsstaff000000 000000 /* Copyright (C) 2009-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include #include "ares.h" #include "ares_data.h" #include "ares_private.h" /* ** ares_free_data() - c-ares external API function. ** ** This function must be used by the application to free data memory that ** has been internally allocated by some c-ares function and for which a ** pointer has already been returned to the calling application. The list ** of c-ares functions returning pointers that must be free'ed using this ** function is: ** ** ares_get_servers() ** ares_parse_srv_reply() ** ares_parse_txt_reply() */ void ares_free_data(void *dataptr) { struct ares_data *ptr; if (!dataptr) return; #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:1684) /* 1684: conversion from pointer to same-sized integral type */ #endif ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif if (ptr->mark != ARES_DATATYPE_MARK) return; switch (ptr->type) { case ARES_DATATYPE_MX_REPLY: if (ptr->data.mx_reply.next) ares_free_data(ptr->data.mx_reply.next); if (ptr->data.mx_reply.host) free(ptr->data.mx_reply.host); break; case ARES_DATATYPE_SRV_REPLY: if (ptr->data.srv_reply.next) ares_free_data(ptr->data.srv_reply.next); if (ptr->data.srv_reply.host) free(ptr->data.srv_reply.host); break; case ARES_DATATYPE_TXT_REPLY: if (ptr->data.txt_reply.next) ares_free_data(ptr->data.txt_reply.next); if (ptr->data.txt_reply.txt) free(ptr->data.txt_reply.txt); break; case ARES_DATATYPE_ADDR_NODE: if (ptr->data.addr_node.next) ares_free_data(ptr->data.addr_node.next); break; case ARES_DATATYPE_NAPTR_REPLY: if (ptr->data.naptr_reply.next) ares_free_data(ptr->data.naptr_reply.next); if (ptr->data.naptr_reply.flags) free(ptr->data.naptr_reply.flags); if (ptr->data.naptr_reply.service) free(ptr->data.naptr_reply.service); if (ptr->data.naptr_reply.regexp) free(ptr->data.naptr_reply.regexp); if (ptr->data.naptr_reply.replacement) free(ptr->data.naptr_reply.replacement); break; case ARES_DATATYPE_SOA_REPLY: if (ptr->data.soa_reply.nsname) free(ptr->data.soa_reply.nsname); if (ptr->data.soa_reply.hostmaster) free(ptr->data.soa_reply.hostmaster); break; default: return; } free(ptr); } /* ** ares_malloc_data() - c-ares internal helper function. ** ** This function allocates memory for a c-ares private ares_data struct ** for the specified ares_datatype, initializes c-ares private fields ** and zero initializes those which later might be used from the public ** API. It returns an interior pointer which can be passed by c-ares ** functions to the calling application, and that must be free'ed using ** c-ares external API function ares_free_data(). */ void *ares_malloc_data(ares_datatype type) { struct ares_data *ptr; ptr = malloc(sizeof(struct ares_data)); if (!ptr) return NULL; switch (type) { case ARES_DATATYPE_MX_REPLY: ptr->data.mx_reply.next = NULL; ptr->data.mx_reply.host = NULL; ptr->data.mx_reply.priority = 0; break; case ARES_DATATYPE_SRV_REPLY: ptr->data.srv_reply.next = NULL; ptr->data.srv_reply.host = NULL; ptr->data.srv_reply.priority = 0; ptr->data.srv_reply.weight = 0; ptr->data.srv_reply.port = 0; break; case ARES_DATATYPE_TXT_REPLY: ptr->data.txt_reply.next = NULL; ptr->data.txt_reply.txt = NULL; ptr->data.txt_reply.length = 0; break; case ARES_DATATYPE_ADDR_NODE: ptr->data.addr_node.next = NULL; ptr->data.addr_node.family = 0; memset(&ptr->data.addr_node.addrV6, 0, sizeof(ptr->data.addr_node.addrV6)); break; case ARES_DATATYPE_NAPTR_REPLY: ptr->data.naptr_reply.next = NULL; ptr->data.naptr_reply.flags = NULL; ptr->data.naptr_reply.service = NULL; ptr->data.naptr_reply.regexp = NULL; ptr->data.naptr_reply.replacement = NULL; ptr->data.naptr_reply.order = 0; ptr->data.naptr_reply.preference = 0; break; case ARES_DATATYPE_SOA_REPLY: ptr->data.soa_reply.nsname = NULL; ptr->data.soa_reply.hostmaster = NULL; ptr->data.soa_reply.serial = 0; ptr->data.soa_reply.refresh = 0; ptr->data.soa_reply.retry = 0; ptr->data.soa_reply.expire = 0; ptr->data.soa_reply.minttl = 0; break; default: free(ptr); return NULL; } ptr->mark = ARES_DATATYPE_MARK; ptr->type = type; return &ptr->data; } node-v4.2.6/deps/cares/src/ares_data.h000644 000766 000024 00000005454 12650222322 017665 0ustar00iojsstaff000000 000000 /* Copyright (C) 2009-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ typedef enum { ARES_DATATYPE_UNKNOWN = 1, /* unknown data type - introduced in 1.7.0 */ ARES_DATATYPE_SRV_REPLY, /* struct ares_srv_reply - introduced in 1.7.0 */ ARES_DATATYPE_TXT_REPLY, /* struct ares_txt_reply - introduced in 1.7.0 */ ARES_DATATYPE_ADDR_NODE, /* struct ares_addr_node - introduced in 1.7.1 */ ARES_DATATYPE_MX_REPLY, /* struct ares_mx_reply - introduced in 1.7.2 */ ARES_DATATYPE_NAPTR_REPLY,/* struct ares_naptr_reply - introduced in 1.7.6 */ ARES_DATATYPE_SOA_REPLY, /* struct ares_soa_reply - introduced in 1.9.0 */ #if 0 ARES_DATATYPE_ADDR6TTL, /* struct ares_addrttl */ ARES_DATATYPE_ADDRTTL, /* struct ares_addr6ttl */ ARES_DATATYPE_HOSTENT, /* struct hostent */ ARES_DATATYPE_OPTIONS, /* struct ares_options */ #endif ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */ } ares_datatype; #define ARES_DATATYPE_MARK 0xbead /* * ares_data struct definition is internal to c-ares and shall not * be exposed by the public API in order to allow future changes * and extensions to it without breaking ABI. This will be used * internally by c-ares as the container of multiple types of data * dynamically allocated for which a reference will be returned * to the calling application. * * c-ares API functions returning a pointer to c-ares internally * allocated data will actually be returning an interior pointer * into this ares_data struct. * * All this is 'invisible' to the calling application, the only * requirement is that this kind of data must be free'ed by the * calling application using ares_free_data() with the pointer * it has received from a previous c-ares function call. */ struct ares_data { ares_datatype type; /* Actual data type identifier. */ unsigned int mark; /* Private ares_data signature. */ union { struct ares_txt_reply txt_reply; struct ares_srv_reply srv_reply; struct ares_addr_node addr_node; struct ares_mx_reply mx_reply; struct ares_naptr_reply naptr_reply; struct ares_soa_reply soa_reply; } data; }; void *ares_malloc_data(ares_datatype type); node-v4.2.6/deps/cares/src/ares_destroy.c000644 000766 000024 00000005503 12650222322 020433 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004-2011 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include #include "ares.h" #include "ares_private.h" void ares_destroy_options(struct ares_options *options) { int i; if(options->servers) free(options->servers); for (i = 0; i < options->ndomains; i++) free(options->domains[i]); if(options->domains) free(options->domains); if(options->sortlist) free(options->sortlist); if(options->lookups) free(options->lookups); } void ares_destroy(ares_channel channel) { int i; struct query *query; struct list_node* list_head; struct list_node* list_node; if (!channel) return; list_head = &(channel->all_queries); for (list_node = list_head->next; list_node != list_head; ) { query = list_node->data; list_node = list_node->next; /* since we're deleting the query */ query->callback(query->arg, ARES_EDESTRUCTION, 0, NULL, 0); ares__free_query(query); } #ifndef NDEBUG /* Freeing the query should remove it from all the lists in which it sits, * so all query lists should be empty now. */ assert(ares__is_list_empty(&(channel->all_queries))); for (i = 0; i < ARES_QID_TABLE_SIZE; i++) { assert(ares__is_list_empty(&(channel->queries_by_qid[i]))); } for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) { assert(ares__is_list_empty(&(channel->queries_by_timeout[i]))); } #endif ares__destroy_servers_state(channel); if (channel->domains) { for (i = 0; i < channel->ndomains; i++) free(channel->domains[i]); free(channel->domains); } if(channel->sortlist) free(channel->sortlist); if (channel->lookups) free(channel->lookups); free(channel); } void ares__destroy_servers_state(ares_channel channel) { struct server_state *server; int i; if (channel->servers) { for (i = 0; i < channel->nservers; i++) { server = &channel->servers[i]; ares__close_sockets(channel, server); assert(ares__is_list_empty(&server->queries_to_server)); } free(channel->servers); channel->servers = NULL; } channel->nservers = -1; } node-v4.2.6/deps/cares/src/ares_dns.h000644 000766 000024 00000012272 12650222322 017534 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_DNS_H #define HEADER_CARES_DNS_H /* Copyright 1998, 2011 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Macro DNS__16BIT reads a network short (16 bit) given in network * byte order, and returns its value as an unsigned short. */ #define DNS__16BIT(p) ((unsigned short)((unsigned int) 0xffff & \ (((unsigned int)((unsigned char)(p)[0]) << 8U) | \ ((unsigned int)((unsigned char)(p)[1]))))) /* * Macro DNS__32BIT reads a network long (32 bit) given in network * byte order, and returns its value as an unsigned int. */ #define DNS__32BIT(p) ((unsigned int) \ (((unsigned int)((unsigned char)(p)[0]) << 24U) | \ ((unsigned int)((unsigned char)(p)[1]) << 16U) | \ ((unsigned int)((unsigned char)(p)[2]) << 8U) | \ ((unsigned int)((unsigned char)(p)[3])))) #define DNS__SET16BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 8) & 0xff)), \ ((p)[1] = (unsigned char)((v) & 0xff))) #define DNS__SET32BIT(p, v) (((p)[0] = (unsigned char)(((v) >> 24) & 0xff)), \ ((p)[1] = (unsigned char)(((v) >> 16) & 0xff)), \ ((p)[2] = (unsigned char)(((v) >> 8) & 0xff)), \ ((p)[3] = (unsigned char)((v) & 0xff))) #if 0 /* we cannot use this approach on systems where we can't access 16/32 bit data on un-aligned addresses */ #define DNS__16BIT(p) ntohs(*(unsigned short*)(p)) #define DNS__32BIT(p) ntohl(*(unsigned long*)(p)) #define DNS__SET16BIT(p, v) *(unsigned short*)(p) = htons(v) #define DNS__SET32BIT(p, v) *(unsigned long*)(p) = htonl(v) #endif /* Macros for parsing a DNS header */ #define DNS_HEADER_QID(h) DNS__16BIT(h) #define DNS_HEADER_QR(h) (((h)[2] >> 7) & 0x1) #define DNS_HEADER_OPCODE(h) (((h)[2] >> 3) & 0xf) #define DNS_HEADER_AA(h) (((h)[2] >> 2) & 0x1) #define DNS_HEADER_TC(h) (((h)[2] >> 1) & 0x1) #define DNS_HEADER_RD(h) ((h)[2] & 0x1) #define DNS_HEADER_RA(h) (((h)[3] >> 7) & 0x1) #define DNS_HEADER_Z(h) (((h)[3] >> 4) & 0x7) #define DNS_HEADER_RCODE(h) ((h)[3] & 0xf) #define DNS_HEADER_QDCOUNT(h) DNS__16BIT((h) + 4) #define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6) #define DNS_HEADER_NSCOUNT(h) DNS__16BIT((h) + 8) #define DNS_HEADER_ARCOUNT(h) DNS__16BIT((h) + 10) /* Macros for constructing a DNS header */ #define DNS_HEADER_SET_QID(h, v) DNS__SET16BIT(h, v) #define DNS_HEADER_SET_QR(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 7)) #define DNS_HEADER_SET_OPCODE(h, v) ((h)[2] |= (unsigned char)(((v) & 0xf) << 3)) #define DNS_HEADER_SET_AA(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 2)) #define DNS_HEADER_SET_TC(h, v) ((h)[2] |= (unsigned char)(((v) & 0x1) << 1)) #define DNS_HEADER_SET_RD(h, v) ((h)[2] |= (unsigned char)((v) & 0x1)) #define DNS_HEADER_SET_RA(h, v) ((h)[3] |= (unsigned char)(((v) & 0x1) << 7)) #define DNS_HEADER_SET_Z(h, v) ((h)[3] |= (unsigned char)(((v) & 0x7) << 4)) #define DNS_HEADER_SET_RCODE(h, v) ((h)[3] |= (unsigned char)((v) & 0xf)) #define DNS_HEADER_SET_QDCOUNT(h, v) DNS__SET16BIT((h) + 4, v) #define DNS_HEADER_SET_ANCOUNT(h, v) DNS__SET16BIT((h) + 6, v) #define DNS_HEADER_SET_NSCOUNT(h, v) DNS__SET16BIT((h) + 8, v) #define DNS_HEADER_SET_ARCOUNT(h, v) DNS__SET16BIT((h) + 10, v) /* Macros for parsing the fixed part of a DNS question */ #define DNS_QUESTION_TYPE(q) DNS__16BIT(q) #define DNS_QUESTION_CLASS(q) DNS__16BIT((q) + 2) /* Macros for constructing the fixed part of a DNS question */ #define DNS_QUESTION_SET_TYPE(q, v) DNS__SET16BIT(q, v) #define DNS_QUESTION_SET_CLASS(q, v) DNS__SET16BIT((q) + 2, v) /* Macros for parsing the fixed part of a DNS resource record */ #define DNS_RR_TYPE(r) DNS__16BIT(r) #define DNS_RR_CLASS(r) DNS__16BIT((r) + 2) #define DNS_RR_TTL(r) DNS__32BIT((r) + 4) #define DNS_RR_LEN(r) DNS__16BIT((r) + 8) /* Macros for constructing the fixed part of a DNS resource record */ #define DNS_RR_SET_TYPE(r, v) DNS__SET16BIT(r, v) #define DNS_RR_SET_CLASS(r, v) DNS__SET16BIT((r) + 2, v) #define DNS_RR_SET_TTL(r, v) DNS__SET32BIT((r) + 4, v) #define DNS_RR_SET_LEN(r, v) DNS__SET16BIT((r) + 8, v) #endif /* HEADER_CARES_DNS_H */ node-v4.2.6/deps/cares/src/ares_expand_name.c000644 000766 000024 00000013412 12650222322 021217 0ustar00iojsstaff000000 000000 /* Copyright 1998, 2011 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_nowarn.h" #include "ares_private.h" /* for the memdebug */ static int name_length(const unsigned char *encoded, const unsigned char *abuf, int alen); /* Expand an RFC1035-encoded domain name given by encoded. The * containing message is given by abuf and alen. The result given by * *s, which is set to a NUL-terminated allocated buffer. *enclen is * set to the length of the encoded name (not the length of the * expanded name; the goal is to tell the caller how many bytes to * move forward to get past the encoded name). * * In the simple case, an encoded name is a series of labels, each * composed of a one-byte length (limited to values between 0 and 63 * inclusive) followed by the label contents. The name is terminated * by a zero-length label. * * In the more complicated case, a label may be terminated by an * indirection pointer, specified by two bytes with the high bits of * the first byte (corresponding to INDIR_MASK) set to 11. With the * two high bits of the first byte stripped off, the indirection * pointer gives an offset from the beginning of the containing * message with more labels to decode. Indirection can happen an * arbitrary number of times, so we have to detect loops. * * Since the expanded name uses '.' as a label separator, we use * backslashes to escape periods or backslashes in the expanded name. */ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen) { int len, indir = 0; char *q; const unsigned char *p; union { ssize_t sig; size_t uns; } nlen; nlen.sig = name_length(encoded, abuf, alen); if (nlen.sig < 0) return ARES_EBADNAME; *s = malloc(nlen.uns + 1); if (!*s) return ARES_ENOMEM; q = *s; if (nlen.uns == 0) { /* RFC2181 says this should be ".": the root of the DNS tree. * Since this function strips trailing dots though, it becomes "" */ q[0] = '\0'; /* indirect root label (like 0xc0 0x0c) is 2 bytes long (stupid, but valid) */ if ((*encoded & INDIR_MASK) == INDIR_MASK) *enclen = 2L; else *enclen = 1L; /* the caller should move one byte to get past this */ return ARES_SUCCESS; } /* No error-checking necessary; it was all done by name_length(). */ p = encoded; while (*p) { if ((*p & INDIR_MASK) == INDIR_MASK) { if (!indir) { *enclen = aresx_uztosl(p + 2U - encoded); indir = 1; } p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1)); } else { len = *p; p++; while (len--) { if (*p == '.' || *p == '\\') *q++ = '\\'; *q++ = *p; p++; } *q++ = '.'; } } if (!indir) *enclen = aresx_uztosl(p + 1U - encoded); /* Nuke the trailing period if we wrote one. */ if (q > *s) *(q - 1) = 0; else *q = 0; /* zero terminate */ return ARES_SUCCESS; } /* Return the length of the expansion of an encoded domain name, or * -1 if the encoding is invalid. */ static int name_length(const unsigned char *encoded, const unsigned char *abuf, int alen) { int n = 0, offset, indir = 0; /* Allow the caller to pass us abuf + alen and have us check for it. */ if (encoded >= abuf + alen) return -1; while (*encoded) { if ((*encoded & INDIR_MASK) == INDIR_MASK) { /* Check the offset and go there. */ if (encoded + 1 >= abuf + alen) return -1; offset = (*encoded & ~INDIR_MASK) << 8 | *(encoded + 1); if (offset >= alen) return -1; encoded = abuf + offset; /* If we've seen more indirects than the message length, * then there's a loop. */ if (++indir > alen) return -1; } else { offset = *encoded; if (encoded + offset + 1 >= abuf + alen) return -1; encoded++; while (offset--) { n += (*encoded == '.' || *encoded == '\\') ? 2 : 1; encoded++; } n++; } } /* If there were any labels at all, then the number of dots is one * less than the number of labels, so subtract one. */ return (n) ? n - 1 : n; } /* Like ares_expand_name but returns EBADRESP in case of invalid input. */ int ares__expand_name_for_response(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen) { int status = ares_expand_name(encoded, abuf, alen, s, enclen); if (status == ARES_EBADNAME) status = ARES_EBADRESP; return status; } node-v4.2.6/deps/cares/src/ares_expand_string.c000644 000766 000024 00000003502 12650222322 021604 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #include "ares.h" #include "ares_private.h" /* for the memdebug */ /* Simply decodes a length-encoded character string. The first byte of the * input is the length of the string to be returned and the bytes thereafter * are the characters of the string. The returned result will be NULL * terminated. */ int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen) { unsigned char *q; union { ssize_t sig; size_t uns; } elen; if (encoded == abuf+alen) return ARES_EBADSTR; elen.uns = *encoded; if (encoded+elen.sig+1 > abuf+alen) return ARES_EBADSTR; encoded++; *s = malloc(elen.uns+1); if (*s == NULL) return ARES_ENOMEM; q = *s; strncpy((char *)q, (char *)encoded, elen.uns); q[elen.uns] = '\0'; *s = q; *enclen = (long)(elen.sig+1); return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_fds.c000644 000766 000024 00000003657 12650222322 017526 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_nowarn.h" #include "ares_private.h" int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds) { struct server_state *server; ares_socket_t nfds; int i; /* Are there any active queries? */ int active_queries = !ares__is_list_empty(&(channel->all_queries)); nfds = 0; for (i = 0; i < channel->nservers; i++) { server = &channel->servers[i]; /* We only need to register interest in UDP sockets if we have * outstanding queries. */ if (active_queries && server->udp_socket != ARES_SOCKET_BAD) { FD_SET(server->udp_socket, read_fds); if (server->udp_socket >= nfds) nfds = server->udp_socket + 1; } /* We always register for TCP events, because we want to know * when the other side closes the connection, so we don't waste * time trying to use a broken connection. */ if (server->tcp_socket != ARES_SOCKET_BAD) { FD_SET(server->tcp_socket, read_fds); if (server->qhead) FD_SET(server->tcp_socket, write_fds); if (server->tcp_socket >= nfds) nfds = server->tcp_socket + 1; } } return (int)nfds; } node-v4.2.6/deps/cares/src/ares_free_hostent.c000644 000766 000024 00000002320 12650222322 021421 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETDB_H #include #endif #include "ares.h" #include "ares_private.h" /* for memdebug */ void ares_free_hostent(struct hostent *host) { char **p; if (!host) return; free((char *)(host->h_name)); for (p = host->h_aliases; *p; p++) free(*p); free(host->h_aliases); free(host->h_addr_list[0]); /* no matter if there is one or many entries, there is only one malloc for all of them */ free(host->h_addr_list); free(host); } node-v4.2.6/deps/cares/src/ares_free_string.c000644 000766 000024 00000001472 12650222322 021252 0ustar00iojsstaff000000 000000 /* Copyright 2000 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_private.h" void ares_free_string(void *str) { free(str); } node-v4.2.6/deps/cares/src/ares_getenv.c000644 000766 000024 00000001542 12650222322 020231 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares_getenv.h" #ifndef HAVE_GETENV char *ares_getenv(const char *name) { #ifdef _WIN32_WCE return NULL; #endif } #endif node-v4.2.6/deps/cares/src/ares_getenv.h000644 000766 000024 00000001603 12650222322 020234 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_GETENV_H #define HEADER_CARES_GETENV_H /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifndef HAVE_GETENV extern char *ares_getenv(const char *name); #endif #endif /* HEADER_CARES_GETENV_H */ node-v4.2.6/deps/cares/src/ares_gethostbyaddr.c000644 000766 000024 00000020675 12650222322 021614 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_inet_net_pton.h" #include "ares_platform.h" #include "ares_private.h" #ifdef WATT32 #undef WIN32 #endif struct addr_query { /* Arguments passed to ares_gethostbyaddr() */ ares_channel channel; struct ares_addr addr; ares_host_callback callback; void *arg; const char *remaining_lookups; int timeouts; }; static void next_lookup(struct addr_query *aquery); static void addr_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_aquery(struct addr_query *aquery, int status, struct hostent *host); static int file_lookup(struct ares_addr *addr, struct hostent **host); static void ptr_rr_name(char *name, const struct ares_addr *addr); void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, int family, ares_host_callback callback, void *arg) { struct addr_query *aquery; if (family != AF_INET && family != AF_INET6) { callback(arg, ARES_ENOTIMP, 0, NULL); return; } if ((family == AF_INET && addrlen != sizeof(aquery->addr.addrV4)) || (family == AF_INET6 && addrlen != sizeof(aquery->addr.addrV6))) { callback(arg, ARES_ENOTIMP, 0, NULL); return; } aquery = malloc(sizeof(struct addr_query)); if (!aquery) { callback(arg, ARES_ENOMEM, 0, NULL); return; } aquery->channel = channel; if (family == AF_INET) memcpy(&aquery->addr.addrV4, addr, sizeof(aquery->addr.addrV4)); else memcpy(&aquery->addr.addrV6, addr, sizeof(aquery->addr.addrV6)); aquery->addr.family = family; aquery->callback = callback; aquery->arg = arg; aquery->remaining_lookups = channel->lookups; aquery->timeouts = 0; next_lookup(aquery); } static void next_lookup(struct addr_query *aquery) { const char *p; char name[128]; int status; struct hostent *host; for (p = aquery->remaining_lookups; *p; p++) { switch (*p) { case 'b': ptr_rr_name(name, &aquery->addr); aquery->remaining_lookups = p + 1; ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, aquery); return; case 'f': status = file_lookup(&aquery->addr, &host); /* this status check below previously checked for !ARES_ENOTFOUND, but we should not assume that this single error code is the one that can occur, as that is in fact no longer the case */ if (status == ARES_SUCCESS) { end_aquery(aquery, status, host); return; } break; } } end_aquery(aquery, ARES_ENOTFOUND, NULL); } static void addr_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct addr_query *aquery = (struct addr_query *) arg; struct hostent *host; size_t addrlen; aquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (aquery->addr.family == AF_INET) { addrlen = sizeof(aquery->addr.addrV4); status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV4, (int)addrlen, AF_INET, &host); } else { addrlen = sizeof(aquery->addr.addrV6); status = ares_parse_ptr_reply(abuf, alen, &aquery->addr.addrV6, (int)addrlen, AF_INET6, &host); } end_aquery(aquery, status, host); } else if (status == ARES_EDESTRUCTION) end_aquery(aquery, status, NULL); else next_lookup(aquery); } static void end_aquery(struct addr_query *aquery, int status, struct hostent *host) { aquery->callback(aquery->arg, status, aquery->timeouts, host); if (host) ares_free_hostent(host); free(aquery); } static int file_lookup(struct ares_addr *addr, struct hostent **host) { FILE *fp; int status; int error; #ifdef WIN32 char PATH_HOSTS[MAX_PATH]; win_platform platform; PATH_HOSTS[0] = '\0'; platform = ares__getplatform(); if (platform == WIN_NT) { char tmp[MAX_PATH]; HKEY hkeyHosts; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) GetWindowsDirectory(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; strcat(PATH_HOSTS, WIN_PATH_HOSTS); #elif defined(WATT32) extern const char *_w32_GetHostsFile (void); const char *PATH_HOSTS = _w32_GetHostsFile(); if (!PATH_HOSTS) return ARES_ENOTFOUND; #endif fp = fopen(PATH_HOSTS, "r"); if (!fp) { error = ERRNO; switch(error) { case ENOENT: case ESRCH: return ARES_ENOTFOUND; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_HOSTS)); *host = NULL; return ARES_EFILE; } } while ((status = ares__get_hostent(fp, addr->family, host)) == ARES_SUCCESS) { if (addr->family != (*host)->h_addrtype) { ares_free_hostent(*host); continue; } if (addr->family == AF_INET) { if (memcmp((*host)->h_addr, &addr->addrV4, sizeof(addr->addrV4)) == 0) break; } else if (addr->family == AF_INET6) { if (memcmp((*host)->h_addr, &addr->addrV6, sizeof(addr->addrV6)) == 0) break; } ares_free_hostent(*host); } fclose(fp); if (status == ARES_EOF) status = ARES_ENOTFOUND; if (status != ARES_SUCCESS) *host = NULL; return status; } static void ptr_rr_name(char *name, const struct ares_addr *addr) { if (addr->family == AF_INET) { unsigned long laddr = ntohl(addr->addrV4.s_addr); unsigned long a1 = (laddr >> 24UL) & 0xFFUL; unsigned long a2 = (laddr >> 16UL) & 0xFFUL; unsigned long a3 = (laddr >> 8UL) & 0xFFUL; unsigned long a4 = laddr & 0xFFUL; sprintf(name, "%lu.%lu.%lu.%lu.in-addr.arpa", a4, a3, a2, a1); } else { unsigned char *bytes = (unsigned char *)&addr->addrV6; /* There are too many arguments to do this in one line using * minimally C89-compliant compilers */ sprintf(name, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.", bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4, bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4, bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4, bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4); sprintf(name+strlen(name), "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4, bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4, bytes[3]&0xf, bytes[3] >> 4, bytes[2]&0xf, bytes[2] >> 4, bytes[1]&0xf, bytes[1] >> 4, bytes[0]&0xf, bytes[0] >> 4); } } node-v4.2.6/deps/cares/src/ares_gethostbyname.c000644 000766 000024 00000036227 12650222322 021622 0ustar00iojsstaff000000 000000 /* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H #include #endif #include "ares.h" #include "ares_inet_net_pton.h" #include "bitncmp.h" #include "ares_platform.h" #include "ares_nowarn.h" #include "ares_private.h" #ifdef WATT32 #undef WIN32 #endif struct host_query { /* Arguments passed to ares_gethostbyname() */ ares_channel channel; char *name; ares_host_callback callback; void *arg; int sent_family; /* this family is what was is being used */ int want_family; /* this family is what is asked for in the API */ const char *remaining_lookups; int timeouts; }; static void next_lookup(struct host_query *hquery, int status_code); static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_hquery(struct host_query *hquery, int status, struct hostent *host); static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg); static int file_lookup(const char *name, int family, struct hostent **host); static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort); static int get6_address_index(const struct ares_in6_addr *addr, const struct apattern *sortlist, int nsort); void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg) { struct host_query *hquery; /* Right now we only know how to look up Internet addresses - and unspec means try both basically. */ switch (family) { case AF_INET: case AF_INET6: case AF_UNSPEC: break; default: callback(arg, ARES_ENOTIMP, 0, NULL); return; } if (fake_hostent(name, family, callback, arg)) return; /* Allocate and fill in the host query structure. */ hquery = malloc(sizeof(struct host_query)); if (!hquery) { callback(arg, ARES_ENOMEM, 0, NULL); return; } hquery->channel = channel; hquery->name = strdup(name); hquery->want_family = family; hquery->sent_family = -1; /* nothing is sent yet */ if (!hquery->name) { free(hquery); callback(arg, ARES_ENOMEM, 0, NULL); return; } hquery->callback = callback; hquery->arg = arg; hquery->remaining_lookups = channel->lookups; hquery->timeouts = 0; /* Start performing lookups according to channel->lookups. */ next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */); } static void next_lookup(struct host_query *hquery, int status_code) { const char *p; struct hostent *host; int status = status_code; for (p = hquery->remaining_lookups; *p; p++) { switch (*p) { case 'b': /* DNS lookup */ hquery->remaining_lookups = p + 1; if ((hquery->want_family == AF_INET6) || (hquery->want_family == AF_UNSPEC)) { /* if inet6 or unspec, start out with AAAA */ hquery->sent_family = AF_INET6; ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback, hquery); } else { hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } return; case 'f': /* Host file lookup */ status = file_lookup(hquery->name, hquery->want_family, &host); /* this status check below previously checked for !ARES_ENOTFOUND, but we should not assume that this single error code is the one that can occur, as that is in fact no longer the case */ if (status == ARES_SUCCESS) { end_hquery(hquery, status, host); return; } status = status_code; /* Use original status code */ break; } } end_hquery(hquery, status, NULL); } static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct host_query *hquery = (struct host_query *) arg; ares_channel channel = hquery->channel; struct hostent *host = NULL; hquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (hquery->sent_family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); } else if (hquery->sent_family == AF_INET6) { status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if ((status == ARES_ENODATA || status == ARES_EBADRESP || (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)) && hquery->want_family == AF_UNSPEC) { /* The query returned something but either there were no AAAA records (e.g. just CNAME) or the response was malformed. Try looking up A instead. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); return; } if (host && channel->nsort) sort6_addresses(host, channel->sortlist, channel->nsort); } end_hquery(hquery, status, host); } else if ((status == ARES_ENODATA || status == ARES_EBADRESP || status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 && hquery->want_family == AF_UNSPEC)) { /* The AAAA query yielded no useful result. Now look up an A instead. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } else if (status == ARES_EDESTRUCTION) end_hquery(hquery, status, NULL); else next_lookup(hquery, status); } static void end_hquery(struct host_query *hquery, int status, struct hostent *host) { hquery->callback(hquery->arg, status, hquery->timeouts, host); if (host) ares_free_hostent(host); free(hquery->name); free(hquery); } /* If the name looks like an IP address, fake up a host entry, end the * query immediately, and return true. Otherwise return false. */ static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg) { struct hostent hostent; char *aliases[1] = { NULL }; char *addrs[2]; int result = 0; struct in_addr in; struct ares_in6_addr in6; if (family == AF_INET || family == AF_INET6) { /* It only looks like an IP address if it's all numbers and dots. */ int numdots = 0, valid = 1; const char *p; for (p = name; *p; p++) { if (!ISDIGIT(*p) && *p != '.') { valid = 0; break; } else if (*p == '.') { numdots++; } } /* if we don't have 3 dots, it is illegal * (although inet_addr doesn't think so). */ if (numdots != 3 || !valid) result = 0; else result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1); if (result) family = AF_INET; } if (family == AF_INET6) result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1); if (!result) return 0; if (family == AF_INET) { hostent.h_length = (int)sizeof(struct in_addr); addrs[0] = (char *)∈ } else if (family == AF_INET6) { hostent.h_length = (int)sizeof(struct ares_in6_addr); addrs[0] = (char *)&in6; } /* Duplicate the name, to avoid a constness violation. */ hostent.h_name = strdup(name); if (!hostent.h_name) { callback(arg, ARES_ENOMEM, 0, NULL); return 1; } /* Fill in the rest of the host structure and terminate the query. */ addrs[1] = NULL; hostent.h_aliases = aliases; hostent.h_addrtype = aresx_sitoss(family); hostent.h_addr_list = addrs; callback(arg, ARES_SUCCESS, 0, &hostent); free((char *)(hostent.h_name)); return 1; } /* This is an API method */ int ares_gethostbyname_file(ares_channel channel, const char *name, int family, struct hostent **host) { int result; /* We only take the channel to ensure that ares_init() been called. */ if(channel == NULL) { /* Anything will do, really. This seems fine, and is consistent with other error cases. */ *host = NULL; return ARES_ENOTFOUND; } /* Just chain to the internal implementation we use here; it's exactly * what we want. */ result = file_lookup(name, family, host); if(result != ARES_SUCCESS) { /* We guarantee a NULL hostent on failure. */ *host = NULL; } return result; } static int file_lookup(const char *name, int family, struct hostent **host) { FILE *fp; char **alias; int status; int error; #ifdef WIN32 char PATH_HOSTS[MAX_PATH]; win_platform platform; PATH_HOSTS[0] = '\0'; platform = ares__getplatform(); if (platform == WIN_NT) { char tmp[MAX_PATH]; HKEY hkeyHosts; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) GetWindowsDirectory(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; strcat(PATH_HOSTS, WIN_PATH_HOSTS); #elif defined(WATT32) extern const char *_w32_GetHostsFile (void); const char *PATH_HOSTS = _w32_GetHostsFile(); if (!PATH_HOSTS) return ARES_ENOTFOUND; #endif fp = fopen(PATH_HOSTS, "r"); if (!fp) { error = ERRNO; switch(error) { case ENOENT: case ESRCH: return ARES_ENOTFOUND; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_HOSTS)); *host = NULL; return ARES_EFILE; } } while ((status = ares__get_hostent(fp, family, host)) == ARES_SUCCESS) { if (strcasecmp((*host)->h_name, name) == 0) break; for (alias = (*host)->h_aliases; *alias; alias++) { if (strcasecmp(*alias, name) == 0) break; } if (*alias) break; ares_free_hostent(*host); } fclose(fp); if (status == ARES_EOF) status = ARES_ENOTFOUND; if (status != ARES_SUCCESS) *host = NULL; return status; } static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort) { struct in_addr a1, a2; int i1, i2, ind1, ind2; /* This is a simple insertion sort, not optimized at all. i1 walks * through the address list, with the loop invariant that everything * to the left of i1 is sorted. In the loop body, the value at i1 is moved * back through the list (via i2) until it is in sorted order. */ for (i1 = 0; host->h_addr_list[i1]; i1++) { memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr)); ind1 = get_address_index(&a1, sortlist, nsort); for (i2 = i1 - 1; i2 >= 0; i2--) { memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr)); ind2 = get_address_index(&a2, sortlist, nsort); if (ind2 <= ind1) break; memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr)); } memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr)); } } /* Find the first entry in sortlist which matches addr. Return nsort * if none of them match. */ static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort) { int i; for (i = 0; i < nsort; i++) { if (sortlist[i].family != AF_INET) continue; if (sortlist[i].type == PATTERN_MASK) { if ((addr->s_addr & sortlist[i].mask.addr4.s_addr) == sortlist[i].addrV4.s_addr) break; } else { if (!ares__bitncmp(&addr->s_addr, &sortlist[i].addrV4.s_addr, sortlist[i].mask.bits)) break; } } return i; } static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort) { struct ares_in6_addr a1, a2; int i1, i2, ind1, ind2; /* This is a simple insertion sort, not optimized at all. i1 walks * through the address list, with the loop invariant that everything * to the left of i1 is sorted. In the loop body, the value at i1 is moved * back through the list (via i2) until it is in sorted order. */ for (i1 = 0; host->h_addr_list[i1]; i1++) { memcpy(&a1, host->h_addr_list[i1], sizeof(struct ares_in6_addr)); ind1 = get6_address_index(&a1, sortlist, nsort); for (i2 = i1 - 1; i2 >= 0; i2--) { memcpy(&a2, host->h_addr_list[i2], sizeof(struct ares_in6_addr)); ind2 = get6_address_index(&a2, sortlist, nsort); if (ind2 <= ind1) break; memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct ares_in6_addr)); } memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct ares_in6_addr)); } } /* Find the first entry in sortlist which matches addr. Return nsort * if none of them match. */ static int get6_address_index(const struct ares_in6_addr *addr, const struct apattern *sortlist, int nsort) { int i; for (i = 0; i < nsort; i++) { if (sortlist[i].family != AF_INET6) continue; if (!ares__bitncmp(addr, &sortlist[i].addrV6, sortlist[i].mask.bits)) break; } return i; } node-v4.2.6/deps/cares/src/ares_getnameinfo.c000644 000766 000024 00000030746 12650222322 021245 0ustar00iojsstaff000000 000000 /* Copyright 2005 by Dominick Meglio * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_GETSERVBYPORT_R # if !defined(GETSERVBYPORT_R_ARGS) || \ (GETSERVBYPORT_R_ARGS < 4) || (GETSERVBYPORT_R_ARGS > 6) # error "you MUST specifiy a valid number of arguments for getservbyport_r" # endif #endif #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_NET_IF_H #include #endif #include "ares.h" #include "ares_ipv6.h" #include "ares_nowarn.h" #include "ares_private.h" struct nameinfo_query { ares_nameinfo_callback callback; void *arg; union { struct sockaddr_in addr4; struct sockaddr_in6 addr6; } addr; int family; int flags; int timeouts; }; #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID #define IPBUFSIZ \ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") + IF_NAMESIZE) #else #define IPBUFSIZ \ (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")) #endif static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host); static char *lookup_service(unsigned short port, int flags, char *buf, size_t buflen); #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf, size_t buflen); #endif static char *ares_striendstr(const char *s1, const char *s2); void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, ares_socklen_t salen, int flags, ares_nameinfo_callback callback, void *arg) { struct sockaddr_in *addr = NULL; struct sockaddr_in6 *addr6 = NULL; struct nameinfo_query *niquery; unsigned int port = 0; /* Validate socket address family and length */ if ((sa->sa_family == AF_INET) && (salen == sizeof(struct sockaddr_in))) { addr = (struct sockaddr_in *)sa; port = addr->sin_port; } else if ((sa->sa_family == AF_INET6) && (salen == sizeof(struct sockaddr_in6))) { addr6 = (struct sockaddr_in6 *)sa; port = addr6->sin6_port; } else { callback(arg, ARES_ENOTIMP, 0, NULL, NULL); return; } /* If neither, assume they want a host */ if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) flags |= ARES_NI_LOOKUPHOST; /* All they want is a service, no need for DNS */ if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) { char buf[33], *service; service = lookup_service((unsigned short)(port & 0xffff), flags, buf, sizeof(buf)); callback(arg, ARES_SUCCESS, 0, NULL, service); return; } /* They want a host lookup */ if ((flags & ARES_NI_LOOKUPHOST)) { /* A numeric host can be handled without DNS */ if ((flags & ARES_NI_NUMERICHOST)) { char ipbuf[IPBUFSIZ]; char srvbuf[33]; char *service = NULL; ipbuf[0] = 0; /* Specifying not to lookup a host, but then saying a host * is required has to be illegal. */ if (flags & ARES_NI_NAMEREQD) { callback(arg, ARES_EBADFLAGS, 0, NULL, NULL); return; } if (salen == sizeof(struct sockaddr_in6)) { ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ); /* If the system supports scope IDs, use it */ #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID append_scopeid(addr6, flags, ipbuf, sizeof(ipbuf)); #endif } else { ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ); } /* They also want a service */ if (flags & ARES_NI_LOOKUPSERVICE) service = lookup_service((unsigned short)(port & 0xffff), flags, srvbuf, sizeof(srvbuf)); callback(arg, ARES_SUCCESS, 0, ipbuf, service); return; } /* This is where a DNS lookup becomes necessary */ else { niquery = malloc(sizeof(struct nameinfo_query)); if (!niquery) { callback(arg, ARES_ENOMEM, 0, NULL, NULL); return; } niquery->callback = callback; niquery->arg = arg; niquery->flags = flags; niquery->timeouts = 0; if (sa->sa_family == AF_INET) { niquery->family = AF_INET; memcpy(&niquery->addr.addr4, addr, sizeof(niquery->addr.addr4)); ares_gethostbyaddr(channel, &addr->sin_addr, sizeof(struct in_addr), AF_INET, nameinfo_callback, niquery); } else { niquery->family = AF_INET6; memcpy(&niquery->addr.addr6, addr6, sizeof(niquery->addr.addr6)); ares_gethostbyaddr(channel, &addr6->sin6_addr, sizeof(struct ares_in6_addr), AF_INET6, nameinfo_callback, niquery); } } } } static void nameinfo_callback(void *arg, int status, int timeouts, struct hostent *host) { struct nameinfo_query *niquery = (struct nameinfo_query *) arg; char srvbuf[33]; char *service = NULL; niquery->timeouts += timeouts; if (status == ARES_SUCCESS) { /* They want a service too */ if (niquery->flags & ARES_NI_LOOKUPSERVICE) { if (niquery->family == AF_INET) service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf, sizeof(srvbuf)); else service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf, sizeof(srvbuf)); } /* NOFQDN means we have to strip off the domain name portion. We do this by determining our own domain name, then searching the string for this domain name and removing it. */ #ifdef HAVE_GETHOSTNAME if (niquery->flags & ARES_NI_NOFQDN) { char buf[255]; char *domain; gethostname(buf, 255); if ((domain = strchr(buf, '.')) != NULL) { char *end = ares_striendstr(host->h_name, domain); if (end) *end = 0; } } #endif niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, (char *)(host->h_name), service); free(niquery); return; } /* We couldn't find the host, but it's OK, we can use the IP */ else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD)) { char ipbuf[IPBUFSIZ]; if (niquery->family == AF_INET) ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ); else { ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ); #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf, sizeof(ipbuf)); #endif } /* They want a service too */ if (niquery->flags & ARES_NI_LOOKUPSERVICE) { if (niquery->family == AF_INET) service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf, sizeof(srvbuf)); else service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf, sizeof(srvbuf)); } niquery->callback(niquery->arg, ARES_SUCCESS, niquery->timeouts, ipbuf, service); free(niquery); return; } niquery->callback(niquery->arg, status, niquery->timeouts, NULL, NULL); free(niquery); } static char *lookup_service(unsigned short port, int flags, char *buf, size_t buflen) { const char *proto; struct servent *sep; #ifdef HAVE_GETSERVBYPORT_R struct servent se; #endif char tmpbuf[4096]; char *name; size_t name_len; if (port) { if (flags & ARES_NI_NUMERICSERV) sep = NULL; else { if (flags & ARES_NI_UDP) proto = "udp"; else if (flags & ARES_NI_SCTP) proto = "sctp"; else if (flags & ARES_NI_DCCP) proto = "dccp"; else proto = "tcp"; #ifdef HAVE_GETSERVBYPORT_R sep = &se; memset(tmpbuf, 0, sizeof(tmpbuf)); #if GETSERVBYPORT_R_ARGS == 6 if (getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), &sep) != 0) sep = NULL; #elif GETSERVBYPORT_R_ARGS == 5 sep = getservbyport_r(port, proto, &se, (void *)tmpbuf, sizeof(tmpbuf)); #elif GETSERVBYPORT_R_ARGS == 4 if (getservbyport_r(port, proto, &se, (void *)tmpbuf) != 0) sep = NULL; #else /* Lets just hope the OS uses TLS! */ sep = getservbyport(port, proto); #endif #else /* Lets just hope the OS uses TLS! */ #if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) sep = getservbyport(port, (char*)proto); #else sep = getservbyport(port, proto); #endif #endif } if (sep && sep->s_name) { /* get service name */ name = sep->s_name; } else { /* get port as a string */ sprintf(tmpbuf, "%u", (unsigned int)ntohs(port)); name = tmpbuf; } name_len = strlen(name); if (name_len < buflen) /* return it if buffer big enough */ memcpy(buf, name, name_len + 1); else /* avoid reusing previous one */ buf[0] = '\0'; return buf; } buf[0] = '\0'; return NULL; } #ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, char *buf, size_t buflen) { #ifdef HAVE_IF_INDEXTONAME int is_ll, is_mcll; #endif static const char fmt_u[] = "%u"; static const char fmt_lu[] = "%lu"; char tmpbuf[IF_NAMESIZE + 2]; size_t bufl; const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))? fmt_lu:fmt_u; tmpbuf[0] = '%'; #ifdef HAVE_IF_INDEXTONAME is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr); is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr); if ((flags & ARES_NI_NUMERICSCOPE) || (!is_ll && !is_mcll)) { sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); } else { if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL) sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); } #else sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); (void) flags; #endif tmpbuf[IF_NAMESIZE + 1] = '\0'; bufl = strlen(buf); if(bufl + strlen(tmpbuf) < buflen) /* only append the scopeid string if it fits in the target buffer */ strcpy(&buf[bufl], tmpbuf); } #endif /* Determines if s1 ends with the string in s2 (case-insensitive) */ static char *ares_striendstr(const char *s1, const char *s2) { const char *c1, *c2, *c1_begin; int lo1, lo2; size_t s1_len = strlen(s1), s2_len = strlen(s2); /* If the substr is longer than the full str, it can't match */ if (s2_len > s1_len) return NULL; /* Jump to the end of s1 minus the length of s2 */ c1_begin = s1+s1_len-s2_len; c1 = (const char *)c1_begin; c2 = s2; while (c2 < s2+s2_len) { lo1 = TOLOWER(*c1); lo2 = TOLOWER(*c2); if (lo1 != lo2) return NULL; else { c1++; c2++; } } if (c2 == c1 && c2 == NULL) return (char *)c1_begin; return NULL; } node-v4.2.6/deps/cares/src/ares_getopt.c000644 000766 000024 00000010721 12650222322 020242 0ustar00iojsstaff000000 000000 /* * Original file name getopt.c Initial import into the c-ares source tree * on 2007-04-11. Lifted from version 5.2 of the 'Open Mash' project with * the modified BSD license, BSD license without the advertising clause. * */ /* * getopt.c -- * * Standard UNIX getopt function. Code is from BSD. * * Copyright (c) 1987-2001 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * A. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * B. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * C. Neither the names of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* #if !defined(lint) * static char sccsid[] = "@(#)getopt.c 8.2 (Berkeley) 4/2/94"; * #endif */ #include #include #include #include "ares_getopt.h" int opterr = 1, /* if error message should be printed */ optind = 1; /* index into parent argv vector */ int optopt = 0; /* character checked for validity */ static int optreset; /* reset getopt */ char *optarg; /* argument associated with option */ #define BADCH (int)'?' #define BADARG (int)':' #define EMSG (char *)"" /* * ares_getopt -- * Parse argc/argv argument vector. */ int ares_getopt(int nargc, char * const nargv[], const char *ostr) { static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ if (optreset || !*place) { /* update scanning pointer */ optreset = 0; if (optind >= nargc || *(place = nargv[optind]) != '-') { place = EMSG; return (EOF); } if (place[1] && *++place == '-') { /* found "--" */ ++optind; place = EMSG; return (EOF); } } /* option letter okay? */ if ((optopt = (int)*place++) == (int)':' || (oli = strchr(ostr, optopt)) == NULL) { /* * if the user didn't specify '-' as an option, * assume it means EOF. */ if (optopt == (int)'-') return (EOF); if (!*place) ++optind; if (opterr && *ostr != ':') (void)fprintf(stderr, "%s: illegal option -- %c\n", __FILE__, optopt); return (BADCH); } if (*++oli != ':') { /* don't need argument */ optarg = NULL; if (!*place) ++optind; } else { /* need an argument */ if (*place) /* no white space */ optarg = place; else if (nargc <= ++optind) { /* no arg */ place = EMSG; if (*ostr == ':') return (BADARG); if (opterr) (void)fprintf(stderr, "%s: option requires an argument -- %c\n", __FILE__, optopt); return (BADCH); } else /* white space */ optarg = nargv[optind]; place = EMSG; ++optind; } return (optopt); /* dump back option letter */ } node-v4.2.6/deps/cares/src/ares_getopt.h000644 000766 000024 00000004005 12650222322 020245 0ustar00iojsstaff000000 000000 #ifndef ARES_GETOPT_H #define ARES_GETOPT_H /* * Copyright (c) 1987-2001 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * A. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * B. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * C. Neither the names of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ int ares_getopt(int nargc, char * const nargv[], const char *ostr); #undef optarg #undef optind #undef opterr #undef optopt #undef optreset #define optarg ares_optarg #define optind ares_optind #define opterr ares_opterr #define optopt ares_optopt #define optreset ares_optreset extern char *optarg; extern int optind; extern int opterr; extern int optopt; #endif /* ARES_GETOPT_H */ node-v4.2.6/deps/cares/src/ares_getsock.c000644 000766 000024 00000004400 12650222322 020374 0ustar00iojsstaff000000 000000 /* Copyright (C) 2005 - 2010, Daniel Stenberg * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_private.h" int ares_getsock(ares_channel channel, ares_socket_t *socks, int numsocks) /* size of the 'socks' array */ { struct server_state *server; int i; int sockindex=0; int bitmap = 0; unsigned int setbits = 0xffffffff; /* Are there any active queries? */ int active_queries = !ares__is_list_empty(&(channel->all_queries)); for (i = 0; i < channel->nservers; i++) { server = &channel->servers[i]; /* We only need to register interest in UDP sockets if we have * outstanding queries. */ if (active_queries && server->udp_socket != ARES_SOCKET_BAD) { if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM) break; socks[sockindex] = server->udp_socket; bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); sockindex++; } /* We always register for TCP events, because we want to know * when the other side closes the connection, so we don't waste * time trying to use a broken connection. */ if (server->tcp_socket != ARES_SOCKET_BAD) { if(sockindex >= numsocks || sockindex >= ARES_GETSOCK_MAXNUM) break; socks[sockindex] = server->tcp_socket; bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex); if (server->qhead && active_queries) /* then the tcp socket is also writable! */ bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex); sockindex++; } } return bitmap; } node-v4.2.6/deps/cares/src/ares_inet_net_pton.h000644 000766 000024 00000001726 12650222322 021617 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_INET_NET_PTON_H #define HEADER_CARES_INET_NET_PTON_H /* Copyright (C) 2005-2013 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #ifdef HAVE_INET_NET_PTON #define ares_inet_net_pton(w,x,y,z) inet_net_pton(w,x,y,z) #else int ares_inet_net_pton(int af, const char *src, void *dst, size_t size); #endif #endif /* HEADER_CARES_INET_NET_PTON_H */ node-v4.2.6/deps/cares/src/ares_init.c000644 000766 000024 00000152567 12650222322 017722 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2007-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #if defined(ANDROID) || defined(__ANDROID__) #include /* From the Bionic sources */ #define DNS_PROP_NAME_PREFIX "net.dns" #define MAX_DNS_PROPERTIES 8 #endif #include "ares.h" #include "ares_inet_net_pton.h" #include "ares_library_init.h" #include "ares_nowarn.h" #include "ares_platform.h" #include "ares_private.h" #ifdef WATT32 #undef WIN32 /* Redefined in MingW/MSVC headers */ #endif static int init_by_options(ares_channel channel, const struct ares_options *options, int optmask); static int init_by_environment(ares_channel channel); static int init_by_resolv_conf(ares_channel channel); static int init_by_defaults(ares_channel channel); #ifndef WATT32 static int config_nameserver(struct server_state **servers, int *nservers, char *str); #endif static int set_search(ares_channel channel, const char *str); static int set_options(ares_channel channel, const char *str); static const char *try_option(const char *p, const char *q, const char *opt); static int init_id_key(rc4_key* key,int key_data_len); #if !defined(WIN32) && !defined(WATT32) && \ !defined(ANDROID) && !defined(__ANDROID__) static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat); static int ip_addr(const char *s, ssize_t len, struct in_addr *addr); static void natural_mask(struct apattern *pat); static int config_domain(ares_channel channel, char *str); static int config_lookup(ares_channel channel, const char *str, const char *bindch, const char *filech); static int config_sortlist(struct apattern **sortlist, int *nsort, const char *str); static char *try_config(char *s, const char *opt, char scc); #endif #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \ x->nservers > -1 && \ x->ndomains > -1 && \ x->ndots > -1 && x->timeout > -1 && \ x->tries > -1) int ares_init(ares_channel *channelptr) { return ares_init_options(channelptr, NULL, 0); } int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask) { ares_channel channel; int i; int status = ARES_SUCCESS; struct timeval now; #ifdef CURLDEBUG const char *env = getenv("CARES_MEMDEBUG"); if (env) curl_memdebug(env); env = getenv("CARES_MEMLIMIT"); if (env) { char *endptr; long num = strtol(env, &endptr, 10); if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) curl_memlimit(num); } #endif if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; channel = malloc(sizeof(struct ares_channeldata)); if (!channel) { *channelptr = NULL; return ARES_ENOMEM; } now = ares__tvnow(); /* Set everything to distinguished values so we know they haven't * been set yet. */ channel->flags = -1; channel->timeout = -1; channel->tries = -1; channel->ndots = -1; channel->rotate = -1; channel->udp_port = -1; channel->tcp_port = -1; channel->ednspsz = -1; channel->socket_send_buffer_size = -1; channel->socket_receive_buffer_size = -1; channel->nservers = -1; channel->ndomains = -1; channel->nsort = -1; channel->tcp_connection_generation = 0; channel->lookups = NULL; channel->domains = NULL; channel->sortlist = NULL; channel->servers = NULL; channel->sock_state_cb = NULL; channel->sock_state_cb_data = NULL; channel->sock_create_cb = NULL; channel->sock_create_cb_data = NULL; channel->last_server = 0; channel->last_timeout_processed = (time_t)now.tv_sec; memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name)); channel->local_ip4 = 0; memset(&channel->local_ip6, 0, sizeof(channel->local_ip6)); /* Initialize our lists of queries */ ares__init_list_head(&(channel->all_queries)); for (i = 0; i < ARES_QID_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_qid[i])); } for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++) { ares__init_list_head(&(channel->queries_by_timeout[i])); } /* Initialize configuration by each of the four sources, from highest * precedence to lowest. */ if (status == ARES_SUCCESS) { status = init_by_options(channel, options, optmask); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_environment(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n", ares_strerror(status))); } if (status == ARES_SUCCESS) { status = init_by_resolv_conf(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n", ares_strerror(status))); } /* * No matter what failed or succeeded, seed defaults to provide * useful behavior for things that we missed. */ status = init_by_defaults(channel); if (status != ARES_SUCCESS) DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n", ares_strerror(status))); /* Generate random key */ if (status == ARES_SUCCESS) { status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN); if (status == ARES_SUCCESS) channel->next_id = ares__generate_new_id(&channel->id_key); else DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n", ares_strerror(status))); } if (status != ARES_SUCCESS) { /* Something failed; clean up memory we may have allocated. */ if (channel->servers) free(channel->servers); if (channel->domains) { for (i = 0; i < channel->ndomains; i++) free(channel->domains[i]); free(channel->domains); } if (channel->sortlist) free(channel->sortlist); if(channel->lookups) free(channel->lookups); free(channel); return status; } /* Trim to one server if ARES_FLAG_PRIMARY is set. */ if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) channel->nservers = 1; ares__init_servers_state(channel); *channelptr = channel; return ARES_SUCCESS; } /* ares_dup() duplicates a channel handle with all its options and returns a new channel handle */ int ares_dup(ares_channel *dest, ares_channel src) { struct ares_options opts; struct ares_addr_node *servers; int ipv6_nservers = 0; int i, rc; int optmask; *dest = NULL; /* in case of failure return NULL explicitly */ /* First get the options supported by the old ares_save_options() function, which is most of them */ rc = ares_save_options(src, &opts, &optmask); if(rc) { ares_destroy_options(&opts); return rc; } /* Then create the new channel with those options */ rc = ares_init_options(dest, &opts, optmask); /* destroy the options copy to not leak any memory */ ares_destroy_options(&opts); if(rc) return rc; /* Now clone the options that ares_save_options() doesn't support. */ (*dest)->sock_create_cb = src->sock_create_cb; (*dest)->sock_create_cb_data = src->sock_create_cb_data; strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name)); (*dest)->local_ip4 = src->local_ip4; memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); /* Full name server cloning required when not all are IPv4 */ for (i = 0; i < src->nservers; i++) { if (src->servers[i].addr.family != AF_INET) { ipv6_nservers++; break; } } if (ipv6_nservers) { rc = ares_get_servers(src, &servers); if (rc != ARES_SUCCESS) return rc; rc = ares_set_servers(*dest, servers); ares_free_data(servers); if (rc != ARES_SUCCESS) return rc; } return ARES_SUCCESS; /* everything went fine */ } /* Save options from initialized channel */ int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask) { int i, j; int ipv4_nservers = 0; /* Zero everything out */ memset(options, 0, sizeof(struct ares_options)); if (!ARES_CONFIG_CHECK(channel)) return ARES_ENODATA; /* Traditionally the optmask wasn't saved in the channel struct so it was recreated here. ROTATE is the first option that has no struct field of its own in the public config struct */ (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS| ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB| ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS| ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) | (channel->optmask & ARES_OPT_ROTATE); /* Copy easy stuff */ options->flags = channel->flags; /* We return full millisecond resolution but that's only because we don't set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */ options->timeout = channel->timeout; options->tries = channel->tries; options->ndots = channel->ndots; options->udp_port = ntohs(aresx_sitous(channel->udp_port)); options->tcp_port = ntohs(aresx_sitous(channel->tcp_port)); options->sock_state_cb = channel->sock_state_cb; options->sock_state_cb_data = channel->sock_state_cb_data; /* Copy IPv4 servers */ if (channel->nservers) { for (i = 0; i < channel->nservers; i++) { if (channel->servers[i].addr.family == AF_INET) ipv4_nservers++; } if (ipv4_nservers) { options->servers = malloc(ipv4_nservers * sizeof(struct in_addr)); if (!options->servers) return ARES_ENOMEM; for (i = j = 0; i < channel->nservers; i++) { if (channel->servers[i].addr.family == AF_INET) memcpy(&options->servers[j++], &channel->servers[i].addr.addrV4, sizeof(channel->servers[i].addr.addrV4)); } } } options->nservers = ipv4_nservers; /* copy domains */ if (channel->ndomains) { options->domains = malloc(channel->ndomains * sizeof(char *)); if (!options->domains) return ARES_ENOMEM; for (i = 0; i < channel->ndomains; i++) { options->ndomains = i; options->domains[i] = strdup(channel->domains[i]); if (!options->domains[i]) return ARES_ENOMEM; } } options->ndomains = channel->ndomains; /* copy lookups */ if (channel->lookups) { options->lookups = strdup(channel->lookups); if (!options->lookups && channel->lookups) return ARES_ENOMEM; } /* copy sortlist */ if (channel->nsort) { options->sortlist = malloc(channel->nsort * sizeof(struct apattern)); if (!options->sortlist) return ARES_ENOMEM; for (i = 0; i < channel->nsort; i++) options->sortlist[i] = channel->sortlist[i]; } options->nsort = channel->nsort; return ARES_SUCCESS; } static int init_by_options(ares_channel channel, const struct ares_options *options, int optmask) { int i; /* Easy stuff. */ if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1) channel->flags = options->flags; if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1) channel->timeout = options->timeout; else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1) channel->timeout = options->timeout * 1000; if ((optmask & ARES_OPT_TRIES) && channel->tries == -1) channel->tries = options->tries; if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1) channel->ndots = options->ndots; if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1) channel->rotate = 1; if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1) channel->udp_port = htons(options->udp_port); if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1) channel->tcp_port = htons(options->tcp_port); if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL) { channel->sock_state_cb = options->sock_state_cb; channel->sock_state_cb_data = options->sock_state_cb_data; } if ((optmask & ARES_OPT_SOCK_SNDBUF) && channel->socket_send_buffer_size == -1) channel->socket_send_buffer_size = options->socket_send_buffer_size; if ((optmask & ARES_OPT_SOCK_RCVBUF) && channel->socket_receive_buffer_size == -1) channel->socket_receive_buffer_size = options->socket_receive_buffer_size; if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1) channel->ednspsz = options->ednspsz; /* Copy the IPv4 servers, if given. */ if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1) { /* Avoid zero size allocations at any cost */ if (options->nservers > 0) { channel->servers = malloc(options->nservers * sizeof(struct server_state)); if (!channel->servers) return ARES_ENOMEM; for (i = 0; i < options->nservers; i++) { channel->servers[i].addr.family = AF_INET; memcpy(&channel->servers[i].addr.addrV4, &options->servers[i], sizeof(channel->servers[i].addr.addrV4)); } } channel->nservers = options->nservers; } /* Copy the domains, if given. Keep channel->ndomains consistent so * we can clean up in case of error. */ if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1) { /* Avoid zero size allocations at any cost */ if (options->ndomains > 0) { channel->domains = malloc(options->ndomains * sizeof(char *)); if (!channel->domains) return ARES_ENOMEM; for (i = 0; i < options->ndomains; i++) { channel->ndomains = i; channel->domains[i] = strdup(options->domains[i]); if (!channel->domains[i]) return ARES_ENOMEM; } } channel->ndomains = options->ndomains; } /* Set lookups, if given. */ if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups) { channel->lookups = strdup(options->lookups); if (!channel->lookups) return ARES_ENOMEM; } /* copy sortlist */ if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) && (options->nsort>0)) { channel->sortlist = malloc(options->nsort * sizeof(struct apattern)); if (!channel->sortlist) return ARES_ENOMEM; for (i = 0; i < options->nsort; i++) channel->sortlist[i] = options->sortlist[i]; channel->nsort = options->nsort; } channel->optmask = optmask; return ARES_SUCCESS; } static int init_by_environment(ares_channel channel) { const char *localdomain, *res_options; int status; localdomain = getenv("LOCALDOMAIN"); if (localdomain && channel->ndomains == -1) { status = set_search(channel, localdomain); if (status != ARES_SUCCESS) return status; } res_options = getenv("RES_OPTIONS"); if (res_options) { status = set_options(channel, res_options); if (status != ARES_SUCCESS) return status; } return ARES_SUCCESS; } #ifdef WIN32 /* * get_REG_SZ() * * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer * to the name of the registry leaf key to be queried, fetch it's string * value and return a pointer in *outptr to a newly allocated memory area * holding it as a null-terminated string. * * Returns 0 and nullifies *outptr upon inability to return a string value. * * Returns 1 and sets *outptr when returning a dynamically allocated string. * * Supported on Windows NT 3.5 and newer. */ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) { DWORD size = 0; int res; *outptr = NULL; /* Find out size of string stored in registry */ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; /* Allocate buffer of indicated size plus one given that string might have been stored without null termination */ *outptr = malloc(size+1); if (!*outptr) return 0; /* Get the value for real */ res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { free(*outptr); *outptr = NULL; return 0; } /* Null terminate buffer allways */ *(*outptr + size) = '\0'; return 1; } /* * get_REG_SZ_9X() * * Functionally identical to get_REG_SZ() * * Supported on Windows 95, 98 and ME. */ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) { DWORD dataType = 0; DWORD size = 0; int res; *outptr = NULL; /* Find out size of string stored in registry */ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; /* Allocate buffer of indicated size plus one given that string might have been stored without null termination */ *outptr = malloc(size+1); if (!*outptr) return 0; /* Get the value for real */ res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { free(*outptr); *outptr = NULL; return 0; } /* Null terminate buffer allways */ *(*outptr + size) = '\0'; return 1; } /* * get_enum_REG_SZ() * * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName' * pointer to the name of the registry leaf key to be queried, parent key * is enumerated searching in child keys for given leaf key name and its * associated string value. When located, this returns a pointer in *outptr * to a newly allocated memory area holding it as a null-terminated string. * * Returns 0 and nullifies *outptr upon inability to return a string value. * * Returns 1 and sets *outptr when returning a dynamically allocated string. * * Supported on Windows NT 3.5 and newer. */ static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName, char **outptr) { char enumKeyName[256]; DWORD enumKeyNameBuffSize; DWORD enumKeyIdx = 0; HKEY hKeyEnum; int gotString; int res; *outptr = NULL; for(;;) { enumKeyNameBuffSize = sizeof(enumKeyName); res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName, &enumKeyNameBuffSize, 0, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE, &hKeyEnum); if (res != ERROR_SUCCESS) continue; gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr); RegCloseKey(hKeyEnum); if (gotString) break; } if (!*outptr) return 0; return 1; } /* * get_DNS_Registry_9X() * * Functionally identical to get_DNS_Registry() * * Implementation supports Windows 95, 98 and ME. */ static int get_DNS_Registry_9X(char **outptr) { HKEY hKey_VxD_MStcp; int gotString; int res; *outptr = NULL; res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, &hKey_VxD_MStcp); if (res != ERROR_SUCCESS) return 0; gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr); RegCloseKey(hKey_VxD_MStcp); if (!gotString || !*outptr) return 0; return 1; } /* * get_DNS_Registry_NT() * * Functionally identical to get_DNS_Registry() * * Refs: Microsoft Knowledge Base articles KB120642 and KB314053. * * Implementation supports Windows NT 3.5 and newer. */ static int get_DNS_Registry_NT(char **outptr) { HKEY hKey_Interfaces = NULL; HKEY hKey_Tcpip_Parameters; int gotString; int res; *outptr = NULL; res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hKey_Tcpip_Parameters); if (res != ERROR_SUCCESS) return 0; /* ** Global DNS settings override adapter specific parameters when both ** are set. Additionally static DNS settings override DHCP-configured ** parameters when both are set. */ /* Global DNS static parameters */ gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr); if (gotString) goto done; /* Global DNS DHCP-configured parameters */ gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr); if (gotString) goto done; /* Try adapter specific parameters */ res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey_Interfaces); if (res != ERROR_SUCCESS) { hKey_Interfaces = NULL; goto done; } /* Adapter specific DNS static parameters */ gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr); if (gotString) goto done; /* Adapter specific DNS DHCP-configured parameters */ gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr); done: if (hKey_Interfaces) RegCloseKey(hKey_Interfaces); RegCloseKey(hKey_Tcpip_Parameters); if (!gotString || !*outptr) return 0; return 1; } /* * get_DNS_Registry() * * Locates DNS info in the registry. When located, this returns a pointer * in *outptr to a newly allocated memory area holding a null-terminated * string with a space or comma seperated list of DNS IP addresses. * * Returns 0 and nullifies *outptr upon inability to return DNSes string. * * Returns 1 and sets *outptr when returning a dynamically allocated string. */ static int get_DNS_Registry(char **outptr) { win_platform platform; int gotString = 0; *outptr = NULL; platform = ares__getplatform(); if (platform == WIN_NT) gotString = get_DNS_Registry_NT(outptr); else if (platform == WIN_9X) gotString = get_DNS_Registry_9X(outptr); if (!gotString) return 0; return 1; } /* * commajoin() * * RTF code. */ static void commajoin(char **dst, const char *src) { char *tmp; if (*dst) { tmp = malloc(strlen(*dst) + strlen(src) + 2); if (!tmp) return; sprintf(tmp, "%s,%s", *dst, src); free(*dst); *dst = tmp; } else { *dst = malloc(strlen(src) + 1); if (!*dst) return; strcpy(*dst, src); } } /* * get_DNS_NetworkParams() * * Locates DNS info using GetNetworkParams() function from the Internet * Protocol Helper (IP Helper) API. When located, this returns a pointer * in *outptr to a newly allocated memory area holding a null-terminated * string with a space or comma seperated list of DNS IP addresses. * * Returns 0 and nullifies *outptr upon inability to return DNSes string. * * Returns 1 and sets *outptr when returning a dynamically allocated string. * * Implementation supports Windows 98 and newer. * * Note: Ancient PSDK required in order to build a W98 target. */ static int get_DNS_NetworkParams(char **outptr) { FIXED_INFO *fi, *newfi; struct ares_addr namesrvr; char *txtaddr; IP_ADDR_STRING *ipAddr; int res; DWORD size = sizeof (*fi); *outptr = NULL; /* Verify run-time availability of GetNetworkParams() */ if (ares_fpGetNetworkParams == ZERO_NULL) return 0; fi = malloc(size); if (!fi) return 0; res = (*ares_fpGetNetworkParams) (fi, &size); if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) goto done; newfi = realloc(fi, size); if (!newfi) goto done; fi = newfi; res = (*ares_fpGetNetworkParams) (fi, &size); if (res != ERROR_SUCCESS) goto done; for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next) { txtaddr = &ipAddr->IpAddress.String[0]; /* Validate converting textual address to binary format. */ if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1) { if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) || (namesrvr.addrV4.S_un.S_addr == INADDR_NONE)) continue; } else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1) { if (memcmp(&namesrvr.addrV6, &ares_in6addr_any, sizeof(namesrvr.addrV6)) == 0) continue; } else continue; commajoin(outptr, txtaddr); if (!*outptr) break; } done: if (fi) free(fi); if (!*outptr) return 0; return 1; } /* * get_DNS_AdaptersAddresses() * * Locates DNS info using GetAdaptersAddresses() function from the Internet * Protocol Helper (IP Helper) API. When located, this returns a pointer * in *outptr to a newly allocated memory area holding a null-terminated * string with a space or comma seperated list of DNS IP addresses. * * Returns 0 and nullifies *outptr upon inability to return DNSes string. * * Returns 1 and sets *outptr when returning a dynamically allocated string. * * Implementation supports Windows XP and newer. */ #define IPAA_INITIAL_BUF_SZ 15 * 1024 #define IPAA_MAX_TRIES 3 static int get_DNS_AdaptersAddresses(char **outptr) { IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr; IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry; ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ; ULONG Bufsz = IPAA_INITIAL_BUF_SZ; ULONG AddrFlags = 0; int trying = IPAA_MAX_TRIES; int res; union { struct sockaddr *sa; struct sockaddr_in *sa4; struct sockaddr_in6 *sa6; } namesrvr; char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; *outptr = NULL; /* Verify run-time availability of GetAdaptersAddresses() */ if (ares_fpGetAdaptersAddresses == ZERO_NULL) return 0; ipaa = malloc(Bufsz); if (!ipaa) return 0; /* Usually this call suceeds with initial buffer size */ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz); if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS)) goto done; while ((res == ERROR_BUFFER_OVERFLOW) && (--trying)) { if (Bufsz < ReqBufsz) { newipaa = realloc(ipaa, ReqBufsz); if (!newipaa) goto done; Bufsz = ReqBufsz; ipaa = newipaa; } res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz); if (res == ERROR_SUCCESS) break; } if (res != ERROR_SUCCESS) goto done; for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next) { for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress; ipaDNSAddr; ipaDNSAddr = ipaDNSAddr->Next) { namesrvr.sa = ipaDNSAddr->Address.lpSockaddr; if (namesrvr.sa->sa_family == AF_INET) { if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) || (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE)) continue; if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr, txtaddr, sizeof(txtaddr))) continue; } else if (namesrvr.sa->sa_family == AF_INET6) { /* Windows apparently always reports some IPv6 DNS servers that * prefixed with fec0:0:0:ffff. These ususally do not point to * working DNS servers, so we ignore them. */ if (strncmp(txtaddr, "fec0:0:0:ffff:", 14) == 0) continue; if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any, sizeof(namesrvr.sa6->sin6_addr)) == 0) continue; if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr, txtaddr, sizeof(txtaddr))) continue; } else continue; commajoin(outptr, txtaddr); if (!*outptr) goto done; } } done: if (ipaa) free(ipaa); if (!*outptr) return 0; return 1; } /* * get_DNS_Windows() * * Locates DNS info from Windows employing most suitable methods available at * run-time no matter which Windows version it is. When located, this returns * a pointer in *outptr to a newly allocated memory area holding a string with * a space or comma seperated list of DNS IP addresses, null-terminated. * * Returns 0 and nullifies *outptr upon inability to return DNSes string. * * Returns 1 and sets *outptr when returning a dynamically allocated string. * * Implementation supports Windows 95 and newer. */ static int get_DNS_Windows(char **outptr) { /* Try using IP helper API GetAdaptersAddresses() */ if (get_DNS_AdaptersAddresses(outptr)) return 1; /* Try using IP helper API GetNetworkParams() */ if (get_DNS_NetworkParams(outptr)) return 1; /* Fall-back to registry information */ return get_DNS_Registry(outptr); } #endif static int init_by_resolv_conf(ares_channel channel) { #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) char *line = NULL; #endif int status = -1, nservers = 0, nsort = 0; struct server_state *servers = NULL; struct apattern *sortlist = NULL; #ifdef WIN32 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */ return ARES_SUCCESS; if (get_DNS_Windows(&line)) { status = config_nameserver(&servers, &nservers, line); free(line); } if (status == ARES_SUCCESS) status = ARES_EOF; else /* Catch the case when all the above checks fail (which happens when there is no network card or the cable is unplugged) */ status = ARES_EFILE; #elif defined(__riscos__) /* Under RISC OS, name servers are listed in the system variable Inet$Resolvers, space separated. */ line = getenv("Inet$Resolvers"); status = ARES_EOF; if (line) { char *resolvers = strdup(line), *pos, *space; if (!resolvers) return ARES_ENOMEM; pos = resolvers; do { space = strchr(pos, ' '); if (space) *space = '\0'; status = config_nameserver(&servers, &nservers, pos); if (status != ARES_SUCCESS) break; pos = space + 1; } while (space); if (status == ARES_SUCCESS) status = ARES_EOF; free(resolvers); } #elif defined(WATT32) int i; sock_init(); for (i = 0; def_nameservers[i]; i++) ; if (i == 0) return ARES_SUCCESS; /* use localhost DNS server */ nservers = i; servers = calloc(i, sizeof(struct server_state)); if (!servers) return ARES_ENOMEM; for (i = 0; def_nameservers[i]; i++) { servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]); servers[i].addr.family = AF_INET; } status = ARES_EOF; #elif defined(ANDROID) || defined(__ANDROID__) unsigned int i; char propname[PROP_NAME_MAX]; char propvalue[PROP_VALUE_MAX]=""; for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); if (__system_property_get(propname, propvalue) < 1) { status = ARES_EOF; break; } status = config_nameserver(&servers, &nservers, propvalue); if (status != ARES_SUCCESS) break; status = ARES_EOF; } #else { char *p; FILE *fp; size_t linesize; int error; int update_domains; /* Don't read resolv.conf and friends if we don't have to */ if (ARES_CONFIG_CHECK(channel)) return ARES_SUCCESS; /* Only update search domains if they're not already specified */ update_domains = (channel->ndomains == -1); fp = fopen(PATH_RESOLV_CONF, "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "domain", ';')) && update_domains) status = config_domain(channel, p); else if ((p = try_config(line, "lookup", ';')) && !channel->lookups) status = config_lookup(channel, p, "bind", "file"); else if ((p = try_config(line, "search", ';')) && update_domains) status = set_search(channel, p); else if ((p = try_config(line, "nameserver", ';')) && channel->nservers == -1) status = config_nameserver(&servers, &nservers, p); else if ((p = try_config(line, "sortlist", ';')) && channel->nsort == -1) status = config_sortlist(&sortlist, &nsort, p); else if ((p = try_config(line, "options", ';'))) status = set_options(channel, p); else status = ARES_SUCCESS; if (status != ARES_SUCCESS) break; } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF)); status = ARES_EFILE; } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */ fp = fopen("/etc/nsswitch.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "dns", "files"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf")); status = ARES_EFILE; } } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Linux / GNU libc 2.x and possibly others have host.conf */ fp = fopen("/etc/host.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "order", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "bind", "hosts"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf")); status = ARES_EFILE; } } } if ((status == ARES_EOF) && (!channel->lookups)) { /* Tru64 uses /etc/svc.conf */ fp = fopen("/etc/svc.conf", "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups) /* ignore errors */ (void)config_lookup(channel, p, "bind", "local"); } fclose(fp); } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: status = ARES_EOF; break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf")); status = ARES_EFILE; } } } if(line) free(line); } #endif /* Handle errors. */ if (status != ARES_EOF) { if (servers != NULL) free(servers); if (sortlist != NULL) free(sortlist); return status; } /* If we got any name server entries, fill them in. */ if (servers) { channel->servers = servers; channel->nservers = nservers; } /* If we got any sortlist entries, fill them in. */ if (sortlist) { channel->sortlist = sortlist; channel->nsort = nsort; } return ARES_SUCCESS; } static int init_by_defaults(ares_channel channel) { char *hostname = NULL; int rc = ARES_SUCCESS; #ifdef HAVE_GETHOSTNAME char *dot; #endif if (channel->flags == -1) channel->flags = 0; if (channel->timeout == -1) channel->timeout = DEFAULT_TIMEOUT; if (channel->tries == -1) channel->tries = DEFAULT_TRIES; if (channel->ndots == -1) channel->ndots = 1; if (channel->rotate == -1) channel->rotate = 0; if (channel->udp_port == -1) channel->udp_port = htons(NAMESERVER_PORT); if (channel->tcp_port == -1) channel->tcp_port = htons(NAMESERVER_PORT); if (channel->ednspsz == -1) channel->ednspsz = EDNSPACKETSZ; if (channel->nservers == -1) { /* If nobody specified servers, try a local named. */ channel->servers = malloc(sizeof(struct server_state)); if (!channel->servers) { rc = ARES_ENOMEM; goto error; } channel->servers[0].addr.family = AF_INET; channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK); channel->nservers = 1; } #if defined(USE_WINSOCK) #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT) #elif defined(ENAMETOOLONG) #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \ (SOCKERRNO == EINVAL)) #else #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL) #endif if (channel->ndomains == -1) { /* Derive a default domain search list from the kernel hostname, * or set it to empty if the hostname isn't helpful. */ #ifndef HAVE_GETHOSTNAME channel->ndomains = 0; /* default to none */ #else GETHOSTNAME_TYPE_ARG2 lenv = 64; size_t len = 64; int res; channel->ndomains = 0; /* default to none */ hostname = malloc(len); if(!hostname) { rc = ARES_ENOMEM; goto error; } do { res = gethostname(hostname, lenv); if(toolong(res)) { char *p; len *= 2; lenv *= 2; p = realloc(hostname, len); if(!p) { rc = ARES_ENOMEM; goto error; } hostname = p; continue; } else if(res) { rc = ARES_EBADNAME; goto error; } } while (res != 0); dot = strchr(hostname, '.'); if (dot) { /* a dot was found */ channel->domains = malloc(sizeof(char *)); if (!channel->domains) { rc = ARES_ENOMEM; goto error; } channel->domains[0] = strdup(dot + 1); if (!channel->domains[0]) { rc = ARES_ENOMEM; goto error; } channel->ndomains = 1; } #endif } if (channel->nsort == -1) { channel->sortlist = NULL; channel->nsort = 0; } if (!channel->lookups) { channel->lookups = strdup("fb"); if (!channel->lookups) rc = ARES_ENOMEM; } error: if(rc) { if(channel->servers) { free(channel->servers); channel->servers = NULL; } if(channel->domains && channel->domains[0]) free(channel->domains[0]); if(channel->domains) { free(channel->domains); channel->domains = NULL; } if(channel->lookups) { free(channel->lookups); channel->lookups = NULL; } } if(hostname) free(hostname); return rc; } #if !defined(WIN32) && !defined(WATT32) && \ !defined(ANDROID) && !defined(__ANDROID__) static int config_domain(ares_channel channel, char *str) { char *q; /* Set a single search domain. */ q = str; while (*q && !ISSPACE(*q)) q++; *q = '\0'; return set_search(channel, str); } #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \ defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) /* workaround icc 9.1 optimizer issue */ # define vqualifier volatile #else # define vqualifier #endif static int config_lookup(ares_channel channel, const char *str, const char *bindch, const char *filech) { char lookups[3], *l; const char *vqualifier p; /* Set the lookup order. Only the first letter of each work * is relevant, and it has to be "b" for DNS or "f" for the * host file. Ignore everything else. */ l = lookups; p = str; while (*p) { if ((*p == *bindch || *p == *filech) && l < lookups + 2) { if (*p == *bindch) *l++ = 'b'; else *l++ = 'f'; } while (*p && !ISSPACE(*p) && (*p != ',')) p++; while (*p && (ISSPACE(*p) || (*p == ','))) p++; } *l = '\0'; channel->lookups = strdup(lookups); return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; } #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ #ifndef WATT32 static int config_nameserver(struct server_state **servers, int *nservers, char *str) { struct ares_addr host; struct server_state *newserv; char *p, *txtaddr; /* On Windows, there may be more than one nameserver specified in the same * registry key, so we parse input as a space or comma seperated list. */ for (p = str; p;) { /* Skip whitespace and commas. */ while (*p && (ISSPACE(*p) || (*p == ','))) p++; if (!*p) /* No more input, done. */ break; /* Pointer to start of IPv4 or IPv6 address part. */ txtaddr = p; /* Advance past this address. */ while (*p && !ISSPACE(*p) && (*p != ',')) p++; if (*p) /* Null terminate this address. */ *p++ = '\0'; else /* Reached end of input, done when this address is processed. */ p = NULL; /* Convert textual address to binary format. */ if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1) host.family = AF_INET; else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1) host.family = AF_INET6; else continue; /* Resize servers state array. */ newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state)); if (!newserv) return ARES_ENOMEM; /* Store address data. */ newserv[*nservers].addr.family = host.family; if (host.family == AF_INET) memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4, sizeof(host.addrV4)); else memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6, sizeof(host.addrV6)); /* Update arguments. */ *servers = newserv; *nservers += 1; } return ARES_SUCCESS; } #if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__) static int config_sortlist(struct apattern **sortlist, int *nsort, const char *str) { struct apattern pat; const char *q; /* Add sortlist entries. */ while (*str && *str != ';') { int bits; char ipbuf[16], ipbufpfx[32]; /* Find just the IP */ q = str; while (*q && *q != '/' && *q != ';' && !ISSPACE(*q)) q++; memcpy(ipbuf, str, q-str); ipbuf[q-str] = '\0'; /* Find the prefix */ if (*q == '/') { const char *str2 = q+1; while (*q && *q != ';' && !ISSPACE(*q)) q++; memcpy(ipbufpfx, str, q-str); ipbufpfx[q-str] = '\0'; str = str2; } else ipbufpfx[0] = '\0'; /* Lets see if it is CIDR */ /* First we'll try IPv6 */ if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf, &pat.addrV6, sizeof(pat.addrV6))) > 0) { pat.type = PATTERN_CIDR; pat.mask.bits = (unsigned short)bits; pat.family = AF_INET6; if (!sortlist_alloc(sortlist, nsort, &pat)) return ARES_ENOMEM; } else if (ipbufpfx[0] && (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4, sizeof(pat.addrV4))) > 0) { pat.type = PATTERN_CIDR; pat.mask.bits = (unsigned short)bits; pat.family = AF_INET; if (!sortlist_alloc(sortlist, nsort, &pat)) return ARES_ENOMEM; } /* See if it is just a regular IP */ else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0) { if (ipbufpfx[0]) { memcpy(ipbuf, str, q-str); ipbuf[q-str] = '\0'; if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0) natural_mask(&pat); } else natural_mask(&pat); pat.family = AF_INET; pat.type = PATTERN_MASK; if (!sortlist_alloc(sortlist, nsort, &pat)) return ARES_ENOMEM; } else { while (*q && *q != ';' && !ISSPACE(*q)) q++; } str = q; while (ISSPACE(*str)) str++; } return ARES_SUCCESS; } #endif /* !WIN32 & !ANDROID & !__ANDROID__ */ #endif /* !WATT32 */ static int set_search(ares_channel channel, const char *str) { int n; const char *p, *q; if(channel->ndomains != -1) { /* if we already have some domains present, free them first */ for(n=0; n < channel->ndomains; n++) free(channel->domains[n]); free(channel->domains); channel->domains = NULL; channel->ndomains = -1; } /* Count the domains given. */ n = 0; p = str; while (*p) { while (*p && !ISSPACE(*p)) p++; while (ISSPACE(*p)) p++; n++; } if (!n) { channel->ndomains = 0; return ARES_SUCCESS; } channel->domains = malloc(n * sizeof(char *)); if (!channel->domains) return ARES_ENOMEM; /* Now copy the domains. */ n = 0; p = str; while (*p) { channel->ndomains = n; q = p; while (*q && !ISSPACE(*q)) q++; channel->domains[n] = malloc(q - p + 1); if (!channel->domains[n]) return ARES_ENOMEM; memcpy(channel->domains[n], p, q - p); channel->domains[n][q - p] = 0; p = q; while (ISSPACE(*p)) p++; n++; } channel->ndomains = n; return ARES_SUCCESS; } static int set_options(ares_channel channel, const char *str) { const char *p, *q, *val; p = str; while (*p) { q = p; while (*q && !ISSPACE(*q)) q++; val = try_option(p, q, "ndots:"); if (val && channel->ndots == -1) channel->ndots = aresx_sltosi(strtol(val, NULL, 10)); val = try_option(p, q, "retrans:"); if (val && channel->timeout == -1) channel->timeout = aresx_sltosi(strtol(val, NULL, 10)); val = try_option(p, q, "retry:"); if (val && channel->tries == -1) channel->tries = aresx_sltosi(strtol(val, NULL, 10)); val = try_option(p, q, "rotate"); if (val && channel->rotate == -1) channel->rotate = 1; p = q; while (ISSPACE(*p)) p++; } return ARES_SUCCESS; } static const char *try_option(const char *p, const char *q, const char *opt) { size_t len = strlen(opt); return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL; } #if !defined(WIN32) && !defined(WATT32) && \ !defined(ANDROID) && !defined(__ANDROID__) static char *try_config(char *s, const char *opt, char scc) { size_t len; char *p; char *q; if (!s || !opt) /* no line or no option */ return NULL; /* Hash '#' character is always used as primary comment char, additionally a not-NUL secondary comment char will be considered when specified. */ /* trim line comment */ p = s; if(scc) while (*p && (*p != '#') && (*p != scc)) p++; else while (*p && (*p != '#')) p++; *p = '\0'; /* trim trailing whitespace */ q = p - 1; while ((q >= s) && ISSPACE(*q)) q--; *++q = '\0'; /* skip leading whitespace */ p = s; while (*p && ISSPACE(*p)) p++; if (!*p) /* empty line */ return NULL; if ((len = strlen(opt)) == 0) /* empty option */ return NULL; if (strncmp(p, opt, len) != 0) /* line and option do not match */ return NULL; /* skip over given option name */ p += len; if (!*p) /* no option value */ return NULL; if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p)) /* whitespace between option name and value is mandatory for given option names which do not end with ':' or '=' */ return NULL; /* skip over whitespace */ while (*p && ISSPACE(*p)) p++; if (!*p) /* no option value */ return NULL; /* return pointer to option value */ return p; } static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat) { struct apattern *newsort; newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern)); if (!newsort) return 0; newsort[*nsort] = *pat; *sortlist = newsort; (*nsort)++; return 1; } static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr) { /* Four octets and three periods yields at most 15 characters. */ if (len > 15) return -1; addr->s_addr = inet_addr(ipbuf); if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0) return -1; return 0; } static void natural_mask(struct apattern *pat) { struct in_addr addr; /* Store a host-byte-order copy of pat in a struct in_addr. Icky, * but portable. */ addr.s_addr = ntohl(pat->addrV4.s_addr); /* This is out of date in the CIDR world, but some people might * still rely on it. */ if (IN_CLASSA(addr.s_addr)) pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET); else if (IN_CLASSB(addr.s_addr)) pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET); else pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET); } #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ /* initialize an rc4 key. If possible a cryptographically secure random key is generated using a suitable function (for example win32's RtlGenRandom as described in http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx otherwise the code defaults to cross-platform albeit less secure mechanism using rand */ static void randomize_key(unsigned char* key,int key_data_len) { int randomized = 0; int counter=0; #ifdef WIN32 BOOLEAN res; if (ares_fpSystemFunction036) { res = (*ares_fpSystemFunction036) (key, key_data_len); if (res) randomized = 1; } #else /* !WIN32 */ #ifdef RANDOM_FILE FILE *f = fopen(RANDOM_FILE, "rb"); if(f) { counter = aresx_uztosi(fread(key, 1, key_data_len, f)); fclose(f); } #endif #endif /* WIN32 */ if (!randomized) { for (;counterstate[0]; for(counter = 0; counter < 256; counter++) /* unnecessary AND but it keeps some compilers happier */ state[counter] = (unsigned char)(counter & 0xff); randomize_key(key->state,key_data_len); key->x = 0; key->y = 0; index1 = 0; index2 = 0; for(counter = 0; counter < 256; counter++) { index2 = (unsigned char)((key_data_ptr[index1] + state[counter] + index2) % 256); ARES_SWAP_BYTE(&state[counter], &state[index2]); index1 = (unsigned char)((index1 + 1) % key_data_len); } free(key_data_ptr); return ARES_SUCCESS; } void ares_set_local_ip4(ares_channel channel, unsigned int local_ip) { channel->local_ip4 = local_ip; } /* local_ip6 should be 16 bytes in length */ void ares_set_local_ip6(ares_channel channel, const unsigned char* local_ip6) { memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6)); } /* local_dev_name should be null terminated. */ void ares_set_local_dev(ares_channel channel, const char* local_dev_name) { strncpy(channel->local_dev_name, local_dev_name, sizeof(channel->local_dev_name)); channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0; } void ares_set_socket_callback(ares_channel channel, ares_sock_create_callback cb, void *data) { channel->sock_create_cb = cb; channel->sock_create_cb_data = data; } void ares__init_servers_state(ares_channel channel) { struct server_state *server; int i; for (i = 0; i < channel->nservers; i++) { server = &channel->servers[i]; server->udp_socket = ARES_SOCKET_BAD; server->tcp_socket = ARES_SOCKET_BAD; server->tcp_connection_generation = ++channel->tcp_connection_generation; server->tcp_lenbuf_pos = 0; server->tcp_buffer_pos = 0; server->tcp_buffer = NULL; server->tcp_length = 0; server->qhead = NULL; server->qtail = NULL; ares__init_list_head(&server->queries_to_server); server->channel = channel; server->is_broken = 0; } } node-v4.2.6/deps/cares/src/ares_iphlpapi.h000644 000766 000024 00000013466 12650222322 020564 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_IPHLPAPI_H #define HEADER_CARES_IPHLPAPI_H /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004 - 2011 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #if defined(USE_WINSOCK) #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 22 #endif #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 65 #endif /* ---------------------------------- */ #if !defined(_WS2DEF_) && \ !defined(__CSADDR_DEFINED__) && \ !defined(__CSADDR_T_DEFINED) /* ---------------------------------- */ typedef struct _SOCKET_ADDRESS { LPSOCKADDR lpSockaddr; INT iSockaddrLength; } SOCKET_ADDRESS, *PSOCKET_ADDRESS; typedef struct _CSADDR_INFO { SOCKET_ADDRESS LocalAddr; SOCKET_ADDRESS RemoteAddr; INT iSocketType; INT iProtocol; } CSADDR_INFO, *PCSADDR_INFO; /* --------------------------------- */ #endif /* ! _WS2DEF_ && \ */ /* ! __CSADDR_DEFINED__ && \ */ /* ! __CSADDR_T_DEFINED */ /* --------------------------------- */ /* ------------------------------- */ #if !defined(IP_ADAPTER_DDNS_ENABLED) /* ------------------------------- */ #define IP_ADAPTER_ADDRESS_DNS_ELIGIBLE 0x0001 #define IP_ADAPTER_ADDRESS_TRANSIENT 0x0002 #define IP_ADAPTER_DDNS_ENABLED 0x0001 #define IP_ADAPTER_REGISTER_ADAPTER_SUFFIX 0x0002 #define IP_ADAPTER_DHCP_ENABLED 0x0004 #define IP_ADAPTER_RECEIVE_ONLY 0x0008 #define IP_ADAPTER_NO_MULTICAST 0x0010 #define IP_ADAPTER_IPV6_OTHER_STATEFUL_CONFIG 0x0020 #define GAA_FLAG_SKIP_UNICAST 0x0001 #define GAA_FLAG_SKIP_ANYCAST 0x0002 #define GAA_FLAG_SKIP_MULTICAST 0x0004 #define GAA_FLAG_SKIP_DNS_SERVER 0x0008 #define GAA_FLAG_INCLUDE_PREFIX 0x0010 #define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020 typedef enum { IpPrefixOriginOther = 0, IpPrefixOriginManual, IpPrefixOriginWellKnown, IpPrefixOriginDhcp, IpPrefixOriginRouterAdvertisement } IP_PREFIX_ORIGIN; typedef enum { IpSuffixOriginOther = 0, IpSuffixOriginManual, IpSuffixOriginWellKnown, IpSuffixOriginDhcp, IpSuffixOriginLinkLayerAddress, IpSuffixOriginRandom } IP_SUFFIX_ORIGIN; typedef enum { IpDadStateInvalid = 0, IpDadStateTentative, IpDadStateDuplicate, IpDadStateDeprecated, IpDadStatePreferred } IP_DAD_STATE; typedef enum { IfOperStatusUp = 1, IfOperStatusDown, IfOperStatusTesting, IfOperStatusUnknown, IfOperStatusDormant, IfOperStatusNotPresent, IfOperStatusLowerLayerDown } IF_OPER_STATUS; typedef enum { ScopeLevelInterface = 0x0001, ScopeLevelLink = 0x0002, ScopeLevelSubnet = 0x0003, ScopeLevelAdmin = 0x0004, ScopeLevelSite = 0x0005, ScopeLevelOrganization = 0x0008, ScopeLevelGlobal = 0x000E } SCOPE_LEVEL; typedef struct _IP_ADAPTER_UNICAST_ADDRESS { union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } s; } u; struct _IP_ADAPTER_UNICAST_ADDRESS *Next; SOCKET_ADDRESS Address; IP_PREFIX_ORIGIN PrefixOrigin; IP_SUFFIX_ORIGIN SuffixOrigin; IP_DAD_STATE DadState; ULONG ValidLifetime; ULONG PreferredLifetime; ULONG LeaseLifetime; } IP_ADAPTER_UNICAST_ADDRESS, *PIP_ADAPTER_UNICAST_ADDRESS; typedef struct _IP_ADAPTER_ANYCAST_ADDRESS { union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } s; } u; struct _IP_ADAPTER_ANYCAST_ADDRESS *Next; SOCKET_ADDRESS Address; } IP_ADAPTER_ANYCAST_ADDRESS, *PIP_ADAPTER_ANYCAST_ADDRESS; typedef struct _IP_ADAPTER_MULTICAST_ADDRESS { union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } s; } u; struct _IP_ADAPTER_MULTICAST_ADDRESS *Next; SOCKET_ADDRESS Address; } IP_ADAPTER_MULTICAST_ADDRESS, *PIP_ADAPTER_MULTICAST_ADDRESS; typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS { union { ULONGLONG Alignment; struct { ULONG Length; DWORD Reserved; } s; } u; struct _IP_ADAPTER_DNS_SERVER_ADDRESS *Next; SOCKET_ADDRESS Address; } IP_ADAPTER_DNS_SERVER_ADDRESS, *PIP_ADAPTER_DNS_SERVER_ADDRESS; typedef struct _IP_ADAPTER_PREFIX { union { ULONGLONG Alignment; struct { ULONG Length; DWORD Flags; } s; } u; struct _IP_ADAPTER_PREFIX *Next; SOCKET_ADDRESS Address; ULONG PrefixLength; } IP_ADAPTER_PREFIX, *PIP_ADAPTER_PREFIX; typedef struct _IP_ADAPTER_ADDRESSES { union { ULONGLONG Alignment; struct { ULONG Length; DWORD IfIndex; } s; } u; struct _IP_ADAPTER_ADDRESSES *Next; PCHAR AdapterName; PIP_ADAPTER_UNICAST_ADDRESS FirstUnicastAddress; PIP_ADAPTER_ANYCAST_ADDRESS FirstAnycastAddress; PIP_ADAPTER_MULTICAST_ADDRESS FirstMulticastAddress; PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress; PWCHAR DnsSuffix; PWCHAR Description; PWCHAR FriendlyName; BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH]; DWORD PhysicalAddressLength; DWORD Flags; DWORD Mtu; DWORD IfType; IF_OPER_STATUS OperStatus; DWORD Ipv6IfIndex; DWORD ZoneIndices[16]; PIP_ADAPTER_PREFIX FirstPrefix; } IP_ADAPTER_ADDRESSES, *PIP_ADAPTER_ADDRESSES; /* -------------------------------- */ #endif /* ! IP_ADAPTER_DDNS_ENABLED */ /* -------------------------------- */ #endif /* USE_WINSOCK */ #endif /* HEADER_CARES_IPHLPAPI_H */ node-v4.2.6/deps/cares/src/ares_ipv6.h000644 000766 000024 00000003636 12650222322 017640 0ustar00iojsstaff000000 000000 /* Copyright (C) 2005 by Dominick Meglio * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #ifndef ARES_IPV6_H #define ARES_IPV6_H #ifndef HAVE_PF_INET6 #define PF_INET6 AF_INET6 #endif #ifndef HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned long sin6_flowinfo; struct ares_in6_addr sin6_addr; unsigned int sin6_scope_id; }; #endif #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; ares_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */ char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next; }; #endif #ifndef NS_IN6ADDRSZ #if SIZEOF_STRUCT_IN6_ADDR == 0 /* We cannot have it set to zero, so we pick a fixed value here */ #define NS_IN6ADDRSZ 16 #else #define NS_IN6ADDRSZ SIZEOF_STRUCT_IN6_ADDR #endif #endif #ifndef NS_INADDRSZ #define NS_INADDRSZ SIZEOF_STRUCT_IN_ADDR #endif #ifndef NS_INT16SZ #define NS_INT16SZ 2 #endif #ifndef IF_NAMESIZE #ifdef IFNAMSIZ #define IF_NAMESIZE IFNAMSIZ #else #define IF_NAMESIZE 256 #endif #endif /* Defined in inet_net_pton.c for no particular reason. */ extern const struct ares_in6_addr ares_in6addr_any; /* :: */ #endif /* ARES_IPV6_H */ node-v4.2.6/deps/cares/src/ares_library_init.c000644 000766 000024 00000006654 12650222322 021441 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004-2009 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_library_init.h" #include "ares_private.h" /* library-private global and unique instance vars */ #ifdef USE_WINSOCK fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL; fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL; fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL; #endif /* library-private global vars with source visibility restricted to this file */ static unsigned int ares_initialized; static int ares_init_flags; #ifdef USE_WINSOCK static HMODULE hnd_iphlpapi; static HMODULE hnd_advapi32; #endif static int ares_win32_init(void) { #ifdef USE_WINSOCK hnd_iphlpapi = 0; hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll"); if (!hnd_iphlpapi) return ARES_ELOADIPHLPAPI; ares_fpGetNetworkParams = (fpGetNetworkParams_t) GetProcAddress(hnd_iphlpapi, "GetNetworkParams"); if (!ares_fpGetNetworkParams) { FreeLibrary(hnd_iphlpapi); return ARES_EADDRGETNETWORKPARAMS; } ares_fpGetAdaptersAddresses = (fpGetAdaptersAddresses_t) GetProcAddress(hnd_iphlpapi, "GetAdaptersAddresses"); if (!ares_fpGetAdaptersAddresses) { /* This can happen on clients before WinXP, I don't think it should be an error, unless we don't want to support Windows 2000 anymore */ } /* * When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036, * also known as RtlGenRandom, which is the case for Windows versions prior * to WinXP then c-ares uses portable rand() function. Then don't error here. */ hnd_advapi32 = 0; hnd_advapi32 = LoadLibraryW(L"advapi32.dll"); if (hnd_advapi32) { ares_fpSystemFunction036 = (fpSystemFunction036_t) GetProcAddress(hnd_advapi32, "SystemFunction036"); } #endif return ARES_SUCCESS; } static void ares_win32_cleanup(void) { #ifdef USE_WINSOCK if (hnd_advapi32) FreeLibrary(hnd_advapi32); if (hnd_iphlpapi) FreeLibrary(hnd_iphlpapi); #endif } int ares_library_init(int flags) { int res; if (ares_initialized) { ares_initialized++; return ARES_SUCCESS; } ares_initialized++; if (flags & ARES_LIB_INIT_WIN32) { res = ares_win32_init(); if (res != ARES_SUCCESS) return res; } ares_init_flags = flags; return ARES_SUCCESS; } void ares_library_cleanup(void) { if (!ares_initialized) return; ares_initialized--; if (ares_initialized) return; if (ares_init_flags & ARES_LIB_INIT_WIN32) ares_win32_cleanup(); ares_init_flags = ARES_LIB_INIT_NONE; } int ares_library_initialized(void) { #ifdef USE_WINSOCK if (!ares_initialized) return ARES_ENOTINITIALIZED; #endif return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_library_init.h000644 000766 000024 00000003003 12650222322 021427 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_LIBRARY_INIT_H #define HEADER_CARES_LIBRARY_INIT_H /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004-2011 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef USE_WINSOCK #include #include typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*); typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG); typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* ); /* Forward-declaration of variables defined in ares_library_init.c */ /* that are global and unique instances for whole c-ares library. */ extern fpGetNetworkParams_t ares_fpGetNetworkParams; extern fpSystemFunction036_t ares_fpSystemFunction036; extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses; #endif /* USE_WINSOCK */ #endif /* HEADER_CARES_LIBRARY_INIT_H */ node-v4.2.6/deps/cares/src/ares_llist.c000644 000766 000024 00000003507 12650222322 020073 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_private.h" /* Routines for managing doubly-linked circular linked lists with a * dummy head. */ /* Initialize a new head node */ void ares__init_list_head(struct list_node* head) { head->prev = head; head->next = head; head->data = NULL; } /* Initialize a list node */ void ares__init_list_node(struct list_node* node, void* d) { node->prev = NULL; node->next = NULL; node->data = d; } /* Returns true iff the given list is empty */ int ares__is_list_empty(struct list_node* head) { return ((head->next == head) && (head->prev == head)); } /* Inserts new_node before old_node */ void ares__insert_in_list(struct list_node* new_node, struct list_node* old_node) { new_node->next = old_node; new_node->prev = old_node->prev; old_node->prev->next = new_node; old_node->prev = new_node; } /* Removes the node from the list it's in, if any */ void ares__remove_from_list(struct list_node* node) { if (node->next != NULL) { node->prev->next = node->next; node->next->prev = node->prev; node->prev = NULL; node->next = NULL; } } node-v4.2.6/deps/cares/src/ares_llist.h000644 000766 000024 00000002345 12650222322 020077 0ustar00iojsstaff000000 000000 #ifndef __ARES_LLIST_H #define __ARES_LLIST_H /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* Node definition for circular, doubly-linked list */ struct list_node { struct list_node *prev; struct list_node *next; void* data; }; void ares__init_list_head(struct list_node* head); void ares__init_list_node(struct list_node* node, void* d); int ares__is_list_empty(struct list_node* head); void ares__insert_in_list(struct list_node* new_node, struct list_node* old_node); void ares__remove_from_list(struct list_node* node); #endif /* __ARES_LLIST_H */ node-v4.2.6/deps/cares/src/ares_mkquery.c000644 000766 000024 00000001704 12650222322 020436 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen) { return ares_create_query(name, dnsclass, type, id, rd, buf, buflen, 0); } node-v4.2.6/deps/cares/src/ares_nowarn.c000644 000766 000024 00000014021 12650222322 020241 0ustar00iojsstaff000000 000000 /* Copyright (C) 2010-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_ASSERT_H # include #endif #ifdef HAVE_LIMITS_H #include #endif #if defined(__INTEL_COMPILER) && defined(__unix__) #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #endif /* __INTEL_COMPILER && __unix__ */ #define BUILDING_ARES_NOWARN_C 1 #include "ares_nowarn.h" #if (SIZEOF_SHORT == 2) # define CARES_MASK_SSHORT 0x7FFF # define CARES_MASK_USHORT 0xFFFF #elif (SIZEOF_SHORT == 4) # define CARES_MASK_SSHORT 0x7FFFFFFF # define CARES_MASK_USHORT 0xFFFFFFFF #elif (SIZEOF_SHORT == 8) # define CARES_MASK_SSHORT 0x7FFFFFFFFFFFFFFF # define CARES_MASK_USHORT 0xFFFFFFFFFFFFFFFF #else # error "SIZEOF_SHORT not defined" #endif #if (SIZEOF_INT == 2) # define CARES_MASK_SINT 0x7FFF # define CARES_MASK_UINT 0xFFFF #elif (SIZEOF_INT == 4) # define CARES_MASK_SINT 0x7FFFFFFF # define CARES_MASK_UINT 0xFFFFFFFF #elif (SIZEOF_INT == 8) # define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFF # define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFF #elif (SIZEOF_INT == 16) # define CARES_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF # define CARES_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF #else # error "SIZEOF_INT not defined" #endif #ifndef HAVE_LIMITS_H /* systems without we guess have 32 bit longs */ #define CARES_MASK_SLONG 0x7FFFFFFFL #define CARES_MASK_ULONG 0xFFFFFFFFUL #else #define CARES_MASK_ULONG ULONG_MAX #define CARES_MASK_SLONG LONG_MAX #endif /* ** unsigned size_t to signed long */ long aresx_uztosl(size_t uznum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif return (long)(uznum & (size_t) CARES_MASK_SLONG); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** unsigned size_t to signed int */ int aresx_uztosi(size_t uznum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif return (int)(uznum & (size_t) CARES_MASK_SINT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** unsigned size_t to signed short */ short aresx_uztoss(size_t uznum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif return (short)(uznum & (size_t) CARES_MASK_SSHORT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** signed int to signed short */ short aresx_sitoss(int sinum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif DEBUGASSERT(sinum >= 0); return (short)(sinum & (int) CARES_MASK_SSHORT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** signed long to signed int */ int aresx_sltosi(long slnum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif DEBUGASSERT(slnum >= 0); return (int)(slnum & (long) CARES_MASK_SINT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** signed ssize_t to signed int */ int aresx_sztosi(ssize_t sznum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif DEBUGASSERT(sznum >= 0); return (int)(sznum & (ssize_t) CARES_MASK_SINT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** signed ssize_t to unsigned int */ unsigned int aresx_sztoui(ssize_t sznum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif DEBUGASSERT(sznum >= 0); return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } /* ** signed int to unsigned short */ unsigned short aresx_sitous(int sinum) { #ifdef __INTEL_COMPILER # pragma warning(push) # pragma warning(disable:810) /* conversion may lose significant bits */ #endif DEBUGASSERT(sinum >= 0); return (unsigned short)(sinum & (int) CARES_MASK_USHORT); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif } #if defined(__INTEL_COMPILER) && defined(__unix__) int aresx_FD_ISSET(int fd, fd_set *fdset) { #pragma warning(push) #pragma warning(disable:1469) /* clobber ignored */ return FD_ISSET(fd, fdset); #pragma warning(pop) } void aresx_FD_SET(int fd, fd_set *fdset) { #pragma warning(push) #pragma warning(disable:1469) /* clobber ignored */ FD_SET(fd, fdset); #pragma warning(pop) } void aresx_FD_ZERO(fd_set *fdset) { #pragma warning(push) #pragma warning(disable:593) /* variable was set but never used */ FD_ZERO(fdset); #pragma warning(pop) } unsigned short aresx_htons(unsigned short usnum) { #if (__INTEL_COMPILER == 910) && defined(__i386__) return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); #else #pragma warning(push) #pragma warning(disable:810) /* conversion may lose significant bits */ return htons(usnum); #pragma warning(pop) #endif } unsigned short aresx_ntohs(unsigned short usnum) { #if (__INTEL_COMPILER == 910) && defined(__i386__) return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); #else #pragma warning(push) #pragma warning(disable:810) /* conversion may lose significant bits */ return ntohs(usnum); #pragma warning(pop) #endif } #endif /* __INTEL_COMPILER && __unix__ */ node-v4.2.6/deps/cares/src/ares_nowarn.h000644 000766 000024 00000003304 12650222322 020250 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_NOWARN_H #define HEADER_CARES_NOWARN_H /* Copyright (C) 2010-2012 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ long aresx_uztosl(size_t uznum); int aresx_uztosi(size_t uznum); short aresx_uztoss(size_t uznum); short aresx_sitoss(int sinum); int aresx_sltosi(long slnum); int aresx_sztosi(ssize_t sznum); unsigned int aresx_sztoui(ssize_t sznum); unsigned short aresx_sitous(int sinum); #if defined(__INTEL_COMPILER) && defined(__unix__) int aresx_FD_ISSET(int fd, fd_set *fdset); void aresx_FD_SET(int fd, fd_set *fdset); void aresx_FD_ZERO(fd_set *fdset); unsigned short aresx_htons(unsigned short usnum); unsigned short aresx_ntohs(unsigned short usnum); #ifndef BUILDING_ARES_NOWARN_C # undef FD_ISSET # define FD_ISSET(a,b) aresx_FD_ISSET((a),(b)) # undef FD_SET # define FD_SET(a,b) aresx_FD_SET((a),(b)) # undef FD_ZERO # define FD_ZERO(a) aresx_FD_ZERO((a)) # undef htons # define htons(a) aresx_htons((a)) # undef ntohs # define ntohs(a) aresx_ntohs((a)) #endif #endif /* __INTEL_COMPILER && __unix__ */ #endif /* HEADER_CARES_NOWARN_H */ node-v4.2.6/deps/cares/src/ares_options.c000644 000766 000024 00000016623 12650222322 020442 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2008-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_ARPA_INET_H # include #endif #include "ares.h" #include "ares_data.h" #include "ares_inet_net_pton.h" #include "ares_private.h" int ares_get_servers(ares_channel channel, struct ares_addr_node **servers) { struct ares_addr_node *srvr_head = NULL; struct ares_addr_node *srvr_last = NULL; struct ares_addr_node *srvr_curr; int status = ARES_SUCCESS; int i; if (!channel) return ARES_ENODATA; for (i = 0; i < channel->nservers; i++) { /* Allocate storage for this server node appending it to the list */ srvr_curr = ares_malloc_data(ARES_DATATYPE_ADDR_NODE); if (!srvr_curr) { status = ARES_ENOMEM; break; } if (srvr_last) { srvr_last->next = srvr_curr; } else { srvr_head = srvr_curr; } srvr_last = srvr_curr; /* Fill this server node data */ srvr_curr->family = channel->servers[i].addr.family; if (srvr_curr->family == AF_INET) memcpy(&srvr_curr->addrV4, &channel->servers[i].addr.addrV4, sizeof(srvr_curr->addrV4)); else memcpy(&srvr_curr->addrV6, &channel->servers[i].addr.addrV6, sizeof(srvr_curr->addrV6)); } if (status != ARES_SUCCESS) { if (srvr_head) { ares_free_data(srvr_head); srvr_head = NULL; } } *servers = srvr_head; return status; } int ares_set_servers(ares_channel channel, struct ares_addr_node *servers) { struct ares_addr_node *srvr; int num_srvrs = 0; int i; if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; if (!channel) return ARES_ENODATA; ares__destroy_servers_state(channel); for (srvr = servers; srvr; srvr = srvr->next) { num_srvrs++; } if (num_srvrs > 0) { /* Allocate storage for servers state */ channel->servers = malloc(num_srvrs * sizeof(struct server_state)); if (!channel->servers) { return ARES_ENOMEM; } channel->nservers = num_srvrs; /* Fill servers state address data */ for (i = 0, srvr = servers; srvr; i++, srvr = srvr->next) { channel->servers[i].addr.family = srvr->family; if (srvr->family == AF_INET) memcpy(&channel->servers[i].addr.addrV4, &srvr->addrV4, sizeof(srvr->addrV4)); else memcpy(&channel->servers[i].addr.addrV6, &srvr->addrV6, sizeof(srvr->addrV6)); } /* Initialize servers state remaining data */ ares__init_servers_state(channel); } return ARES_SUCCESS; } /* Incomming string format: host[:port][,host[:port]]... */ /* IPv6 addresses with ports require square brackets [fe80::1%lo0]:53 */ int ares_set_servers_csv(ares_channel channel, const char* _csv) { size_t i; char* csv = NULL; char* ptr; char* start_host; int cc = 0; int rv = ARES_SUCCESS; struct ares_addr_node *servers = NULL; struct ares_addr_node *last = NULL; if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; if (!channel) return ARES_ENODATA; ares__destroy_servers_state(channel); i = strlen(_csv); if (i == 0) return ARES_SUCCESS; /* blank all servers */ csv = malloc(i + 2); if (!csv) return ARES_ENOMEM; strcpy(csv, _csv); if (csv[i-1] != ',') { /* make parsing easier by ensuring ending ',' */ csv[i] = ','; csv[i+1] = 0; } start_host = csv; for (ptr = csv; *ptr; ptr++) { if (*ptr == ':') { /* count colons to determine if we have an IPv6 number or IPv4 with port */ cc++; } else if (*ptr == '[') { /* move start_host if an open square bracket is found wrapping an IPv6 address */ start_host = ptr + 1; } else if (*ptr == ',') { char* pp = ptr - 1; char* p = ptr; struct in_addr in4; struct ares_in6_addr in6; struct ares_addr_node *s = NULL; *ptr = 0; /* null terminate host:port string */ /* Got an entry..see if the port was specified. */ if (cc > 0) { while (pp > start_host) { /* a single close square bracket followed by a colon, ']:' indicates an IPv6 address with port */ if ((*pp == ']') && (*p == ':')) break; /* found port */ /* a single colon, ':' indicates an IPv4 address with port */ if ((*pp == ':') && (cc == 1)) break; /* found port */ if (!(ISDIGIT(*pp) || (*pp == ':'))) { /* Found end of digits before we found :, so wasn't a port */ /* must allow ':' for IPv6 case of ']:' indicates we found a port */ pp = p = ptr; break; } pp--; p--; } if ((pp != start_host) && ((pp + 1) < ptr)) { /* Found it. Parse over the port number */ /* when an IPv6 address is wrapped with square brackets the port starts at pp + 2 */ if (*pp == ']') p++; /* move p before ':' */ /* p will point to the start of the port */ (void)strtol(p, NULL, 10); *pp = 0; /* null terminate host */ } } /* resolve host, try ipv4 first, rslt is in network byte order */ rv = ares_inet_pton(AF_INET, start_host, &in4); if (!rv) { /* Ok, try IPv6 then */ rv = ares_inet_pton(AF_INET6, start_host, &in6); if (!rv) { rv = ARES_EBADSTR; goto out; } /* was ipv6, add new server */ s = malloc(sizeof(*s)); if (!s) { rv = ARES_ENOMEM; goto out; } s->family = AF_INET6; memcpy(&s->addr, &in6, sizeof(struct ares_in6_addr)); } else { /* was ipv4, add new server */ s = malloc(sizeof(*s)); if (!s) { rv = ARES_ENOMEM; goto out; } s->family = AF_INET; memcpy(&s->addr, &in4, sizeof(struct in_addr)); } if (s) { /* TODO: Add port to ares_addr_node and assign it here. */ s->next = NULL; if (last) { last->next = s; /* need to move last to maintain the linked list */ last = last->next; } else { servers = s; last = s; } } /* Set up for next one */ start_host = ptr + 1; cc = 0; } } rv = ares_set_servers(channel, servers); out: if (csv) free(csv); while (servers) { struct ares_addr_node *s = servers; servers = servers->next; free(s); } return rv; } node-v4.2.6/deps/cares/src/ares_parse_a_reply.c000644 000766 000024 00000016536 12650222322 021577 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_LIMITS_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_private.h" int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host, struct ares_addrttl *addrttls, int *naddrttls) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct in_addr *addrs; struct hostent *hostent; const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; /* Set *host to NULL for all failure cases. */ if (host) *host = NULL; /* Same with *naddrttls. */ if (naddrttls) *naddrttls = 0; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; if (host) { /* Allocate addresses and aliases; ancount gives an upper bound for both. */ addrs = malloc(ancount * sizeof(struct in_addr)); if (!addrs) { free(hostname); return ARES_ENOMEM; } aliases = malloc((ancount + 1) * sizeof(char *)); if (!aliases) { free(hostname); free(addrs); return ARES_ENOMEM; } } else { addrs = NULL; aliases = NULL; } naddrs = 0; naliases = 0; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < (int)ancount; i++) { /* Decode the RR up to the data field. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) break; aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); rr_ttl = DNS_RR_TTL(aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } if (rr_class == C_IN && rr_type == T_A && rr_len == sizeof(struct in_addr) && strcasecmp(rr_name, hostname) == 0) { if (addrs) { if (aptr + sizeof(struct in_addr) > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); } if (naddrs < max_addr_ttls) { struct ares_addrttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct in_addr) > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); at->ttl = rr_ttl; } naddrs++; status = ARES_SUCCESS; } if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ if (aliases) aliases[naliases] = rr_name; else free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) break; free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ if (cname_ttl > rr_ttl) cname_ttl = rr_ttl; } else free(rr_name); aptr += rr_len; if (aptr > abuf + alen) { status = ARES_EBADRESP; break; } } if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) /* the check for naliases to be zero is to make sure CNAME responses don't get caught here */ status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. */ if (naddrttls) { const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; for (i = 0; i < n; i++) { /* Ensure that each A TTL is no larger than the CNAME TTL. */ if (addrttls[i].ttl > cname_ttl) addrttls[i].ttl = cname_ttl; } *naddrttls = n; } if (aliases) aliases[naliases] = NULL; if (host) { /* Allocate memory to build the host entry. */ hostent = malloc(sizeof(struct hostent)); if (hostent) { hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; hostent->h_aliases = aliases; hostent->h_addrtype = AF_INET; hostent->h_length = sizeof(struct in_addr); for (i = 0; i < naddrs; i++) hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; if (!naddrs && addrs) free(addrs); *host = hostent; return ARES_SUCCESS; } free(hostent); } status = ARES_ENOMEM; } } if (aliases) { for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); } free(addrs); free(hostname); return status; } node-v4.2.6/deps/cares/src/ares_parse_aaaa_reply.c000644 000766 000024 00000016715 12650222322 022241 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright 2005 Dominick Meglio * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_LIMITS_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_inet_net_pton.h" #include "ares_private.h" int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host, struct ares_addr6ttl *addrttls, int *naddrttls) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct ares_in6_addr *addrs; struct hostent *hostent; const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; /* Set *host to NULL for all failure cases. */ if (host) *host = NULL; /* Same with *naddrttls. */ if (naddrttls) *naddrttls = 0; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Allocate addresses and aliases; ancount gives an upper bound for both. */ if (host) { addrs = malloc(ancount * sizeof(struct ares_in6_addr)); if (!addrs) { free(hostname); return ARES_ENOMEM; } aliases = malloc((ancount + 1) * sizeof(char *)); if (!aliases) { free(hostname); free(addrs); return ARES_ENOMEM; } } else { addrs = NULL; aliases = NULL; } naddrs = 0; naliases = 0; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < (int)ancount; i++) { /* Decode the RR up to the data field. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) break; aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); rr_ttl = DNS_RR_TTL(aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } if (rr_class == C_IN && rr_type == T_AAAA && rr_len == sizeof(struct ares_in6_addr) && strcasecmp(rr_name, hostname) == 0) { if (addrs) { if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr)); } if (naddrs < max_addr_ttls) { struct ares_addr6ttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr)); at->ttl = rr_ttl; } naddrs++; status = ARES_SUCCESS; } if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ if (aliases) aliases[naliases] = rr_name; else free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) break; free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ if (cname_ttl > rr_ttl) cname_ttl = rr_ttl; } else free(rr_name); aptr += rr_len; if (aptr > abuf + alen) { status = ARES_EBADRESP; break; } } /* the check for naliases to be zero is to make sure CNAME responses don't get caught here */ if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. */ if (naddrttls) { const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; for (i = 0; i < n; i++) { /* Ensure that each A TTL is no larger than the CNAME TTL. */ if (addrttls[i].ttl > cname_ttl) addrttls[i].ttl = cname_ttl; } *naddrttls = n; } if (aliases) aliases[naliases] = NULL; if (host) { /* Allocate memory to build the host entry. */ hostent = malloc(sizeof(struct hostent)); if (hostent) { hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; hostent->h_aliases = aliases; hostent->h_addrtype = AF_INET6; hostent->h_length = sizeof(struct ares_in6_addr); for (i = 0; i < naddrs; i++) hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; if (!naddrs && addrs) free(addrs); *host = hostent; return ARES_SUCCESS; } free(hostent); } status = ARES_ENOMEM; } } if (aliases) { for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); } free(addrs); free(hostname); return status; } node-v4.2.6/deps/cares/src/ares_parse_mx_reply.c000644 000766 000024 00000010557 12650222322 022000 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2010 Jeremy Lal * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_data.h" #include "ares_private.h" int ares_parse_mx_reply (const unsigned char *abuf, int alen, struct ares_mx_reply **mx_out) { unsigned int qdcount, ancount, i; const unsigned char *aptr, *vptr; int status, rr_type, rr_class, rr_len; long len; char *hostname = NULL, *rr_name = NULL; struct ares_mx_reply *mx_head = NULL; struct ares_mx_reply *mx_last = NULL; struct ares_mx_reply *mx_curr; /* Set *mx_out to NULL for all failure cases. */ *mx_out = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT (abuf); ancount = DNS_HEADER_ANCOUNT (abuf); if (qdcount != 1) return ARES_EBADRESP; if (ancount == 0) return ARES_ENODATA; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name (aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) { break; } aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE (aptr); rr_class = DNS_RR_CLASS (aptr); rr_len = DNS_RR_LEN (aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { status = ARES_EBADRESP; break; } /* Check if we are really looking at a MX record */ if (rr_class == C_IN && rr_type == T_MX) { /* parse the MX record itself */ if (rr_len < 2) { status = ARES_EBADRESP; break; } /* Allocate storage for this MX answer appending it to the list */ mx_curr = ares_malloc_data(ARES_DATATYPE_MX_REPLY); if (!mx_curr) { status = ARES_ENOMEM; break; } if (mx_last) { mx_last->next = mx_curr; } else { mx_head = mx_curr; } mx_last = mx_curr; vptr = aptr; mx_curr->priority = DNS__16BIT(vptr); vptr += sizeof(unsigned short); status = ares_expand_name (vptr, abuf, alen, &mx_curr->host, &len); if (status != ARES_SUCCESS) break; } /* Don't lose memory in the next iteration */ free (rr_name); rr_name = NULL; /* Move on to the next record */ aptr += rr_len; } if (hostname) free (hostname); if (rr_name) free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) { if (mx_head) ares_free_data (mx_head); return status; } /* everything looks fine, return the data */ *mx_out = mx_head; return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_parse_naptr_reply.c000644 000766 000024 00000012035 12650222322 022471 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2009 by Jakub Hrozek * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_data.h" #include "ares_private.h" /* AIX portability check */ #ifndef T_NAPTR #define T_NAPTR 35 /* naming authority pointer */ #endif int ares_parse_naptr_reply (const unsigned char *abuf, int alen, struct ares_naptr_reply **naptr_out) { unsigned int qdcount, ancount, i; const unsigned char *aptr, *vptr; int status, rr_type, rr_class, rr_len; long len; char *hostname = NULL, *rr_name = NULL; struct ares_naptr_reply *naptr_head = NULL; struct ares_naptr_reply *naptr_last = NULL; struct ares_naptr_reply *naptr_curr; /* Set *naptr_out to NULL for all failure cases. */ *naptr_out = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT (abuf); ancount = DNS_HEADER_ANCOUNT (abuf); if (qdcount != 1) return ARES_EBADRESP; if (ancount == 0) return ARES_ENODATA; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name (aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) { break; } aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE (aptr); rr_class = DNS_RR_CLASS (aptr); rr_len = DNS_RR_LEN (aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { status = ARES_EBADRESP; break; } /* Check if we are really looking at a NAPTR record */ if (rr_class == C_IN && rr_type == T_NAPTR) { /* parse the NAPTR record itself */ /* Allocate storage for this NAPTR answer appending it to the list */ naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY); if (!naptr_curr) { status = ARES_ENOMEM; break; } if (naptr_last) { naptr_last->next = naptr_curr; } else { naptr_head = naptr_curr; } naptr_last = naptr_curr; vptr = aptr; naptr_curr->order = DNS__16BIT(vptr); vptr += sizeof(unsigned short); naptr_curr->preference = DNS__16BIT(vptr); vptr += sizeof(unsigned short); status = ares_expand_string(vptr, abuf, alen, &naptr_curr->flags, &len); if (status != ARES_SUCCESS) break; vptr += len; status = ares_expand_string(vptr, abuf, alen, &naptr_curr->service, &len); if (status != ARES_SUCCESS) break; vptr += len; status = ares_expand_string(vptr, abuf, alen, &naptr_curr->regexp, &len); if (status != ARES_SUCCESS) break; vptr += len; status = ares_expand_name(vptr, abuf, alen, &naptr_curr->replacement, &len); if (status != ARES_SUCCESS) break; } /* Don't lose memory in the next iteration */ free (rr_name); rr_name = NULL; /* Move on to the next record */ aptr += rr_len; } if (hostname) free (hostname); if (rr_name) free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) { if (naptr_head) ares_free_data (naptr_head); return status; } /* everything looks fine, return the data */ *naptr_out = naptr_head; return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_parse_ns_reply.c000644 000766 000024 00000011521 12650222322 021764 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * ares_parse_ns_reply created by Vlad Dinulescu * on behalf of AVIRA Gmbh - http://www.avira.com */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_private.h" int ares_parse_ns_reply( const unsigned char* abuf, int alen, struct hostent** host ) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len; int nameservers_num; long len; const unsigned char *aptr; char* hostname, *rr_name, *rr_data, **nameservers; struct hostent *hostent; /* Set *host to NULL for all failure cases. */ *host = NULL; /* Give up if abuf doesn't have room for a header. */ if ( alen < HFIXEDSZ ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT( abuf ); ancount = DNS_HEADER_ANCOUNT( abuf ); if ( qdcount != 1 ) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares__expand_name_for_response( aptr, abuf, alen, &hostname, &len); if ( status != ARES_SUCCESS ) return status; if ( aptr + len + QFIXEDSZ > abuf + alen ) { free( hostname ); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Allocate nameservers array; ancount gives an upper bound */ nameservers = malloc( ( ancount + 1 ) * sizeof( char * ) ); if ( !nameservers ) { free( hostname ); return ARES_ENOMEM; } nameservers_num = 0; /* Examine each answer resource record (RR) in turn. */ for ( i = 0; i < ( int ) ancount; i++ ) { /* Decode the RR up to the data field. */ status = ares__expand_name_for_response( aptr, abuf, alen, &rr_name, &len ); if ( status != ARES_SUCCESS ) break; aptr += len; if ( aptr + RRFIXEDSZ > abuf + alen ) { status = ARES_EBADRESP; free(rr_name); break; } rr_type = DNS_RR_TYPE( aptr ); rr_class = DNS_RR_CLASS( aptr ); rr_len = DNS_RR_LEN( aptr ); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } if ( rr_class == C_IN && rr_type == T_NS ) { /* Decode the RR data and add it to the nameservers list */ status = ares__expand_name_for_response( aptr, abuf, alen, &rr_data, &len); if ( status != ARES_SUCCESS ) { free(rr_name); break; } nameservers[nameservers_num] = malloc(strlen(rr_data)+1); if (nameservers[nameservers_num]==NULL) { free(rr_name); free(rr_data); status=ARES_ENOMEM; break; } strcpy(nameservers[nameservers_num],rr_data); free(rr_data); nameservers_num++; } free( rr_name ); aptr += rr_len; if ( aptr > abuf + alen ) { status = ARES_EBADRESP; break; } } if ( status == ARES_SUCCESS && nameservers_num == 0 ) { status = ARES_ENODATA; } if ( status == ARES_SUCCESS ) { /* We got our answer. Allocate memory to build the host entry. */ nameservers[nameservers_num] = NULL; hostent = malloc( sizeof( struct hostent ) ); if ( hostent ) { hostent->h_addr_list = malloc( 1 * sizeof( char * ) ); if ( hostent->h_addr_list ) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; hostent->h_aliases = nameservers; hostent->h_addrtype = AF_INET; hostent->h_length = sizeof( struct in_addr ); hostent->h_addr_list[0] = NULL; *host = hostent; return ARES_SUCCESS; } free( hostent ); } status = ARES_ENOMEM; } for ( i = 0; i < nameservers_num; i++ ) free( nameservers[i] ); free( nameservers ); free( hostname ); return status; } node-v4.2.6/deps/cares/src/ares_parse_ptr_reply.c000644 000766 000024 00000014637 12650222322 022164 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_nowarn.h" #include "ares_private.h" int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len; long len; const unsigned char *aptr; char *ptrname, *hostname, *rr_name, *rr_data; struct hostent *hostent; int aliascnt = 0; int alias_alloc = 8; char ** aliases; /* Set *host to NULL for all failure cases. */ *host = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares__expand_name_for_response(aptr, abuf, alen, &ptrname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free(ptrname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ hostname = NULL; aliases = malloc(alias_alloc * sizeof(char *)); if (!aliases) { free(ptrname); return ARES_ENOMEM; } for (i = 0; i < (int)ancount; i++) { /* Decode the RR up to the data field. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) break; aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { free(rr_name); status = ARES_EBADRESP; break; } if (rr_class == C_IN && rr_type == T_PTR && strcasecmp(rr_name, ptrname) == 0) { /* Decode the RR data and set hostname to it. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) { free(rr_name); break; } if (hostname) free(hostname); hostname = rr_data; aliases[aliascnt] = malloc((strlen(rr_data)+1) * sizeof(char)); if (!aliases[aliascnt]) { free(rr_name); status = ARES_ENOMEM; break; } strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1); aliascnt++; if (aliascnt >= alias_alloc) { char **ptr; alias_alloc *= 2; ptr = realloc(aliases, alias_alloc * sizeof(char *)); if(!ptr) { free(rr_name); status = ARES_ENOMEM; break; } aliases = ptr; } } if (rr_class == C_IN && rr_type == T_CNAME) { /* Decode the RR data and replace ptrname with it. */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) { free(rr_name); break; } free(ptrname); ptrname = rr_data; } free(rr_name); aptr += rr_len; if (aptr > abuf + alen) { status = ARES_EBADRESP; break; } } if (status == ARES_SUCCESS && !hostname) status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ hostent = malloc(sizeof(struct hostent)); if (hostent) { hostent->h_addr_list = malloc(2 * sizeof(char *)); if (hostent->h_addr_list) { hostent->h_addr_list[0] = malloc(addrlen); if (hostent->h_addr_list[0]) { hostent->h_aliases = malloc((aliascnt+1) * sizeof (char *)); if (hostent->h_aliases) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; for (i=0 ; ih_aliases[i] = aliases[i]; hostent->h_aliases[aliascnt] = NULL; hostent->h_addrtype = aresx_sitoss(family); hostent->h_length = aresx_sitoss(addrlen); memcpy(hostent->h_addr_list[0], addr, addrlen); hostent->h_addr_list[1] = NULL; *host = hostent; free(aliases); free(ptrname); return ARES_SUCCESS; } free(hostent->h_addr_list[0]); } free(hostent->h_addr_list); } free(hostent); } status = ARES_ENOMEM; } for (i=0 ; i * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_data.h" #include "ares_private.h" int ares_parse_soa_reply(const unsigned char *abuf, int alen, struct ares_soa_reply **soa_out) { const unsigned char *aptr; long len; char *qname = NULL, *rr_name = NULL; struct ares_soa_reply *soa = NULL; int qdcount, ancount; int status; if (alen < HFIXEDSZ) return ARES_EBADRESP; /* parse message header */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1 || ancount != 1) return ARES_EBADRESP; aptr = abuf + HFIXEDSZ; /* query name */ status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len); if (status != ARES_SUCCESS) goto failed_stat; aptr += len; /* skip qtype & qclass */ if (aptr + QFIXEDSZ > abuf + alen) goto failed; aptr += QFIXEDSZ; /* rr_name */ status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) goto failed_stat; aptr += len; /* skip rr_type, rr_class, rr_ttl, rr_rdlen */ if (aptr + RRFIXEDSZ > abuf + alen) goto failed; aptr += RRFIXEDSZ; /* allocate result struct */ soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY); if (!soa) { status = ARES_ENOMEM; goto failed_stat; } /* nsname */ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len); if (status != ARES_SUCCESS) goto failed_stat; aptr += len; /* hostmaster */ status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len); if (status != ARES_SUCCESS) goto failed_stat; aptr += len; /* integer fields */ if (aptr + 5 * 4 > abuf + alen) goto failed; soa->serial = DNS__32BIT(aptr + 0 * 4); soa->refresh = DNS__32BIT(aptr + 1 * 4); soa->retry = DNS__32BIT(aptr + 2 * 4); soa->expire = DNS__32BIT(aptr + 3 * 4); soa->minttl = DNS__32BIT(aptr + 4 * 4); free(qname); free(rr_name); *soa_out = soa; return ARES_SUCCESS; failed: status = ARES_EBADRESP; failed_stat: ares_free_data(soa); if (qname) free(qname); if (rr_name) free(rr_name); return status; } node-v4.2.6/deps/cares/src/ares_parse_srv_reply.c000644 000766 000024 00000011241 12650222322 022155 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2009 by Jakub Hrozek * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_data.h" #include "ares_private.h" /* AIX portability check */ #ifndef T_SRV # define T_SRV 33 /* server selection */ #endif int ares_parse_srv_reply (const unsigned char *abuf, int alen, struct ares_srv_reply **srv_out) { unsigned int qdcount, ancount, i; const unsigned char *aptr, *vptr; int status, rr_type, rr_class, rr_len; long len; char *hostname = NULL, *rr_name = NULL; struct ares_srv_reply *srv_head = NULL; struct ares_srv_reply *srv_last = NULL; struct ares_srv_reply *srv_curr; /* Set *srv_out to NULL for all failure cases. */ *srv_out = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT (abuf); ancount = DNS_HEADER_ANCOUNT (abuf); if (qdcount != 1) return ARES_EBADRESP; if (ancount == 0) return ARES_ENODATA; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name (aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) { break; } aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE (aptr); rr_class = DNS_RR_CLASS (aptr); rr_len = DNS_RR_LEN (aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { status = ARES_EBADRESP; break; } /* Check if we are really looking at a SRV record */ if (rr_class == C_IN && rr_type == T_SRV) { /* parse the SRV record itself */ if (rr_len < 6) { status = ARES_EBADRESP; break; } /* Allocate storage for this SRV answer appending it to the list */ srv_curr = ares_malloc_data(ARES_DATATYPE_SRV_REPLY); if (!srv_curr) { status = ARES_ENOMEM; break; } if (srv_last) { srv_last->next = srv_curr; } else { srv_head = srv_curr; } srv_last = srv_curr; vptr = aptr; srv_curr->priority = DNS__16BIT(vptr); vptr += sizeof(unsigned short); srv_curr->weight = DNS__16BIT(vptr); vptr += sizeof(unsigned short); srv_curr->port = DNS__16BIT(vptr); vptr += sizeof(unsigned short); status = ares_expand_name (vptr, abuf, alen, &srv_curr->host, &len); if (status != ARES_SUCCESS) break; } /* Don't lose memory in the next iteration */ free (rr_name); rr_name = NULL; /* Move on to the next record */ aptr += rr_len; } if (hostname) free (hostname); if (rr_name) free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) { if (srv_head) ares_free_data (srv_head); return status; } /* everything looks fine, return the data */ *srv_out = srv_head; return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_parse_txt_reply.c000644 000766 000024 00000012533 12650222322 022167 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2009 by Jakub Hrozek * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_data.h" #include "ares_private.h" int ares_parse_txt_reply (const unsigned char *abuf, int alen, struct ares_txt_reply **txt_out) { size_t substr_len; unsigned int qdcount, ancount, i; const unsigned char *aptr; const unsigned char *strptr; int status, rr_type, rr_class, rr_len; long len; char *hostname = NULL, *rr_name = NULL; struct ares_txt_reply *txt_head = NULL; struct ares_txt_reply *txt_last = NULL; struct ares_txt_reply *txt_curr; /* Set *txt_out to NULL for all failure cases. */ *txt_out = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT (abuf); ancount = DNS_HEADER_ANCOUNT (abuf); if (qdcount != 1) return ARES_EBADRESP; if (ancount == 0) return ARES_ENODATA; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name (aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free (hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) { break; } aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE (aptr); rr_class = DNS_RR_CLASS (aptr); rr_len = DNS_RR_LEN (aptr); aptr += RRFIXEDSZ; if (aptr + rr_len > abuf + alen) { status = ARES_EBADRESP; break; } /* Check if we are really looking at a TXT record */ if (rr_class == C_IN && rr_type == T_TXT) { /* * There may be multiple substrings in a single TXT record. Each * substring may be up to 255 characters in length, with a * "length byte" indicating the size of the substring payload. * RDATA contains both the length-bytes and payloads of all * substrings contained therein. */ strptr = aptr; while (strptr < (aptr + rr_len)) { substr_len = (unsigned char)*strptr; if (strptr + substr_len + 1 > aptr + rr_len) { status = ARES_EBADRESP; break; } /* Allocate storage for this TXT answer appending it to the list */ txt_curr = ares_malloc_data(ARES_DATATYPE_TXT_REPLY); if (!txt_curr) { status = ARES_ENOMEM; break; } if (txt_last) { txt_last->next = txt_curr; } else { txt_head = txt_curr; } txt_last = txt_curr; txt_curr->record_start = strptr == aptr; txt_curr->length = substr_len; txt_curr->txt = malloc (substr_len + 1/* Including null byte */); if (txt_curr->txt == NULL) { status = ARES_ENOMEM; break; } ++strptr; memcpy ((char *) txt_curr->txt, strptr, substr_len); /* Make sure we NULL-terminate */ txt_curr->txt[substr_len] = 0; strptr += substr_len; } } /* Don't lose memory in the next iteration */ free (rr_name); rr_name = NULL; /* Move on to the next record */ aptr += rr_len; } if (hostname) free (hostname); if (rr_name) free (rr_name); /* clean up on error */ if (status != ARES_SUCCESS) { if (txt_head) ares_free_data (txt_head); return status; } /* everything looks fine, return the data */ *txt_out = txt_head; return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_platform.c000644 000766 000024 00001702610 12650222322 020572 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004 - 2011 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #include "ares_platform.h" #include "ares_nowarn.h" #include "ares_private.h" #if defined(WIN32) && !defined(MSDOS) #define V_PLATFORM_WIN32s 0 #define V_PLATFORM_WIN32_WINDOWS 1 #define V_PLATFORM_WIN32_NT 2 #define V_PLATFORM_WIN32_CE 3 win_platform ares__getplatform(void) { OSVERSIONINFOEX OsvEx; memset(&OsvEx, 0, sizeof(OsvEx)); OsvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (!GetVersionEx((void *)&OsvEx)) { memset(&OsvEx, 0, sizeof(OsvEx)); OsvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx((void *)&OsvEx)) return WIN_UNKNOWN; } switch(OsvEx.dwPlatformId) { case V_PLATFORM_WIN32s: return WIN_3X; case V_PLATFORM_WIN32_WINDOWS: return WIN_9X; case V_PLATFORM_WIN32_NT: return WIN_NT; case V_PLATFORM_WIN32_CE: return WIN_CE; default: return WIN_UNKNOWN; } } #endif /* WIN32 && ! MSDOS */ #if defined(_WIN32_WCE) /* IANA Well Known Ports are in range 0-1023 */ #define USE_IANA_WELL_KNOWN_PORTS 1 /* IANA Registered Ports are in range 1024-49151 */ #define USE_IANA_REGISTERED_PORTS 1 struct pvt_servent { char *s_name; char **s_aliases; unsigned short s_port; char *s_proto; }; /* * Ref: http://www.iana.org/assignments/port-numbers */ static struct pvt_servent IANAports[] = { #ifdef USE_IANA_WELL_KNOWN_PORTS {"tcpmux", {NULL}, 1, "tcp"}, {"tcpmux", {NULL}, 1, "udp"}, {"compressnet", {NULL}, 2, "tcp"}, {"compressnet", {NULL}, 2, "udp"}, {"compressnet", {NULL}, 3, "tcp"}, {"compressnet", {NULL}, 3, "udp"}, {"rje", {NULL}, 5, "tcp"}, {"rje", {NULL}, 5, "udp"}, {"echo", {NULL}, 7, "tcp"}, {"echo", {NULL}, 7, "udp"}, {"discard", {NULL}, 9, "tcp"}, {"discard", {NULL}, 9, "udp"}, {"discard", {NULL}, 9, "sctp"}, {"discard", {NULL}, 9, "dccp"}, {"systat", {NULL}, 11, "tcp"}, {"systat", {NULL}, 11, "udp"}, {"daytime", {NULL}, 13, "tcp"}, {"daytime", {NULL}, 13, "udp"}, {"qotd", {NULL}, 17, "tcp"}, {"qotd", {NULL}, 17, "udp"}, {"msp", {NULL}, 18, "tcp"}, {"msp", {NULL}, 18, "udp"}, {"chargen", {NULL}, 19, "tcp"}, {"chargen", {NULL}, 19, "udp"}, {"ftp-data", {NULL}, 20, "tcp"}, {"ftp-data", {NULL}, 20, "udp"}, {"ftp-data", {NULL}, 20, "sctp"}, {"ftp", {NULL}, 21, "tcp"}, {"ftp", {NULL}, 21, "udp"}, {"ftp", {NULL}, 21, "sctp"}, {"ssh", {NULL}, 22, "tcp"}, {"ssh", {NULL}, 22, "udp"}, {"ssh", {NULL}, 22, "sctp"}, {"telnet", {NULL}, 23, "tcp"}, {"telnet", {NULL}, 23, "udp"}, {"smtp", {NULL}, 25, "tcp"}, {"smtp", {NULL}, 25, "udp"}, {"nsw-fe", {NULL}, 27, "tcp"}, {"nsw-fe", {NULL}, 27, "udp"}, {"msg-icp", {NULL}, 29, "tcp"}, {"msg-icp", {NULL}, 29, "udp"}, {"msg-auth", {NULL}, 31, "tcp"}, {"msg-auth", {NULL}, 31, "udp"}, {"dsp", {NULL}, 33, "tcp"}, {"dsp", {NULL}, 33, "udp"}, {"time", {NULL}, 37, "tcp"}, {"time", {NULL}, 37, "udp"}, {"rap", {NULL}, 38, "tcp"}, {"rap", {NULL}, 38, "udp"}, {"rlp", {NULL}, 39, "tcp"}, {"rlp", {NULL}, 39, "udp"}, {"graphics", {NULL}, 41, "tcp"}, {"graphics", {NULL}, 41, "udp"}, {"name", {NULL}, 42, "tcp"}, {"name", {NULL}, 42, "udp"}, {"nameserver", {NULL}, 42, "tcp"}, {"nameserver", {NULL}, 42, "udp"}, {"nicname", {NULL}, 43, "tcp"}, {"nicname", {NULL}, 43, "udp"}, {"mpm-flags", {NULL}, 44, "tcp"}, {"mpm-flags", {NULL}, 44, "udp"}, {"mpm", {NULL}, 45, "tcp"}, {"mpm", {NULL}, 45, "udp"}, {"mpm-snd", {NULL}, 46, "tcp"}, {"mpm-snd", {NULL}, 46, "udp"}, {"ni-ftp", {NULL}, 47, "tcp"}, {"ni-ftp", {NULL}, 47, "udp"}, {"auditd", {NULL}, 48, "tcp"}, {"auditd", {NULL}, 48, "udp"}, {"tacacs", {NULL}, 49, "tcp"}, {"tacacs", {NULL}, 49, "udp"}, {"re-mail-ck", {NULL}, 50, "tcp"}, {"re-mail-ck", {NULL}, 50, "udp"}, {"la-maint", {NULL}, 51, "tcp"}, {"la-maint", {NULL}, 51, "udp"}, {"xns-time", {NULL}, 52, "tcp"}, {"xns-time", {NULL}, 52, "udp"}, {"domain", {NULL}, 53, "tcp"}, {"domain", {NULL}, 53, "udp"}, {"xns-ch", {NULL}, 54, "tcp"}, {"xns-ch", {NULL}, 54, "udp"}, {"isi-gl", {NULL}, 55, "tcp"}, {"isi-gl", {NULL}, 55, "udp"}, {"xns-auth", {NULL}, 56, "tcp"}, {"xns-auth", {NULL}, 56, "udp"}, {"xns-mail", {NULL}, 58, "tcp"}, {"xns-mail", {NULL}, 58, "udp"}, {"ni-mail", {NULL}, 61, "tcp"}, {"ni-mail", {NULL}, 61, "udp"}, {"acas", {NULL}, 62, "tcp"}, {"acas", {NULL}, 62, "udp"}, {"whois++", {NULL}, 63, "tcp"}, {"whois++", {NULL}, 63, "udp"}, {"covia", {NULL}, 64, "tcp"}, {"covia", {NULL}, 64, "udp"}, {"tacacs-ds", {NULL}, 65, "tcp"}, {"tacacs-ds", {NULL}, 65, "udp"}, {"sql*net", {NULL}, 66, "tcp"}, {"sql*net", {NULL}, 66, "udp"}, {"bootps", {NULL}, 67, "tcp"}, {"bootps", {NULL}, 67, "udp"}, {"bootpc", {NULL}, 68, "tcp"}, {"bootpc", {NULL}, 68, "udp"}, {"tftp", {NULL}, 69, "tcp"}, {"tftp", {NULL}, 69, "udp"}, {"gopher", {NULL}, 70, "tcp"}, {"gopher", {NULL}, 70, "udp"}, {"netrjs-1", {NULL}, 71, "tcp"}, {"netrjs-1", {NULL}, 71, "udp"}, {"netrjs-2", {NULL}, 72, "tcp"}, {"netrjs-2", {NULL}, 72, "udp"}, {"netrjs-3", {NULL}, 73, "tcp"}, {"netrjs-3", {NULL}, 73, "udp"}, {"netrjs-4", {NULL}, 74, "tcp"}, {"netrjs-4", {NULL}, 74, "udp"}, {"deos", {NULL}, 76, "tcp"}, {"deos", {NULL}, 76, "udp"}, {"vettcp", {NULL}, 78, "tcp"}, {"vettcp", {NULL}, 78, "udp"}, {"finger", {NULL}, 79, "tcp"}, {"finger", {NULL}, 79, "udp"}, {"http", {NULL}, 80, "tcp"}, {"http", {NULL}, 80, "udp"}, {"www", {NULL}, 80, "tcp"}, {"www", {NULL}, 80, "udp"}, {"www-http", {NULL}, 80, "tcp"}, {"www-http", {NULL}, 80, "udp"}, {"http", {NULL}, 80, "sctp"}, {"xfer", {NULL}, 82, "tcp"}, {"xfer", {NULL}, 82, "udp"}, {"mit-ml-dev", {NULL}, 83, "tcp"}, {"mit-ml-dev", {NULL}, 83, "udp"}, {"ctf", {NULL}, 84, "tcp"}, {"ctf", {NULL}, 84, "udp"}, {"mit-ml-dev", {NULL}, 85, "tcp"}, {"mit-ml-dev", {NULL}, 85, "udp"}, {"mfcobol", {NULL}, 86, "tcp"}, {"mfcobol", {NULL}, 86, "udp"}, {"kerberos", {NULL}, 88, "tcp"}, {"kerberos", {NULL}, 88, "udp"}, {"su-mit-tg", {NULL}, 89, "tcp"}, {"su-mit-tg", {NULL}, 89, "udp"}, {"dnsix", {NULL}, 90, "tcp"}, {"dnsix", {NULL}, 90, "udp"}, {"mit-dov", {NULL}, 91, "tcp"}, {"mit-dov", {NULL}, 91, "udp"}, {"npp", {NULL}, 92, "tcp"}, {"npp", {NULL}, 92, "udp"}, {"dcp", {NULL}, 93, "tcp"}, {"dcp", {NULL}, 93, "udp"}, {"objcall", {NULL}, 94, "tcp"}, {"objcall", {NULL}, 94, "udp"}, {"supdup", {NULL}, 95, "tcp"}, {"supdup", {NULL}, 95, "udp"}, {"dixie", {NULL}, 96, "tcp"}, {"dixie", {NULL}, 96, "udp"}, {"swift-rvf", {NULL}, 97, "tcp"}, {"swift-rvf", {NULL}, 97, "udp"}, {"tacnews", {NULL}, 98, "tcp"}, {"tacnews", {NULL}, 98, "udp"}, {"metagram", {NULL}, 99, "tcp"}, {"metagram", {NULL}, 99, "udp"}, {"newacct", {NULL}, 100, "tcp"}, {"hostname", {NULL}, 101, "tcp"}, {"hostname", {NULL}, 101, "udp"}, {"iso-tsap", {NULL}, 102, "tcp"}, {"iso-tsap", {NULL}, 102, "udp"}, {"gppitnp", {NULL}, 103, "tcp"}, {"gppitnp", {NULL}, 103, "udp"}, {"acr-nema", {NULL}, 104, "tcp"}, {"acr-nema", {NULL}, 104, "udp"}, {"cso", {NULL}, 105, "tcp"}, {"cso", {NULL}, 105, "udp"}, {"csnet-ns", {NULL}, 105, "tcp"}, {"csnet-ns", {NULL}, 105, "udp"}, {"3com-tsmux", {NULL}, 106, "tcp"}, {"3com-tsmux", {NULL}, 106, "udp"}, {"rtelnet", {NULL}, 107, "tcp"}, {"rtelnet", {NULL}, 107, "udp"}, {"snagas", {NULL}, 108, "tcp"}, {"snagas", {NULL}, 108, "udp"}, {"pop2", {NULL}, 109, "tcp"}, {"pop2", {NULL}, 109, "udp"}, {"pop3", {NULL}, 110, "tcp"}, {"pop3", {NULL}, 110, "udp"}, {"sunrpc", {NULL}, 111, "tcp"}, {"sunrpc", {NULL}, 111, "udp"}, {"mcidas", {NULL}, 112, "tcp"}, {"mcidas", {NULL}, 112, "udp"}, {"ident", {NULL}, 113, "tcp"}, {"auth", {NULL}, 113, "tcp"}, {"auth", {NULL}, 113, "udp"}, {"sftp", {NULL}, 115, "tcp"}, {"sftp", {NULL}, 115, "udp"}, {"ansanotify", {NULL}, 116, "tcp"}, {"ansanotify", {NULL}, 116, "udp"}, {"uucp-path", {NULL}, 117, "tcp"}, {"uucp-path", {NULL}, 117, "udp"}, {"sqlserv", {NULL}, 118, "tcp"}, {"sqlserv", {NULL}, 118, "udp"}, {"nntp", {NULL}, 119, "tcp"}, {"nntp", {NULL}, 119, "udp"}, {"cfdptkt", {NULL}, 120, "tcp"}, {"cfdptkt", {NULL}, 120, "udp"}, {"erpc", {NULL}, 121, "tcp"}, {"erpc", {NULL}, 121, "udp"}, {"smakynet", {NULL}, 122, "tcp"}, {"smakynet", {NULL}, 122, "udp"}, {"ntp", {NULL}, 123, "tcp"}, {"ntp", {NULL}, 123, "udp"}, {"ansatrader", {NULL}, 124, "tcp"}, {"ansatrader", {NULL}, 124, "udp"}, {"locus-map", {NULL}, 125, "tcp"}, {"locus-map", {NULL}, 125, "udp"}, {"nxedit", {NULL}, 126, "tcp"}, {"nxedit", {NULL}, 126, "udp"}, {"locus-con", {NULL}, 127, "tcp"}, {"locus-con", {NULL}, 127, "udp"}, {"gss-xlicen", {NULL}, 128, "tcp"}, {"gss-xlicen", {NULL}, 128, "udp"}, {"pwdgen", {NULL}, 129, "tcp"}, {"pwdgen", {NULL}, 129, "udp"}, {"cisco-fna", {NULL}, 130, "tcp"}, {"cisco-fna", {NULL}, 130, "udp"}, {"cisco-tna", {NULL}, 131, "tcp"}, {"cisco-tna", {NULL}, 131, "udp"}, {"cisco-sys", {NULL}, 132, "tcp"}, {"cisco-sys", {NULL}, 132, "udp"}, {"statsrv", {NULL}, 133, "tcp"}, {"statsrv", {NULL}, 133, "udp"}, {"ingres-net", {NULL}, 134, "tcp"}, {"ingres-net", {NULL}, 134, "udp"}, {"epmap", {NULL}, 135, "tcp"}, {"epmap", {NULL}, 135, "udp"}, {"profile", {NULL}, 136, "tcp"}, {"profile", {NULL}, 136, "udp"}, {"netbios-ns", {NULL}, 137, "tcp"}, {"netbios-ns", {NULL}, 137, "udp"}, {"netbios-dgm", {NULL}, 138, "tcp"}, {"netbios-dgm", {NULL}, 138, "udp"}, {"netbios-ssn", {NULL}, 139, "tcp"}, {"netbios-ssn", {NULL}, 139, "udp"}, {"emfis-data", {NULL}, 140, "tcp"}, {"emfis-data", {NULL}, 140, "udp"}, {"emfis-cntl", {NULL}, 141, "tcp"}, {"emfis-cntl", {NULL}, 141, "udp"}, {"bl-idm", {NULL}, 142, "tcp"}, {"bl-idm", {NULL}, 142, "udp"}, {"imap", {NULL}, 143, "tcp"}, {"imap", {NULL}, 143, "udp"}, {"uma", {NULL}, 144, "tcp"}, {"uma", {NULL}, 144, "udp"}, {"uaac", {NULL}, 145, "tcp"}, {"uaac", {NULL}, 145, "udp"}, {"iso-tp0", {NULL}, 146, "tcp"}, {"iso-tp0", {NULL}, 146, "udp"}, {"iso-ip", {NULL}, 147, "tcp"}, {"iso-ip", {NULL}, 147, "udp"}, {"jargon", {NULL}, 148, "tcp"}, {"jargon", {NULL}, 148, "udp"}, {"aed-512", {NULL}, 149, "tcp"}, {"aed-512", {NULL}, 149, "udp"}, {"sql-net", {NULL}, 150, "tcp"}, {"sql-net", {NULL}, 150, "udp"}, {"hems", {NULL}, 151, "tcp"}, {"hems", {NULL}, 151, "udp"}, {"bftp", {NULL}, 152, "tcp"}, {"bftp", {NULL}, 152, "udp"}, {"sgmp", {NULL}, 153, "tcp"}, {"sgmp", {NULL}, 153, "udp"}, {"netsc-prod", {NULL}, 154, "tcp"}, {"netsc-prod", {NULL}, 154, "udp"}, {"netsc-dev", {NULL}, 155, "tcp"}, {"netsc-dev", {NULL}, 155, "udp"}, {"sqlsrv", {NULL}, 156, "tcp"}, {"sqlsrv", {NULL}, 156, "udp"}, {"knet-cmp", {NULL}, 157, "tcp"}, {"knet-cmp", {NULL}, 157, "udp"}, {"pcmail-srv", {NULL}, 158, "tcp"}, {"pcmail-srv", {NULL}, 158, "udp"}, {"nss-routing", {NULL}, 159, "tcp"}, {"nss-routing", {NULL}, 159, "udp"}, {"sgmp-traps", {NULL}, 160, "tcp"}, {"sgmp-traps", {NULL}, 160, "udp"}, {"snmp", {NULL}, 161, "tcp"}, {"snmp", {NULL}, 161, "udp"}, {"snmptrap", {NULL}, 162, "tcp"}, {"snmptrap", {NULL}, 162, "udp"}, {"cmip-man", {NULL}, 163, "tcp"}, {"cmip-man", {NULL}, 163, "udp"}, {"cmip-agent", {NULL}, 164, "tcp"}, {"cmip-agent", {NULL}, 164, "udp"}, {"xns-courier", {NULL}, 165, "tcp"}, {"xns-courier", {NULL}, 165, "udp"}, {"s-net", {NULL}, 166, "tcp"}, {"s-net", {NULL}, 166, "udp"}, {"namp", {NULL}, 167, "tcp"}, {"namp", {NULL}, 167, "udp"}, {"rsvd", {NULL}, 168, "tcp"}, {"rsvd", {NULL}, 168, "udp"}, {"send", {NULL}, 169, "tcp"}, {"send", {NULL}, 169, "udp"}, {"print-srv", {NULL}, 170, "tcp"}, {"print-srv", {NULL}, 170, "udp"}, {"multiplex", {NULL}, 171, "tcp"}, {"multiplex", {NULL}, 171, "udp"}, {"cl/1", {NULL}, 172, "tcp"}, {"cl/1", {NULL}, 172, "udp"}, {"xyplex-mux", {NULL}, 173, "tcp"}, {"xyplex-mux", {NULL}, 173, "udp"}, {"mailq", {NULL}, 174, "tcp"}, {"mailq", {NULL}, 174, "udp"}, {"vmnet", {NULL}, 175, "tcp"}, {"vmnet", {NULL}, 175, "udp"}, {"genrad-mux", {NULL}, 176, "tcp"}, {"genrad-mux", {NULL}, 176, "udp"}, {"xdmcp", {NULL}, 177, "tcp"}, {"xdmcp", {NULL}, 177, "udp"}, {"nextstep", {NULL}, 178, "tcp"}, {"nextstep", {NULL}, 178, "udp"}, {"bgp", {NULL}, 179, "tcp"}, {"bgp", {NULL}, 179, "udp"}, {"bgp", {NULL}, 179, "sctp"}, {"ris", {NULL}, 180, "tcp"}, {"ris", {NULL}, 180, "udp"}, {"unify", {NULL}, 181, "tcp"}, {"unify", {NULL}, 181, "udp"}, {"audit", {NULL}, 182, "tcp"}, {"audit", {NULL}, 182, "udp"}, {"ocbinder", {NULL}, 183, "tcp"}, {"ocbinder", {NULL}, 183, "udp"}, {"ocserver", {NULL}, 184, "tcp"}, {"ocserver", {NULL}, 184, "udp"}, {"remote-kis", {NULL}, 185, "tcp"}, {"remote-kis", {NULL}, 185, "udp"}, {"kis", {NULL}, 186, "tcp"}, {"kis", {NULL}, 186, "udp"}, {"aci", {NULL}, 187, "tcp"}, {"aci", {NULL}, 187, "udp"}, {"mumps", {NULL}, 188, "tcp"}, {"mumps", {NULL}, 188, "udp"}, {"qft", {NULL}, 189, "tcp"}, {"qft", {NULL}, 189, "udp"}, {"gacp", {NULL}, 190, "tcp"}, {"gacp", {NULL}, 190, "udp"}, {"prospero", {NULL}, 191, "tcp"}, {"prospero", {NULL}, 191, "udp"}, {"osu-nms", {NULL}, 192, "tcp"}, {"osu-nms", {NULL}, 192, "udp"}, {"srmp", {NULL}, 193, "tcp"}, {"srmp", {NULL}, 193, "udp"}, {"irc", {NULL}, 194, "tcp"}, {"irc", {NULL}, 194, "udp"}, {"dn6-nlm-aud", {NULL}, 195, "tcp"}, {"dn6-nlm-aud", {NULL}, 195, "udp"}, {"dn6-smm-red", {NULL}, 196, "tcp"}, {"dn6-smm-red", {NULL}, 196, "udp"}, {"dls", {NULL}, 197, "tcp"}, {"dls", {NULL}, 197, "udp"}, {"dls-mon", {NULL}, 198, "tcp"}, {"dls-mon", {NULL}, 198, "udp"}, {"smux", {NULL}, 199, "tcp"}, {"smux", {NULL}, 199, "udp"}, {"src", {NULL}, 200, "tcp"}, {"src", {NULL}, 200, "udp"}, {"at-rtmp", {NULL}, 201, "tcp"}, {"at-rtmp", {NULL}, 201, "udp"}, {"at-nbp", {NULL}, 202, "tcp"}, {"at-nbp", {NULL}, 202, "udp"}, {"at-3", {NULL}, 203, "tcp"}, {"at-3", {NULL}, 203, "udp"}, {"at-echo", {NULL}, 204, "tcp"}, {"at-echo", {NULL}, 204, "udp"}, {"at-5", {NULL}, 205, "tcp"}, {"at-5", {NULL}, 205, "udp"}, {"at-zis", {NULL}, 206, "tcp"}, {"at-zis", {NULL}, 206, "udp"}, {"at-7", {NULL}, 207, "tcp"}, {"at-7", {NULL}, 207, "udp"}, {"at-8", {NULL}, 208, "tcp"}, {"at-8", {NULL}, 208, "udp"}, {"qmtp", {NULL}, 209, "tcp"}, {"qmtp", {NULL}, 209, "udp"}, {"z39.50", {NULL}, 210, "tcp"}, {"z39.50", {NULL}, 210, "udp"}, {"914c/g", {NULL}, 211, "tcp"}, {"914c/g", {NULL}, 211, "udp"}, {"anet", {NULL}, 212, "tcp"}, {"anet", {NULL}, 212, "udp"}, {"ipx", {NULL}, 213, "tcp"}, {"ipx", {NULL}, 213, "udp"}, {"vmpwscs", {NULL}, 214, "tcp"}, {"vmpwscs", {NULL}, 214, "udp"}, {"softpc", {NULL}, 215, "tcp"}, {"softpc", {NULL}, 215, "udp"}, {"CAIlic", {NULL}, 216, "tcp"}, {"CAIlic", {NULL}, 216, "udp"}, {"dbase", {NULL}, 217, "tcp"}, {"dbase", {NULL}, 217, "udp"}, {"mpp", {NULL}, 218, "tcp"}, {"mpp", {NULL}, 218, "udp"}, {"uarps", {NULL}, 219, "tcp"}, {"uarps", {NULL}, 219, "udp"}, {"imap3", {NULL}, 220, "tcp"}, {"imap3", {NULL}, 220, "udp"}, {"fln-spx", {NULL}, 221, "tcp"}, {"fln-spx", {NULL}, 221, "udp"}, {"rsh-spx", {NULL}, 222, "tcp"}, {"rsh-spx", {NULL}, 222, "udp"}, {"cdc", {NULL}, 223, "tcp"}, {"cdc", {NULL}, 223, "udp"}, {"masqdialer", {NULL}, 224, "tcp"}, {"masqdialer", {NULL}, 224, "udp"}, {"direct", {NULL}, 242, "tcp"}, {"direct", {NULL}, 242, "udp"}, {"sur-meas", {NULL}, 243, "tcp"}, {"sur-meas", {NULL}, 243, "udp"}, {"inbusiness", {NULL}, 244, "tcp"}, {"inbusiness", {NULL}, 244, "udp"}, {"link", {NULL}, 245, "tcp"}, {"link", {NULL}, 245, "udp"}, {"dsp3270", {NULL}, 246, "tcp"}, {"dsp3270", {NULL}, 246, "udp"}, {"subntbcst_tftp", {NULL}, 247, "tcp"}, {"subntbcst_tftp", {NULL}, 247, "udp"}, {"bhfhs", {NULL}, 248, "tcp"}, {"bhfhs", {NULL}, 248, "udp"}, {"rap", {NULL}, 256, "tcp"}, {"rap", {NULL}, 256, "udp"}, {"set", {NULL}, 257, "tcp"}, {"set", {NULL}, 257, "udp"}, {"esro-gen", {NULL}, 259, "tcp"}, {"esro-gen", {NULL}, 259, "udp"}, {"openport", {NULL}, 260, "tcp"}, {"openport", {NULL}, 260, "udp"}, {"nsiiops", {NULL}, 261, "tcp"}, {"nsiiops", {NULL}, 261, "udp"}, {"arcisdms", {NULL}, 262, "tcp"}, {"arcisdms", {NULL}, 262, "udp"}, {"hdap", {NULL}, 263, "tcp"}, {"hdap", {NULL}, 263, "udp"}, {"bgmp", {NULL}, 264, "tcp"}, {"bgmp", {NULL}, 264, "udp"}, {"x-bone-ctl", {NULL}, 265, "tcp"}, {"x-bone-ctl", {NULL}, 265, "udp"}, {"sst", {NULL}, 266, "tcp"}, {"sst", {NULL}, 266, "udp"}, {"td-service", {NULL}, 267, "tcp"}, {"td-service", {NULL}, 267, "udp"}, {"td-replica", {NULL}, 268, "tcp"}, {"td-replica", {NULL}, 268, "udp"}, {"manet", {NULL}, 269, "tcp"}, {"manet", {NULL}, 269, "udp"}, {"gist", {NULL}, 270, "udp"}, {"http-mgmt", {NULL}, 280, "tcp"}, {"http-mgmt", {NULL}, 280, "udp"}, {"personal-link", {NULL}, 281, "tcp"}, {"personal-link", {NULL}, 281, "udp"}, {"cableport-ax", {NULL}, 282, "tcp"}, {"cableport-ax", {NULL}, 282, "udp"}, {"rescap", {NULL}, 283, "tcp"}, {"rescap", {NULL}, 283, "udp"}, {"corerjd", {NULL}, 284, "tcp"}, {"corerjd", {NULL}, 284, "udp"}, {"fxp", {NULL}, 286, "tcp"}, {"fxp", {NULL}, 286, "udp"}, {"k-block", {NULL}, 287, "tcp"}, {"k-block", {NULL}, 287, "udp"}, {"novastorbakcup", {NULL}, 308, "tcp"}, {"novastorbakcup", {NULL}, 308, "udp"}, {"entrusttime", {NULL}, 309, "tcp"}, {"entrusttime", {NULL}, 309, "udp"}, {"bhmds", {NULL}, 310, "tcp"}, {"bhmds", {NULL}, 310, "udp"}, {"asip-webadmin", {NULL}, 311, "tcp"}, {"asip-webadmin", {NULL}, 311, "udp"}, {"vslmp", {NULL}, 312, "tcp"}, {"vslmp", {NULL}, 312, "udp"}, {"magenta-logic", {NULL}, 313, "tcp"}, {"magenta-logic", {NULL}, 313, "udp"}, {"opalis-robot", {NULL}, 314, "tcp"}, {"opalis-robot", {NULL}, 314, "udp"}, {"dpsi", {NULL}, 315, "tcp"}, {"dpsi", {NULL}, 315, "udp"}, {"decauth", {NULL}, 316, "tcp"}, {"decauth", {NULL}, 316, "udp"}, {"zannet", {NULL}, 317, "tcp"}, {"zannet", {NULL}, 317, "udp"}, {"pkix-timestamp", {NULL}, 318, "tcp"}, {"pkix-timestamp", {NULL}, 318, "udp"}, {"ptp-event", {NULL}, 319, "tcp"}, {"ptp-event", {NULL}, 319, "udp"}, {"ptp-general", {NULL}, 320, "tcp"}, {"ptp-general", {NULL}, 320, "udp"}, {"pip", {NULL}, 321, "tcp"}, {"pip", {NULL}, 321, "udp"}, {"rtsps", {NULL}, 322, "tcp"}, {"rtsps", {NULL}, 322, "udp"}, {"texar", {NULL}, 333, "tcp"}, {"texar", {NULL}, 333, "udp"}, {"pdap", {NULL}, 344, "tcp"}, {"pdap", {NULL}, 344, "udp"}, {"pawserv", {NULL}, 345, "tcp"}, {"pawserv", {NULL}, 345, "udp"}, {"zserv", {NULL}, 346, "tcp"}, {"zserv", {NULL}, 346, "udp"}, {"fatserv", {NULL}, 347, "tcp"}, {"fatserv", {NULL}, 347, "udp"}, {"csi-sgwp", {NULL}, 348, "tcp"}, {"csi-sgwp", {NULL}, 348, "udp"}, {"mftp", {NULL}, 349, "tcp"}, {"mftp", {NULL}, 349, "udp"}, {"matip-type-a", {NULL}, 350, "tcp"}, {"matip-type-a", {NULL}, 350, "udp"}, {"matip-type-b", {NULL}, 351, "tcp"}, {"matip-type-b", {NULL}, 351, "udp"}, {"bhoetty", {NULL}, 351, "tcp"}, {"bhoetty", {NULL}, 351, "udp"}, {"dtag-ste-sb", {NULL}, 352, "tcp"}, {"dtag-ste-sb", {NULL}, 352, "udp"}, {"bhoedap4", {NULL}, 352, "tcp"}, {"bhoedap4", {NULL}, 352, "udp"}, {"ndsauth", {NULL}, 353, "tcp"}, {"ndsauth", {NULL}, 353, "udp"}, {"bh611", {NULL}, 354, "tcp"}, {"bh611", {NULL}, 354, "udp"}, {"datex-asn", {NULL}, 355, "tcp"}, {"datex-asn", {NULL}, 355, "udp"}, {"cloanto-net-1", {NULL}, 356, "tcp"}, {"cloanto-net-1", {NULL}, 356, "udp"}, {"bhevent", {NULL}, 357, "tcp"}, {"bhevent", {NULL}, 357, "udp"}, {"shrinkwrap", {NULL}, 358, "tcp"}, {"shrinkwrap", {NULL}, 358, "udp"}, {"nsrmp", {NULL}, 359, "tcp"}, {"nsrmp", {NULL}, 359, "udp"}, {"scoi2odialog", {NULL}, 360, "tcp"}, {"scoi2odialog", {NULL}, 360, "udp"}, {"semantix", {NULL}, 361, "tcp"}, {"semantix", {NULL}, 361, "udp"}, {"srssend", {NULL}, 362, "tcp"}, {"srssend", {NULL}, 362, "udp"}, {"rsvp_tunnel", {NULL}, 363, "tcp"}, {"rsvp_tunnel", {NULL}, 363, "udp"}, {"aurora-cmgr", {NULL}, 364, "tcp"}, {"aurora-cmgr", {NULL}, 364, "udp"}, {"dtk", {NULL}, 365, "tcp"}, {"dtk", {NULL}, 365, "udp"}, {"odmr", {NULL}, 366, "tcp"}, {"odmr", {NULL}, 366, "udp"}, {"mortgageware", {NULL}, 367, "tcp"}, {"mortgageware", {NULL}, 367, "udp"}, {"qbikgdp", {NULL}, 368, "tcp"}, {"qbikgdp", {NULL}, 368, "udp"}, {"rpc2portmap", {NULL}, 369, "tcp"}, {"rpc2portmap", {NULL}, 369, "udp"}, {"codaauth2", {NULL}, 370, "tcp"}, {"codaauth2", {NULL}, 370, "udp"}, {"clearcase", {NULL}, 371, "tcp"}, {"clearcase", {NULL}, 371, "udp"}, {"ulistproc", {NULL}, 372, "tcp"}, {"ulistproc", {NULL}, 372, "udp"}, {"legent-1", {NULL}, 373, "tcp"}, {"legent-1", {NULL}, 373, "udp"}, {"legent-2", {NULL}, 374, "tcp"}, {"legent-2", {NULL}, 374, "udp"}, {"hassle", {NULL}, 375, "tcp"}, {"hassle", {NULL}, 375, "udp"}, {"nip", {NULL}, 376, "tcp"}, {"nip", {NULL}, 376, "udp"}, {"tnETOS", {NULL}, 377, "tcp"}, {"tnETOS", {NULL}, 377, "udp"}, {"dsETOS", {NULL}, 378, "tcp"}, {"dsETOS", {NULL}, 378, "udp"}, {"is99c", {NULL}, 379, "tcp"}, {"is99c", {NULL}, 379, "udp"}, {"is99s", {NULL}, 380, "tcp"}, {"is99s", {NULL}, 380, "udp"}, {"hp-collector", {NULL}, 381, "tcp"}, {"hp-collector", {NULL}, 381, "udp"}, {"hp-managed-node", {NULL}, 382, "tcp"}, {"hp-managed-node", {NULL}, 382, "udp"}, {"hp-alarm-mgr", {NULL}, 383, "tcp"}, {"hp-alarm-mgr", {NULL}, 383, "udp"}, {"arns", {NULL}, 384, "tcp"}, {"arns", {NULL}, 384, "udp"}, {"ibm-app", {NULL}, 385, "tcp"}, {"ibm-app", {NULL}, 385, "udp"}, {"asa", {NULL}, 386, "tcp"}, {"asa", {NULL}, 386, "udp"}, {"aurp", {NULL}, 387, "tcp"}, {"aurp", {NULL}, 387, "udp"}, {"unidata-ldm", {NULL}, 388, "tcp"}, {"unidata-ldm", {NULL}, 388, "udp"}, {"ldap", {NULL}, 389, "tcp"}, {"ldap", {NULL}, 389, "udp"}, {"uis", {NULL}, 390, "tcp"}, {"uis", {NULL}, 390, "udp"}, {"synotics-relay", {NULL}, 391, "tcp"}, {"synotics-relay", {NULL}, 391, "udp"}, {"synotics-broker", {NULL}, 392, "tcp"}, {"synotics-broker", {NULL}, 392, "udp"}, {"meta5", {NULL}, 393, "tcp"}, {"meta5", {NULL}, 393, "udp"}, {"embl-ndt", {NULL}, 394, "tcp"}, {"embl-ndt", {NULL}, 394, "udp"}, {"netcp", {NULL}, 395, "tcp"}, {"netcp", {NULL}, 395, "udp"}, {"netware-ip", {NULL}, 396, "tcp"}, {"netware-ip", {NULL}, 396, "udp"}, {"mptn", {NULL}, 397, "tcp"}, {"mptn", {NULL}, 397, "udp"}, {"kryptolan", {NULL}, 398, "tcp"}, {"kryptolan", {NULL}, 398, "udp"}, {"iso-tsap-c2", {NULL}, 399, "tcp"}, {"iso-tsap-c2", {NULL}, 399, "udp"}, {"osb-sd", {NULL}, 400, "tcp"}, {"osb-sd", {NULL}, 400, "udp"}, {"ups", {NULL}, 401, "tcp"}, {"ups", {NULL}, 401, "udp"}, {"genie", {NULL}, 402, "tcp"}, {"genie", {NULL}, 402, "udp"}, {"decap", {NULL}, 403, "tcp"}, {"decap", {NULL}, 403, "udp"}, {"nced", {NULL}, 404, "tcp"}, {"nced", {NULL}, 404, "udp"}, {"ncld", {NULL}, 405, "tcp"}, {"ncld", {NULL}, 405, "udp"}, {"imsp", {NULL}, 406, "tcp"}, {"imsp", {NULL}, 406, "udp"}, {"timbuktu", {NULL}, 407, "tcp"}, {"timbuktu", {NULL}, 407, "udp"}, {"prm-sm", {NULL}, 408, "tcp"}, {"prm-sm", {NULL}, 408, "udp"}, {"prm-nm", {NULL}, 409, "tcp"}, {"prm-nm", {NULL}, 409, "udp"}, {"decladebug", {NULL}, 410, "tcp"}, {"decladebug", {NULL}, 410, "udp"}, {"rmt", {NULL}, 411, "tcp"}, {"rmt", {NULL}, 411, "udp"}, {"synoptics-trap", {NULL}, 412, "tcp"}, {"synoptics-trap", {NULL}, 412, "udp"}, {"smsp", {NULL}, 413, "tcp"}, {"smsp", {NULL}, 413, "udp"}, {"infoseek", {NULL}, 414, "tcp"}, {"infoseek", {NULL}, 414, "udp"}, {"bnet", {NULL}, 415, "tcp"}, {"bnet", {NULL}, 415, "udp"}, {"silverplatter", {NULL}, 416, "tcp"}, {"silverplatter", {NULL}, 416, "udp"}, {"onmux", {NULL}, 417, "tcp"}, {"onmux", {NULL}, 417, "udp"}, {"hyper-g", {NULL}, 418, "tcp"}, {"hyper-g", {NULL}, 418, "udp"}, {"ariel1", {NULL}, 419, "tcp"}, {"ariel1", {NULL}, 419, "udp"}, {"smpte", {NULL}, 420, "tcp"}, {"smpte", {NULL}, 420, "udp"}, {"ariel2", {NULL}, 421, "tcp"}, {"ariel2", {NULL}, 421, "udp"}, {"ariel3", {NULL}, 422, "tcp"}, {"ariel3", {NULL}, 422, "udp"}, {"opc-job-start", {NULL}, 423, "tcp"}, {"opc-job-start", {NULL}, 423, "udp"}, {"opc-job-track", {NULL}, 424, "tcp"}, {"opc-job-track", {NULL}, 424, "udp"}, {"icad-el", {NULL}, 425, "tcp"}, {"icad-el", {NULL}, 425, "udp"}, {"smartsdp", {NULL}, 426, "tcp"}, {"smartsdp", {NULL}, 426, "udp"}, {"svrloc", {NULL}, 427, "tcp"}, {"svrloc", {NULL}, 427, "udp"}, {"ocs_cmu", {NULL}, 428, "tcp"}, {"ocs_cmu", {NULL}, 428, "udp"}, {"ocs_amu", {NULL}, 429, "tcp"}, {"ocs_amu", {NULL}, 429, "udp"}, {"utmpsd", {NULL}, 430, "tcp"}, {"utmpsd", {NULL}, 430, "udp"}, {"utmpcd", {NULL}, 431, "tcp"}, {"utmpcd", {NULL}, 431, "udp"}, {"iasd", {NULL}, 432, "tcp"}, {"iasd", {NULL}, 432, "udp"}, {"nnsp", {NULL}, 433, "tcp"}, {"nnsp", {NULL}, 433, "udp"}, {"mobileip-agent", {NULL}, 434, "tcp"}, {"mobileip-agent", {NULL}, 434, "udp"}, {"mobilip-mn", {NULL}, 435, "tcp"}, {"mobilip-mn", {NULL}, 435, "udp"}, {"dna-cml", {NULL}, 436, "tcp"}, {"dna-cml", {NULL}, 436, "udp"}, {"comscm", {NULL}, 437, "tcp"}, {"comscm", {NULL}, 437, "udp"}, {"dsfgw", {NULL}, 438, "tcp"}, {"dsfgw", {NULL}, 438, "udp"}, {"dasp", {NULL}, 439, "tcp"}, {"dasp", {NULL}, 439, "udp"}, {"sgcp", {NULL}, 440, "tcp"}, {"sgcp", {NULL}, 440, "udp"}, {"decvms-sysmgt", {NULL}, 441, "tcp"}, {"decvms-sysmgt", {NULL}, 441, "udp"}, {"cvc_hostd", {NULL}, 442, "tcp"}, {"cvc_hostd", {NULL}, 442, "udp"}, {"https", {NULL}, 443, "tcp"}, {"https", {NULL}, 443, "udp"}, {"https", {NULL}, 443, "sctp"}, {"snpp", {NULL}, 444, "tcp"}, {"snpp", {NULL}, 444, "udp"}, {"microsoft-ds", {NULL}, 445, "tcp"}, {"microsoft-ds", {NULL}, 445, "udp"}, {"ddm-rdb", {NULL}, 446, "tcp"}, {"ddm-rdb", {NULL}, 446, "udp"}, {"ddm-dfm", {NULL}, 447, "tcp"}, {"ddm-dfm", {NULL}, 447, "udp"}, {"ddm-ssl", {NULL}, 448, "tcp"}, {"ddm-ssl", {NULL}, 448, "udp"}, {"as-servermap", {NULL}, 449, "tcp"}, {"as-servermap", {NULL}, 449, "udp"}, {"tserver", {NULL}, 450, "tcp"}, {"tserver", {NULL}, 450, "udp"}, {"sfs-smp-net", {NULL}, 451, "tcp"}, {"sfs-smp-net", {NULL}, 451, "udp"}, {"sfs-config", {NULL}, 452, "tcp"}, {"sfs-config", {NULL}, 452, "udp"}, {"creativeserver", {NULL}, 453, "tcp"}, {"creativeserver", {NULL}, 453, "udp"}, {"contentserver", {NULL}, 454, "tcp"}, {"contentserver", {NULL}, 454, "udp"}, {"creativepartnr", {NULL}, 455, "tcp"}, {"creativepartnr", {NULL}, 455, "udp"}, {"macon-tcp", {NULL}, 456, "tcp"}, {"macon-udp", {NULL}, 456, "udp"}, {"scohelp", {NULL}, 457, "tcp"}, {"scohelp", {NULL}, 457, "udp"}, {"appleqtc", {NULL}, 458, "tcp"}, {"appleqtc", {NULL}, 458, "udp"}, {"ampr-rcmd", {NULL}, 459, "tcp"}, {"ampr-rcmd", {NULL}, 459, "udp"}, {"skronk", {NULL}, 460, "tcp"}, {"skronk", {NULL}, 460, "udp"}, {"datasurfsrv", {NULL}, 461, "tcp"}, {"datasurfsrv", {NULL}, 461, "udp"}, {"datasurfsrvsec", {NULL}, 462, "tcp"}, {"datasurfsrvsec", {NULL}, 462, "udp"}, {"alpes", {NULL}, 463, "tcp"}, {"alpes", {NULL}, 463, "udp"}, {"kpasswd", {NULL}, 464, "tcp"}, {"kpasswd", {NULL}, 464, "udp"}, {"urd", {NULL}, 465, "tcp"}, {"igmpv3lite", {NULL}, 465, "udp"}, {"digital-vrc", {NULL}, 466, "tcp"}, {"digital-vrc", {NULL}, 466, "udp"}, {"mylex-mapd", {NULL}, 467, "tcp"}, {"mylex-mapd", {NULL}, 467, "udp"}, {"photuris", {NULL}, 468, "tcp"}, {"photuris", {NULL}, 468, "udp"}, {"rcp", {NULL}, 469, "tcp"}, {"rcp", {NULL}, 469, "udp"}, {"scx-proxy", {NULL}, 470, "tcp"}, {"scx-proxy", {NULL}, 470, "udp"}, {"mondex", {NULL}, 471, "tcp"}, {"mondex", {NULL}, 471, "udp"}, {"ljk-login", {NULL}, 472, "tcp"}, {"ljk-login", {NULL}, 472, "udp"}, {"hybrid-pop", {NULL}, 473, "tcp"}, {"hybrid-pop", {NULL}, 473, "udp"}, {"tn-tl-w1", {NULL}, 474, "tcp"}, {"tn-tl-w2", {NULL}, 474, "udp"}, {"tcpnethaspsrv", {NULL}, 475, "tcp"}, {"tcpnethaspsrv", {NULL}, 475, "udp"}, {"tn-tl-fd1", {NULL}, 476, "tcp"}, {"tn-tl-fd1", {NULL}, 476, "udp"}, {"ss7ns", {NULL}, 477, "tcp"}, {"ss7ns", {NULL}, 477, "udp"}, {"spsc", {NULL}, 478, "tcp"}, {"spsc", {NULL}, 478, "udp"}, {"iafserver", {NULL}, 479, "tcp"}, {"iafserver", {NULL}, 479, "udp"}, {"iafdbase", {NULL}, 480, "tcp"}, {"iafdbase", {NULL}, 480, "udp"}, {"ph", {NULL}, 481, "tcp"}, {"ph", {NULL}, 481, "udp"}, {"bgs-nsi", {NULL}, 482, "tcp"}, {"bgs-nsi", {NULL}, 482, "udp"}, {"ulpnet", {NULL}, 483, "tcp"}, {"ulpnet", {NULL}, 483, "udp"}, {"integra-sme", {NULL}, 484, "tcp"}, {"integra-sme", {NULL}, 484, "udp"}, {"powerburst", {NULL}, 485, "tcp"}, {"powerburst", {NULL}, 485, "udp"}, {"avian", {NULL}, 486, "tcp"}, {"avian", {NULL}, 486, "udp"}, {"saft", {NULL}, 487, "tcp"}, {"saft", {NULL}, 487, "udp"}, {"gss-http", {NULL}, 488, "tcp"}, {"gss-http", {NULL}, 488, "udp"}, {"nest-protocol", {NULL}, 489, "tcp"}, {"nest-protocol", {NULL}, 489, "udp"}, {"micom-pfs", {NULL}, 490, "tcp"}, {"micom-pfs", {NULL}, 490, "udp"}, {"go-login", {NULL}, 491, "tcp"}, {"go-login", {NULL}, 491, "udp"}, {"ticf-1", {NULL}, 492, "tcp"}, {"ticf-1", {NULL}, 492, "udp"}, {"ticf-2", {NULL}, 493, "tcp"}, {"ticf-2", {NULL}, 493, "udp"}, {"pov-ray", {NULL}, 494, "tcp"}, {"pov-ray", {NULL}, 494, "udp"}, {"intecourier", {NULL}, 495, "tcp"}, {"intecourier", {NULL}, 495, "udp"}, {"pim-rp-disc", {NULL}, 496, "tcp"}, {"pim-rp-disc", {NULL}, 496, "udp"}, {"dantz", {NULL}, 497, "tcp"}, {"dantz", {NULL}, 497, "udp"}, {"siam", {NULL}, 498, "tcp"}, {"siam", {NULL}, 498, "udp"}, {"iso-ill", {NULL}, 499, "tcp"}, {"iso-ill", {NULL}, 499, "udp"}, {"isakmp", {NULL}, 500, "tcp"}, {"isakmp", {NULL}, 500, "udp"}, {"stmf", {NULL}, 501, "tcp"}, {"stmf", {NULL}, 501, "udp"}, {"asa-appl-proto", {NULL}, 502, "tcp"}, {"asa-appl-proto", {NULL}, 502, "udp"}, {"intrinsa", {NULL}, 503, "tcp"}, {"intrinsa", {NULL}, 503, "udp"}, {"citadel", {NULL}, 504, "tcp"}, {"citadel", {NULL}, 504, "udp"}, {"mailbox-lm", {NULL}, 505, "tcp"}, {"mailbox-lm", {NULL}, 505, "udp"}, {"ohimsrv", {NULL}, 506, "tcp"}, {"ohimsrv", {NULL}, 506, "udp"}, {"crs", {NULL}, 507, "tcp"}, {"crs", {NULL}, 507, "udp"}, {"xvttp", {NULL}, 508, "tcp"}, {"xvttp", {NULL}, 508, "udp"}, {"snare", {NULL}, 509, "tcp"}, {"snare", {NULL}, 509, "udp"}, {"fcp", {NULL}, 510, "tcp"}, {"fcp", {NULL}, 510, "udp"}, {"passgo", {NULL}, 511, "tcp"}, {"passgo", {NULL}, 511, "udp"}, {"exec", {NULL}, 512, "tcp"}, {"comsat", {NULL}, 512, "udp"}, {"biff", {NULL}, 512, "udp"}, {"login", {NULL}, 513, "tcp"}, {"who", {NULL}, 513, "udp"}, {"shell", {NULL}, 514, "tcp"}, {"syslog", {NULL}, 514, "udp"}, {"printer", {NULL}, 515, "tcp"}, {"printer", {NULL}, 515, "udp"}, {"videotex", {NULL}, 516, "tcp"}, {"videotex", {NULL}, 516, "udp"}, {"talk", {NULL}, 517, "tcp"}, {"talk", {NULL}, 517, "udp"}, {"ntalk", {NULL}, 518, "tcp"}, {"ntalk", {NULL}, 518, "udp"}, {"utime", {NULL}, 519, "tcp"}, {"utime", {NULL}, 519, "udp"}, {"efs", {NULL}, 520, "tcp"}, {"router", {NULL}, 520, "udp"}, {"ripng", {NULL}, 521, "tcp"}, {"ripng", {NULL}, 521, "udp"}, {"ulp", {NULL}, 522, "tcp"}, {"ulp", {NULL}, 522, "udp"}, {"ibm-db2", {NULL}, 523, "tcp"}, {"ibm-db2", {NULL}, 523, "udp"}, {"ncp", {NULL}, 524, "tcp"}, {"ncp", {NULL}, 524, "udp"}, {"timed", {NULL}, 525, "tcp"}, {"timed", {NULL}, 525, "udp"}, {"tempo", {NULL}, 526, "tcp"}, {"tempo", {NULL}, 526, "udp"}, {"stx", {NULL}, 527, "tcp"}, {"stx", {NULL}, 527, "udp"}, {"custix", {NULL}, 528, "tcp"}, {"custix", {NULL}, 528, "udp"}, {"irc-serv", {NULL}, 529, "tcp"}, {"irc-serv", {NULL}, 529, "udp"}, {"courier", {NULL}, 530, "tcp"}, {"courier", {NULL}, 530, "udp"}, {"conference", {NULL}, 531, "tcp"}, {"conference", {NULL}, 531, "udp"}, {"netnews", {NULL}, 532, "tcp"}, {"netnews", {NULL}, 532, "udp"}, {"netwall", {NULL}, 533, "tcp"}, {"netwall", {NULL}, 533, "udp"}, {"windream", {NULL}, 534, "tcp"}, {"windream", {NULL}, 534, "udp"}, {"iiop", {NULL}, 535, "tcp"}, {"iiop", {NULL}, 535, "udp"}, {"opalis-rdv", {NULL}, 536, "tcp"}, {"opalis-rdv", {NULL}, 536, "udp"}, {"nmsp", {NULL}, 537, "tcp"}, {"nmsp", {NULL}, 537, "udp"}, {"gdomap", {NULL}, 538, "tcp"}, {"gdomap", {NULL}, 538, "udp"}, {"apertus-ldp", {NULL}, 539, "tcp"}, {"apertus-ldp", {NULL}, 539, "udp"}, {"uucp", {NULL}, 540, "tcp"}, {"uucp", {NULL}, 540, "udp"}, {"uucp-rlogin", {NULL}, 541, "tcp"}, {"uucp-rlogin", {NULL}, 541, "udp"}, {"commerce", {NULL}, 542, "tcp"}, {"commerce", {NULL}, 542, "udp"}, {"klogin", {NULL}, 543, "tcp"}, {"klogin", {NULL}, 543, "udp"}, {"kshell", {NULL}, 544, "tcp"}, {"kshell", {NULL}, 544, "udp"}, {"appleqtcsrvr", {NULL}, 545, "tcp"}, {"appleqtcsrvr", {NULL}, 545, "udp"}, {"dhcpv6-client", {NULL}, 546, "tcp"}, {"dhcpv6-client", {NULL}, 546, "udp"}, {"dhcpv6-server", {NULL}, 547, "tcp"}, {"dhcpv6-server", {NULL}, 547, "udp"}, {"afpovertcp", {NULL}, 548, "tcp"}, {"afpovertcp", {NULL}, 548, "udp"}, {"idfp", {NULL}, 549, "tcp"}, {"idfp", {NULL}, 549, "udp"}, {"new-rwho", {NULL}, 550, "tcp"}, {"new-rwho", {NULL}, 550, "udp"}, {"cybercash", {NULL}, 551, "tcp"}, {"cybercash", {NULL}, 551, "udp"}, {"devshr-nts", {NULL}, 552, "tcp"}, {"devshr-nts", {NULL}, 552, "udp"}, {"pirp", {NULL}, 553, "tcp"}, {"pirp", {NULL}, 553, "udp"}, {"rtsp", {NULL}, 554, "tcp"}, {"rtsp", {NULL}, 554, "udp"}, {"dsf", {NULL}, 555, "tcp"}, {"dsf", {NULL}, 555, "udp"}, {"remotefs", {NULL}, 556, "tcp"}, {"remotefs", {NULL}, 556, "udp"}, {"openvms-sysipc", {NULL}, 557, "tcp"}, {"openvms-sysipc", {NULL}, 557, "udp"}, {"sdnskmp", {NULL}, 558, "tcp"}, {"sdnskmp", {NULL}, 558, "udp"}, {"teedtap", {NULL}, 559, "tcp"}, {"teedtap", {NULL}, 559, "udp"}, {"rmonitor", {NULL}, 560, "tcp"}, {"rmonitor", {NULL}, 560, "udp"}, {"monitor", {NULL}, 561, "tcp"}, {"monitor", {NULL}, 561, "udp"}, {"chshell", {NULL}, 562, "tcp"}, {"chshell", {NULL}, 562, "udp"}, {"nntps", {NULL}, 563, "tcp"}, {"nntps", {NULL}, 563, "udp"}, {"9pfs", {NULL}, 564, "tcp"}, {"9pfs", {NULL}, 564, "udp"}, {"whoami", {NULL}, 565, "tcp"}, {"whoami", {NULL}, 565, "udp"}, {"streettalk", {NULL}, 566, "tcp"}, {"streettalk", {NULL}, 566, "udp"}, {"banyan-rpc", {NULL}, 567, "tcp"}, {"banyan-rpc", {NULL}, 567, "udp"}, {"ms-shuttle", {NULL}, 568, "tcp"}, {"ms-shuttle", {NULL}, 568, "udp"}, {"ms-rome", {NULL}, 569, "tcp"}, {"ms-rome", {NULL}, 569, "udp"}, {"meter", {NULL}, 570, "tcp"}, {"meter", {NULL}, 570, "udp"}, {"meter", {NULL}, 571, "tcp"}, {"meter", {NULL}, 571, "udp"}, {"sonar", {NULL}, 572, "tcp"}, {"sonar", {NULL}, 572, "udp"}, {"banyan-vip", {NULL}, 573, "tcp"}, {"banyan-vip", {NULL}, 573, "udp"}, {"ftp-agent", {NULL}, 574, "tcp"}, {"ftp-agent", {NULL}, 574, "udp"}, {"vemmi", {NULL}, 575, "tcp"}, {"vemmi", {NULL}, 575, "udp"}, {"ipcd", {NULL}, 576, "tcp"}, {"ipcd", {NULL}, 576, "udp"}, {"vnas", {NULL}, 577, "tcp"}, {"vnas", {NULL}, 577, "udp"}, {"ipdd", {NULL}, 578, "tcp"}, {"ipdd", {NULL}, 578, "udp"}, {"decbsrv", {NULL}, 579, "tcp"}, {"decbsrv", {NULL}, 579, "udp"}, {"sntp-heartbeat", {NULL}, 580, "tcp"}, {"sntp-heartbeat", {NULL}, 580, "udp"}, {"bdp", {NULL}, 581, "tcp"}, {"bdp", {NULL}, 581, "udp"}, {"scc-security", {NULL}, 582, "tcp"}, {"scc-security", {NULL}, 582, "udp"}, {"philips-vc", {NULL}, 583, "tcp"}, {"philips-vc", {NULL}, 583, "udp"}, {"keyserver", {NULL}, 584, "tcp"}, {"keyserver", {NULL}, 584, "udp"}, {"password-chg", {NULL}, 586, "tcp"}, {"password-chg", {NULL}, 586, "udp"}, {"submission", {NULL}, 587, "tcp"}, {"submission", {NULL}, 587, "udp"}, {"cal", {NULL}, 588, "tcp"}, {"cal", {NULL}, 588, "udp"}, {"eyelink", {NULL}, 589, "tcp"}, {"eyelink", {NULL}, 589, "udp"}, {"tns-cml", {NULL}, 590, "tcp"}, {"tns-cml", {NULL}, 590, "udp"}, {"http-alt", {NULL}, 591, "tcp"}, {"http-alt", {NULL}, 591, "udp"}, {"eudora-set", {NULL}, 592, "tcp"}, {"eudora-set", {NULL}, 592, "udp"}, {"http-rpc-epmap", {NULL}, 593, "tcp"}, {"http-rpc-epmap", {NULL}, 593, "udp"}, {"tpip", {NULL}, 594, "tcp"}, {"tpip", {NULL}, 594, "udp"}, {"cab-protocol", {NULL}, 595, "tcp"}, {"cab-protocol", {NULL}, 595, "udp"}, {"smsd", {NULL}, 596, "tcp"}, {"smsd", {NULL}, 596, "udp"}, {"ptcnameservice", {NULL}, 597, "tcp"}, {"ptcnameservice", {NULL}, 597, "udp"}, {"sco-websrvrmg3", {NULL}, 598, "tcp"}, {"sco-websrvrmg3", {NULL}, 598, "udp"}, {"acp", {NULL}, 599, "tcp"}, {"acp", {NULL}, 599, "udp"}, {"ipcserver", {NULL}, 600, "tcp"}, {"ipcserver", {NULL}, 600, "udp"}, {"syslog-conn", {NULL}, 601, "tcp"}, {"syslog-conn", {NULL}, 601, "udp"}, {"xmlrpc-beep", {NULL}, 602, "tcp"}, {"xmlrpc-beep", {NULL}, 602, "udp"}, {"idxp", {NULL}, 603, "tcp"}, {"idxp", {NULL}, 603, "udp"}, {"tunnel", {NULL}, 604, "tcp"}, {"tunnel", {NULL}, 604, "udp"}, {"soap-beep", {NULL}, 605, "tcp"}, {"soap-beep", {NULL}, 605, "udp"}, {"urm", {NULL}, 606, "tcp"}, {"urm", {NULL}, 606, "udp"}, {"nqs", {NULL}, 607, "tcp"}, {"nqs", {NULL}, 607, "udp"}, {"sift-uft", {NULL}, 608, "tcp"}, {"sift-uft", {NULL}, 608, "udp"}, {"npmp-trap", {NULL}, 609, "tcp"}, {"npmp-trap", {NULL}, 609, "udp"}, {"npmp-local", {NULL}, 610, "tcp"}, {"npmp-local", {NULL}, 610, "udp"}, {"npmp-gui", {NULL}, 611, "tcp"}, {"npmp-gui", {NULL}, 611, "udp"}, {"hmmp-ind", {NULL}, 612, "tcp"}, {"hmmp-ind", {NULL}, 612, "udp"}, {"hmmp-op", {NULL}, 613, "tcp"}, {"hmmp-op", {NULL}, 613, "udp"}, {"sshell", {NULL}, 614, "tcp"}, {"sshell", {NULL}, 614, "udp"}, {"sco-inetmgr", {NULL}, 615, "tcp"}, {"sco-inetmgr", {NULL}, 615, "udp"}, {"sco-sysmgr", {NULL}, 616, "tcp"}, {"sco-sysmgr", {NULL}, 616, "udp"}, {"sco-dtmgr", {NULL}, 617, "tcp"}, {"sco-dtmgr", {NULL}, 617, "udp"}, {"dei-icda", {NULL}, 618, "tcp"}, {"dei-icda", {NULL}, 618, "udp"}, {"compaq-evm", {NULL}, 619, "tcp"}, {"compaq-evm", {NULL}, 619, "udp"}, {"sco-websrvrmgr", {NULL}, 620, "tcp"}, {"sco-websrvrmgr", {NULL}, 620, "udp"}, {"escp-ip", {NULL}, 621, "tcp"}, {"escp-ip", {NULL}, 621, "udp"}, {"collaborator", {NULL}, 622, "tcp"}, {"collaborator", {NULL}, 622, "udp"}, {"oob-ws-http", {NULL}, 623, "tcp"}, {"asf-rmcp", {NULL}, 623, "udp"}, {"cryptoadmin", {NULL}, 624, "tcp"}, {"cryptoadmin", {NULL}, 624, "udp"}, {"dec_dlm", {NULL}, 625, "tcp"}, {"dec_dlm", {NULL}, 625, "udp"}, {"asia", {NULL}, 626, "tcp"}, {"asia", {NULL}, 626, "udp"}, {"passgo-tivoli", {NULL}, 627, "tcp"}, {"passgo-tivoli", {NULL}, 627, "udp"}, {"qmqp", {NULL}, 628, "tcp"}, {"qmqp", {NULL}, 628, "udp"}, {"3com-amp3", {NULL}, 629, "tcp"}, {"3com-amp3", {NULL}, 629, "udp"}, {"rda", {NULL}, 630, "tcp"}, {"rda", {NULL}, 630, "udp"}, {"ipp", {NULL}, 631, "tcp"}, {"ipp", {NULL}, 631, "udp"}, {"bmpp", {NULL}, 632, "tcp"}, {"bmpp", {NULL}, 632, "udp"}, {"servstat", {NULL}, 633, "tcp"}, {"servstat", {NULL}, 633, "udp"}, {"ginad", {NULL}, 634, "tcp"}, {"ginad", {NULL}, 634, "udp"}, {"rlzdbase", {NULL}, 635, "tcp"}, {"rlzdbase", {NULL}, 635, "udp"}, {"ldaps", {NULL}, 636, "tcp"}, {"ldaps", {NULL}, 636, "udp"}, {"lanserver", {NULL}, 637, "tcp"}, {"lanserver", {NULL}, 637, "udp"}, {"mcns-sec", {NULL}, 638, "tcp"}, {"mcns-sec", {NULL}, 638, "udp"}, {"msdp", {NULL}, 639, "tcp"}, {"msdp", {NULL}, 639, "udp"}, {"entrust-sps", {NULL}, 640, "tcp"}, {"entrust-sps", {NULL}, 640, "udp"}, {"repcmd", {NULL}, 641, "tcp"}, {"repcmd", {NULL}, 641, "udp"}, {"esro-emsdp", {NULL}, 642, "tcp"}, {"esro-emsdp", {NULL}, 642, "udp"}, {"sanity", {NULL}, 643, "tcp"}, {"sanity", {NULL}, 643, "udp"}, {"dwr", {NULL}, 644, "tcp"}, {"dwr", {NULL}, 644, "udp"}, {"pssc", {NULL}, 645, "tcp"}, {"pssc", {NULL}, 645, "udp"}, {"ldp", {NULL}, 646, "tcp"}, {"ldp", {NULL}, 646, "udp"}, {"dhcp-failover", {NULL}, 647, "tcp"}, {"dhcp-failover", {NULL}, 647, "udp"}, {"rrp", {NULL}, 648, "tcp"}, {"rrp", {NULL}, 648, "udp"}, {"cadview-3d", {NULL}, 649, "tcp"}, {"cadview-3d", {NULL}, 649, "udp"}, {"obex", {NULL}, 650, "tcp"}, {"obex", {NULL}, 650, "udp"}, {"ieee-mms", {NULL}, 651, "tcp"}, {"ieee-mms", {NULL}, 651, "udp"}, {"hello-port", {NULL}, 652, "tcp"}, {"hello-port", {NULL}, 652, "udp"}, {"repscmd", {NULL}, 653, "tcp"}, {"repscmd", {NULL}, 653, "udp"}, {"aodv", {NULL}, 654, "tcp"}, {"aodv", {NULL}, 654, "udp"}, {"tinc", {NULL}, 655, "tcp"}, {"tinc", {NULL}, 655, "udp"}, {"spmp", {NULL}, 656, "tcp"}, {"spmp", {NULL}, 656, "udp"}, {"rmc", {NULL}, 657, "tcp"}, {"rmc", {NULL}, 657, "udp"}, {"tenfold", {NULL}, 658, "tcp"}, {"tenfold", {NULL}, 658, "udp"}, {"mac-srvr-admin", {NULL}, 660, "tcp"}, {"mac-srvr-admin", {NULL}, 660, "udp"}, {"hap", {NULL}, 661, "tcp"}, {"hap", {NULL}, 661, "udp"}, {"pftp", {NULL}, 662, "tcp"}, {"pftp", {NULL}, 662, "udp"}, {"purenoise", {NULL}, 663, "tcp"}, {"purenoise", {NULL}, 663, "udp"}, {"oob-ws-https", {NULL}, 664, "tcp"}, {"asf-secure-rmcp", {NULL}, 664, "udp"}, {"sun-dr", {NULL}, 665, "tcp"}, {"sun-dr", {NULL}, 665, "udp"}, {"mdqs", {NULL}, 666, "tcp"}, {"mdqs", {NULL}, 666, "udp"}, {"doom", {NULL}, 666, "tcp"}, {"doom", {NULL}, 666, "udp"}, {"disclose", {NULL}, 667, "tcp"}, {"disclose", {NULL}, 667, "udp"}, {"mecomm", {NULL}, 668, "tcp"}, {"mecomm", {NULL}, 668, "udp"}, {"meregister", {NULL}, 669, "tcp"}, {"meregister", {NULL}, 669, "udp"}, {"vacdsm-sws", {NULL}, 670, "tcp"}, {"vacdsm-sws", {NULL}, 670, "udp"}, {"vacdsm-app", {NULL}, 671, "tcp"}, {"vacdsm-app", {NULL}, 671, "udp"}, {"vpps-qua", {NULL}, 672, "tcp"}, {"vpps-qua", {NULL}, 672, "udp"}, {"cimplex", {NULL}, 673, "tcp"}, {"cimplex", {NULL}, 673, "udp"}, {"acap", {NULL}, 674, "tcp"}, {"acap", {NULL}, 674, "udp"}, {"dctp", {NULL}, 675, "tcp"}, {"dctp", {NULL}, 675, "udp"}, {"vpps-via", {NULL}, 676, "tcp"}, {"vpps-via", {NULL}, 676, "udp"}, {"vpp", {NULL}, 677, "tcp"}, {"vpp", {NULL}, 677, "udp"}, {"ggf-ncp", {NULL}, 678, "tcp"}, {"ggf-ncp", {NULL}, 678, "udp"}, {"mrm", {NULL}, 679, "tcp"}, {"mrm", {NULL}, 679, "udp"}, {"entrust-aaas", {NULL}, 680, "tcp"}, {"entrust-aaas", {NULL}, 680, "udp"}, {"entrust-aams", {NULL}, 681, "tcp"}, {"entrust-aams", {NULL}, 681, "udp"}, {"xfr", {NULL}, 682, "tcp"}, {"xfr", {NULL}, 682, "udp"}, {"corba-iiop", {NULL}, 683, "tcp"}, {"corba-iiop", {NULL}, 683, "udp"}, {"corba-iiop-ssl", {NULL}, 684, "tcp"}, {"corba-iiop-ssl", {NULL}, 684, "udp"}, {"mdc-portmapper", {NULL}, 685, "tcp"}, {"mdc-portmapper", {NULL}, 685, "udp"}, {"hcp-wismar", {NULL}, 686, "tcp"}, {"hcp-wismar", {NULL}, 686, "udp"}, {"asipregistry", {NULL}, 687, "tcp"}, {"asipregistry", {NULL}, 687, "udp"}, {"realm-rusd", {NULL}, 688, "tcp"}, {"realm-rusd", {NULL}, 688, "udp"}, {"nmap", {NULL}, 689, "tcp"}, {"nmap", {NULL}, 689, "udp"}, {"vatp", {NULL}, 690, "tcp"}, {"vatp", {NULL}, 690, "udp"}, {"msexch-routing", {NULL}, 691, "tcp"}, {"msexch-routing", {NULL}, 691, "udp"}, {"hyperwave-isp", {NULL}, 692, "tcp"}, {"hyperwave-isp", {NULL}, 692, "udp"}, {"connendp", {NULL}, 693, "tcp"}, {"connendp", {NULL}, 693, "udp"}, {"ha-cluster", {NULL}, 694, "tcp"}, {"ha-cluster", {NULL}, 694, "udp"}, {"ieee-mms-ssl", {NULL}, 695, "tcp"}, {"ieee-mms-ssl", {NULL}, 695, "udp"}, {"rushd", {NULL}, 696, "tcp"}, {"rushd", {NULL}, 696, "udp"}, {"uuidgen", {NULL}, 697, "tcp"}, {"uuidgen", {NULL}, 697, "udp"}, {"olsr", {NULL}, 698, "tcp"}, {"olsr", {NULL}, 698, "udp"}, {"accessnetwork", {NULL}, 699, "tcp"}, {"accessnetwork", {NULL}, 699, "udp"}, {"epp", {NULL}, 700, "tcp"}, {"epp", {NULL}, 700, "udp"}, {"lmp", {NULL}, 701, "tcp"}, {"lmp", {NULL}, 701, "udp"}, {"iris-beep", {NULL}, 702, "tcp"}, {"iris-beep", {NULL}, 702, "udp"}, {"elcsd", {NULL}, 704, "tcp"}, {"elcsd", {NULL}, 704, "udp"}, {"agentx", {NULL}, 705, "tcp"}, {"agentx", {NULL}, 705, "udp"}, {"silc", {NULL}, 706, "tcp"}, {"silc", {NULL}, 706, "udp"}, {"borland-dsj", {NULL}, 707, "tcp"}, {"borland-dsj", {NULL}, 707, "udp"}, {"entrust-kmsh", {NULL}, 709, "tcp"}, {"entrust-kmsh", {NULL}, 709, "udp"}, {"entrust-ash", {NULL}, 710, "tcp"}, {"entrust-ash", {NULL}, 710, "udp"}, {"cisco-tdp", {NULL}, 711, "tcp"}, {"cisco-tdp", {NULL}, 711, "udp"}, {"tbrpf", {NULL}, 712, "tcp"}, {"tbrpf", {NULL}, 712, "udp"}, {"iris-xpc", {NULL}, 713, "tcp"}, {"iris-xpc", {NULL}, 713, "udp"}, {"iris-xpcs", {NULL}, 714, "tcp"}, {"iris-xpcs", {NULL}, 714, "udp"}, {"iris-lwz", {NULL}, 715, "tcp"}, {"iris-lwz", {NULL}, 715, "udp"}, {"pana", {NULL}, 716, "udp"}, {"netviewdm1", {NULL}, 729, "tcp"}, {"netviewdm1", {NULL}, 729, "udp"}, {"netviewdm2", {NULL}, 730, "tcp"}, {"netviewdm2", {NULL}, 730, "udp"}, {"netviewdm3", {NULL}, 731, "tcp"}, {"netviewdm3", {NULL}, 731, "udp"}, {"netgw", {NULL}, 741, "tcp"}, {"netgw", {NULL}, 741, "udp"}, {"netrcs", {NULL}, 742, "tcp"}, {"netrcs", {NULL}, 742, "udp"}, {"flexlm", {NULL}, 744, "tcp"}, {"flexlm", {NULL}, 744, "udp"}, {"fujitsu-dev", {NULL}, 747, "tcp"}, {"fujitsu-dev", {NULL}, 747, "udp"}, {"ris-cm", {NULL}, 748, "tcp"}, {"ris-cm", {NULL}, 748, "udp"}, {"kerberos-adm", {NULL}, 749, "tcp"}, {"kerberos-adm", {NULL}, 749, "udp"}, {"rfile", {NULL}, 750, "tcp"}, {"loadav", {NULL}, 750, "udp"}, {"kerberos-iv", {NULL}, 750, "udp"}, {"pump", {NULL}, 751, "tcp"}, {"pump", {NULL}, 751, "udp"}, {"qrh", {NULL}, 752, "tcp"}, {"qrh", {NULL}, 752, "udp"}, {"rrh", {NULL}, 753, "tcp"}, {"rrh", {NULL}, 753, "udp"}, {"tell", {NULL}, 754, "tcp"}, {"tell", {NULL}, 754, "udp"}, {"nlogin", {NULL}, 758, "tcp"}, {"nlogin", {NULL}, 758, "udp"}, {"con", {NULL}, 759, "tcp"}, {"con", {NULL}, 759, "udp"}, {"ns", {NULL}, 760, "tcp"}, {"ns", {NULL}, 760, "udp"}, {"rxe", {NULL}, 761, "tcp"}, {"rxe", {NULL}, 761, "udp"}, {"quotad", {NULL}, 762, "tcp"}, {"quotad", {NULL}, 762, "udp"}, {"cycleserv", {NULL}, 763, "tcp"}, {"cycleserv", {NULL}, 763, "udp"}, {"omserv", {NULL}, 764, "tcp"}, {"omserv", {NULL}, 764, "udp"}, {"webster", {NULL}, 765, "tcp"}, {"webster", {NULL}, 765, "udp"}, {"phonebook", {NULL}, 767, "tcp"}, {"phonebook", {NULL}, 767, "udp"}, {"vid", {NULL}, 769, "tcp"}, {"vid", {NULL}, 769, "udp"}, {"cadlock", {NULL}, 770, "tcp"}, {"cadlock", {NULL}, 770, "udp"}, {"rtip", {NULL}, 771, "tcp"}, {"rtip", {NULL}, 771, "udp"}, {"cycleserv2", {NULL}, 772, "tcp"}, {"cycleserv2", {NULL}, 772, "udp"}, {"submit", {NULL}, 773, "tcp"}, {"notify", {NULL}, 773, "udp"}, {"rpasswd", {NULL}, 774, "tcp"}, {"acmaint_dbd", {NULL}, 774, "udp"}, {"entomb", {NULL}, 775, "tcp"}, {"acmaint_transd", {NULL}, 775, "udp"}, {"wpages", {NULL}, 776, "tcp"}, {"wpages", {NULL}, 776, "udp"}, {"multiling-http", {NULL}, 777, "tcp"}, {"multiling-http", {NULL}, 777, "udp"}, {"wpgs", {NULL}, 780, "tcp"}, {"wpgs", {NULL}, 780, "udp"}, {"mdbs_daemon", {NULL}, 800, "tcp"}, {"mdbs_daemon", {NULL}, 800, "udp"}, {"device", {NULL}, 801, "tcp"}, {"device", {NULL}, 801, "udp"}, {"fcp-udp", {NULL}, 810, "tcp"}, {"fcp-udp", {NULL}, 810, "udp"}, {"itm-mcell-s", {NULL}, 828, "tcp"}, {"itm-mcell-s", {NULL}, 828, "udp"}, {"pkix-3-ca-ra", {NULL}, 829, "tcp"}, {"pkix-3-ca-ra", {NULL}, 829, "udp"}, {"netconf-ssh", {NULL}, 830, "tcp"}, {"netconf-ssh", {NULL}, 830, "udp"}, {"netconf-beep", {NULL}, 831, "tcp"}, {"netconf-beep", {NULL}, 831, "udp"}, {"netconfsoaphttp", {NULL}, 832, "tcp"}, {"netconfsoaphttp", {NULL}, 832, "udp"}, {"netconfsoapbeep", {NULL}, 833, "tcp"}, {"netconfsoapbeep", {NULL}, 833, "udp"}, {"dhcp-failover2", {NULL}, 847, "tcp"}, {"dhcp-failover2", {NULL}, 847, "udp"}, {"gdoi", {NULL}, 848, "tcp"}, {"gdoi", {NULL}, 848, "udp"}, {"iscsi", {NULL}, 860, "tcp"}, {"iscsi", {NULL}, 860, "udp"}, {"owamp-control", {NULL}, 861, "tcp"}, {"owamp-control", {NULL}, 861, "udp"}, {"twamp-control", {NULL}, 862, "tcp"}, {"twamp-control", {NULL}, 862, "udp"}, {"rsync", {NULL}, 873, "tcp"}, {"rsync", {NULL}, 873, "udp"}, {"iclcnet-locate", {NULL}, 886, "tcp"}, {"iclcnet-locate", {NULL}, 886, "udp"}, {"iclcnet_svinfo", {NULL}, 887, "tcp"}, {"iclcnet_svinfo", {NULL}, 887, "udp"}, {"accessbuilder", {NULL}, 888, "tcp"}, {"accessbuilder", {NULL}, 888, "udp"}, {"cddbp", {NULL}, 888, "tcp"}, {"omginitialrefs", {NULL}, 900, "tcp"}, {"omginitialrefs", {NULL}, 900, "udp"}, {"smpnameres", {NULL}, 901, "tcp"}, {"smpnameres", {NULL}, 901, "udp"}, {"ideafarm-door", {NULL}, 902, "tcp"}, {"ideafarm-door", {NULL}, 902, "udp"}, {"ideafarm-panic", {NULL}, 903, "tcp"}, {"ideafarm-panic", {NULL}, 903, "udp"}, {"kink", {NULL}, 910, "tcp"}, {"kink", {NULL}, 910, "udp"}, {"xact-backup", {NULL}, 911, "tcp"}, {"xact-backup", {NULL}, 911, "udp"}, {"apex-mesh", {NULL}, 912, "tcp"}, {"apex-mesh", {NULL}, 912, "udp"}, {"apex-edge", {NULL}, 913, "tcp"}, {"apex-edge", {NULL}, 913, "udp"}, {"ftps-data", {NULL}, 989, "tcp"}, {"ftps-data", {NULL}, 989, "udp"}, {"ftps", {NULL}, 990, "tcp"}, {"ftps", {NULL}, 990, "udp"}, {"nas", {NULL}, 991, "tcp"}, {"nas", {NULL}, 991, "udp"}, {"telnets", {NULL}, 992, "tcp"}, {"telnets", {NULL}, 992, "udp"}, {"imaps", {NULL}, 993, "tcp"}, {"imaps", {NULL}, 993, "udp"}, {"ircs", {NULL}, 994, "tcp"}, {"ircs", {NULL}, 994, "udp"}, {"pop3s", {NULL}, 995, "tcp"}, {"pop3s", {NULL}, 995, "udp"}, {"vsinet", {NULL}, 996, "tcp"}, {"vsinet", {NULL}, 996, "udp"}, {"maitrd", {NULL}, 997, "tcp"}, {"maitrd", {NULL}, 997, "udp"}, {"busboy", {NULL}, 998, "tcp"}, {"puparp", {NULL}, 998, "udp"}, {"garcon", {NULL}, 999, "tcp"}, {"applix", {NULL}, 999, "udp"}, {"puprouter", {NULL}, 999, "tcp"}, {"puprouter", {NULL}, 999, "udp"}, {"cadlock2", {NULL}, 1000, "tcp"}, {"cadlock2", {NULL}, 1000, "udp"}, {"surf", {NULL}, 1010, "tcp"}, {"surf", {NULL}, 1010, "udp"}, {"exp1", {NULL}, 1021, "tcp"}, {"exp1", {NULL}, 1021, "udp"}, {"exp2", {NULL}, 1022, "tcp"}, {"exp2", {NULL}, 1022, "udp"}, #endif /* USE_IANA_WELL_KNOWN_PORTS */ #ifdef USE_IANA_REGISTERED_PORTS {"blackjack", {NULL}, 1025, "tcp"}, {"blackjack", {NULL}, 1025, "udp"}, {"cap", {NULL}, 1026, "tcp"}, {"cap", {NULL}, 1026, "udp"}, {"solid-mux", {NULL}, 1029, "tcp"}, {"solid-mux", {NULL}, 1029, "udp"}, {"iad1", {NULL}, 1030, "tcp"}, {"iad1", {NULL}, 1030, "udp"}, {"iad2", {NULL}, 1031, "tcp"}, {"iad2", {NULL}, 1031, "udp"}, {"iad3", {NULL}, 1032, "tcp"}, {"iad3", {NULL}, 1032, "udp"}, {"netinfo-local", {NULL}, 1033, "tcp"}, {"netinfo-local", {NULL}, 1033, "udp"}, {"activesync", {NULL}, 1034, "tcp"}, {"activesync", {NULL}, 1034, "udp"}, {"mxxrlogin", {NULL}, 1035, "tcp"}, {"mxxrlogin", {NULL}, 1035, "udp"}, {"nsstp", {NULL}, 1036, "tcp"}, {"nsstp", {NULL}, 1036, "udp"}, {"ams", {NULL}, 1037, "tcp"}, {"ams", {NULL}, 1037, "udp"}, {"mtqp", {NULL}, 1038, "tcp"}, {"mtqp", {NULL}, 1038, "udp"}, {"sbl", {NULL}, 1039, "tcp"}, {"sbl", {NULL}, 1039, "udp"}, {"netarx", {NULL}, 1040, "tcp"}, {"netarx", {NULL}, 1040, "udp"}, {"danf-ak2", {NULL}, 1041, "tcp"}, {"danf-ak2", {NULL}, 1041, "udp"}, {"afrog", {NULL}, 1042, "tcp"}, {"afrog", {NULL}, 1042, "udp"}, {"boinc-client", {NULL}, 1043, "tcp"}, {"boinc-client", {NULL}, 1043, "udp"}, {"dcutility", {NULL}, 1044, "tcp"}, {"dcutility", {NULL}, 1044, "udp"}, {"fpitp", {NULL}, 1045, "tcp"}, {"fpitp", {NULL}, 1045, "udp"}, {"wfremotertm", {NULL}, 1046, "tcp"}, {"wfremotertm", {NULL}, 1046, "udp"}, {"neod1", {NULL}, 1047, "tcp"}, {"neod1", {NULL}, 1047, "udp"}, {"neod2", {NULL}, 1048, "tcp"}, {"neod2", {NULL}, 1048, "udp"}, {"td-postman", {NULL}, 1049, "tcp"}, {"td-postman", {NULL}, 1049, "udp"}, {"cma", {NULL}, 1050, "tcp"}, {"cma", {NULL}, 1050, "udp"}, {"optima-vnet", {NULL}, 1051, "tcp"}, {"optima-vnet", {NULL}, 1051, "udp"}, {"ddt", {NULL}, 1052, "tcp"}, {"ddt", {NULL}, 1052, "udp"}, {"remote-as", {NULL}, 1053, "tcp"}, {"remote-as", {NULL}, 1053, "udp"}, {"brvread", {NULL}, 1054, "tcp"}, {"brvread", {NULL}, 1054, "udp"}, {"ansyslmd", {NULL}, 1055, "tcp"}, {"ansyslmd", {NULL}, 1055, "udp"}, {"vfo", {NULL}, 1056, "tcp"}, {"vfo", {NULL}, 1056, "udp"}, {"startron", {NULL}, 1057, "tcp"}, {"startron", {NULL}, 1057, "udp"}, {"nim", {NULL}, 1058, "tcp"}, {"nim", {NULL}, 1058, "udp"}, {"nimreg", {NULL}, 1059, "tcp"}, {"nimreg", {NULL}, 1059, "udp"}, {"polestar", {NULL}, 1060, "tcp"}, {"polestar", {NULL}, 1060, "udp"}, {"kiosk", {NULL}, 1061, "tcp"}, {"kiosk", {NULL}, 1061, "udp"}, {"veracity", {NULL}, 1062, "tcp"}, {"veracity", {NULL}, 1062, "udp"}, {"kyoceranetdev", {NULL}, 1063, "tcp"}, {"kyoceranetdev", {NULL}, 1063, "udp"}, {"jstel", {NULL}, 1064, "tcp"}, {"jstel", {NULL}, 1064, "udp"}, {"syscomlan", {NULL}, 1065, "tcp"}, {"syscomlan", {NULL}, 1065, "udp"}, {"fpo-fns", {NULL}, 1066, "tcp"}, {"fpo-fns", {NULL}, 1066, "udp"}, {"instl_boots", {NULL}, 1067, "tcp"}, {"instl_boots", {NULL}, 1067, "udp"}, {"instl_bootc", {NULL}, 1068, "tcp"}, {"instl_bootc", {NULL}, 1068, "udp"}, {"cognex-insight", {NULL}, 1069, "tcp"}, {"cognex-insight", {NULL}, 1069, "udp"}, {"gmrupdateserv", {NULL}, 1070, "tcp"}, {"gmrupdateserv", {NULL}, 1070, "udp"}, {"bsquare-voip", {NULL}, 1071, "tcp"}, {"bsquare-voip", {NULL}, 1071, "udp"}, {"cardax", {NULL}, 1072, "tcp"}, {"cardax", {NULL}, 1072, "udp"}, {"bridgecontrol", {NULL}, 1073, "tcp"}, {"bridgecontrol", {NULL}, 1073, "udp"}, {"warmspotMgmt", {NULL}, 1074, "tcp"}, {"warmspotMgmt", {NULL}, 1074, "udp"}, {"rdrmshc", {NULL}, 1075, "tcp"}, {"rdrmshc", {NULL}, 1075, "udp"}, {"dab-sti-c", {NULL}, 1076, "tcp"}, {"dab-sti-c", {NULL}, 1076, "udp"}, {"imgames", {NULL}, 1077, "tcp"}, {"imgames", {NULL}, 1077, "udp"}, {"avocent-proxy", {NULL}, 1078, "tcp"}, {"avocent-proxy", {NULL}, 1078, "udp"}, {"asprovatalk", {NULL}, 1079, "tcp"}, {"asprovatalk", {NULL}, 1079, "udp"}, {"socks", {NULL}, 1080, "tcp"}, {"socks", {NULL}, 1080, "udp"}, {"pvuniwien", {NULL}, 1081, "tcp"}, {"pvuniwien", {NULL}, 1081, "udp"}, {"amt-esd-prot", {NULL}, 1082, "tcp"}, {"amt-esd-prot", {NULL}, 1082, "udp"}, {"ansoft-lm-1", {NULL}, 1083, "tcp"}, {"ansoft-lm-1", {NULL}, 1083, "udp"}, {"ansoft-lm-2", {NULL}, 1084, "tcp"}, {"ansoft-lm-2", {NULL}, 1084, "udp"}, {"webobjects", {NULL}, 1085, "tcp"}, {"webobjects", {NULL}, 1085, "udp"}, {"cplscrambler-lg", {NULL}, 1086, "tcp"}, {"cplscrambler-lg", {NULL}, 1086, "udp"}, {"cplscrambler-in", {NULL}, 1087, "tcp"}, {"cplscrambler-in", {NULL}, 1087, "udp"}, {"cplscrambler-al", {NULL}, 1088, "tcp"}, {"cplscrambler-al", {NULL}, 1088, "udp"}, {"ff-annunc", {NULL}, 1089, "tcp"}, {"ff-annunc", {NULL}, 1089, "udp"}, {"ff-fms", {NULL}, 1090, "tcp"}, {"ff-fms", {NULL}, 1090, "udp"}, {"ff-sm", {NULL}, 1091, "tcp"}, {"ff-sm", {NULL}, 1091, "udp"}, {"obrpd", {NULL}, 1092, "tcp"}, {"obrpd", {NULL}, 1092, "udp"}, {"proofd", {NULL}, 1093, "tcp"}, {"proofd", {NULL}, 1093, "udp"}, {"rootd", {NULL}, 1094, "tcp"}, {"rootd", {NULL}, 1094, "udp"}, {"nicelink", {NULL}, 1095, "tcp"}, {"nicelink", {NULL}, 1095, "udp"}, {"cnrprotocol", {NULL}, 1096, "tcp"}, {"cnrprotocol", {NULL}, 1096, "udp"}, {"sunclustermgr", {NULL}, 1097, "tcp"}, {"sunclustermgr", {NULL}, 1097, "udp"}, {"rmiactivation", {NULL}, 1098, "tcp"}, {"rmiactivation", {NULL}, 1098, "udp"}, {"rmiregistry", {NULL}, 1099, "tcp"}, {"rmiregistry", {NULL}, 1099, "udp"}, {"mctp", {NULL}, 1100, "tcp"}, {"mctp", {NULL}, 1100, "udp"}, {"pt2-discover", {NULL}, 1101, "tcp"}, {"pt2-discover", {NULL}, 1101, "udp"}, {"adobeserver-1", {NULL}, 1102, "tcp"}, {"adobeserver-1", {NULL}, 1102, "udp"}, {"adobeserver-2", {NULL}, 1103, "tcp"}, {"adobeserver-2", {NULL}, 1103, "udp"}, {"xrl", {NULL}, 1104, "tcp"}, {"xrl", {NULL}, 1104, "udp"}, {"ftranhc", {NULL}, 1105, "tcp"}, {"ftranhc", {NULL}, 1105, "udp"}, {"isoipsigport-1", {NULL}, 1106, "tcp"}, {"isoipsigport-1", {NULL}, 1106, "udp"}, {"isoipsigport-2", {NULL}, 1107, "tcp"}, {"isoipsigport-2", {NULL}, 1107, "udp"}, {"ratio-adp", {NULL}, 1108, "tcp"}, {"ratio-adp", {NULL}, 1108, "udp"}, {"webadmstart", {NULL}, 1110, "tcp"}, {"nfsd-keepalive", {NULL}, 1110, "udp"}, {"lmsocialserver", {NULL}, 1111, "tcp"}, {"lmsocialserver", {NULL}, 1111, "udp"}, {"icp", {NULL}, 1112, "tcp"}, {"icp", {NULL}, 1112, "udp"}, {"ltp-deepspace", {NULL}, 1113, "tcp"}, {"ltp-deepspace", {NULL}, 1113, "udp"}, {"mini-sql", {NULL}, 1114, "tcp"}, {"mini-sql", {NULL}, 1114, "udp"}, {"ardus-trns", {NULL}, 1115, "tcp"}, {"ardus-trns", {NULL}, 1115, "udp"}, {"ardus-cntl", {NULL}, 1116, "tcp"}, {"ardus-cntl", {NULL}, 1116, "udp"}, {"ardus-mtrns", {NULL}, 1117, "tcp"}, {"ardus-mtrns", {NULL}, 1117, "udp"}, {"sacred", {NULL}, 1118, "tcp"}, {"sacred", {NULL}, 1118, "udp"}, {"bnetgame", {NULL}, 1119, "tcp"}, {"bnetgame", {NULL}, 1119, "udp"}, {"bnetfile", {NULL}, 1120, "tcp"}, {"bnetfile", {NULL}, 1120, "udp"}, {"rmpp", {NULL}, 1121, "tcp"}, {"rmpp", {NULL}, 1121, "udp"}, {"availant-mgr", {NULL}, 1122, "tcp"}, {"availant-mgr", {NULL}, 1122, "udp"}, {"murray", {NULL}, 1123, "tcp"}, {"murray", {NULL}, 1123, "udp"}, {"hpvmmcontrol", {NULL}, 1124, "tcp"}, {"hpvmmcontrol", {NULL}, 1124, "udp"}, {"hpvmmagent", {NULL}, 1125, "tcp"}, {"hpvmmagent", {NULL}, 1125, "udp"}, {"hpvmmdata", {NULL}, 1126, "tcp"}, {"hpvmmdata", {NULL}, 1126, "udp"}, {"kwdb-commn", {NULL}, 1127, "tcp"}, {"kwdb-commn", {NULL}, 1127, "udp"}, {"saphostctrl", {NULL}, 1128, "tcp"}, {"saphostctrl", {NULL}, 1128, "udp"}, {"saphostctrls", {NULL}, 1129, "tcp"}, {"saphostctrls", {NULL}, 1129, "udp"}, {"casp", {NULL}, 1130, "tcp"}, {"casp", {NULL}, 1130, "udp"}, {"caspssl", {NULL}, 1131, "tcp"}, {"caspssl", {NULL}, 1131, "udp"}, {"kvm-via-ip", {NULL}, 1132, "tcp"}, {"kvm-via-ip", {NULL}, 1132, "udp"}, {"dfn", {NULL}, 1133, "tcp"}, {"dfn", {NULL}, 1133, "udp"}, {"aplx", {NULL}, 1134, "tcp"}, {"aplx", {NULL}, 1134, "udp"}, {"omnivision", {NULL}, 1135, "tcp"}, {"omnivision", {NULL}, 1135, "udp"}, {"hhb-gateway", {NULL}, 1136, "tcp"}, {"hhb-gateway", {NULL}, 1136, "udp"}, {"trim", {NULL}, 1137, "tcp"}, {"trim", {NULL}, 1137, "udp"}, {"encrypted_admin", {NULL}, 1138, "tcp"}, {"encrypted_admin", {NULL}, 1138, "udp"}, {"evm", {NULL}, 1139, "tcp"}, {"evm", {NULL}, 1139, "udp"}, {"autonoc", {NULL}, 1140, "tcp"}, {"autonoc", {NULL}, 1140, "udp"}, {"mxomss", {NULL}, 1141, "tcp"}, {"mxomss", {NULL}, 1141, "udp"}, {"edtools", {NULL}, 1142, "tcp"}, {"edtools", {NULL}, 1142, "udp"}, {"imyx", {NULL}, 1143, "tcp"}, {"imyx", {NULL}, 1143, "udp"}, {"fuscript", {NULL}, 1144, "tcp"}, {"fuscript", {NULL}, 1144, "udp"}, {"x9-icue", {NULL}, 1145, "tcp"}, {"x9-icue", {NULL}, 1145, "udp"}, {"audit-transfer", {NULL}, 1146, "tcp"}, {"audit-transfer", {NULL}, 1146, "udp"}, {"capioverlan", {NULL}, 1147, "tcp"}, {"capioverlan", {NULL}, 1147, "udp"}, {"elfiq-repl", {NULL}, 1148, "tcp"}, {"elfiq-repl", {NULL}, 1148, "udp"}, {"bvtsonar", {NULL}, 1149, "tcp"}, {"bvtsonar", {NULL}, 1149, "udp"}, {"blaze", {NULL}, 1150, "tcp"}, {"blaze", {NULL}, 1150, "udp"}, {"unizensus", {NULL}, 1151, "tcp"}, {"unizensus", {NULL}, 1151, "udp"}, {"winpoplanmess", {NULL}, 1152, "tcp"}, {"winpoplanmess", {NULL}, 1152, "udp"}, {"c1222-acse", {NULL}, 1153, "tcp"}, {"c1222-acse", {NULL}, 1153, "udp"}, {"resacommunity", {NULL}, 1154, "tcp"}, {"resacommunity", {NULL}, 1154, "udp"}, {"nfa", {NULL}, 1155, "tcp"}, {"nfa", {NULL}, 1155, "udp"}, {"iascontrol-oms", {NULL}, 1156, "tcp"}, {"iascontrol-oms", {NULL}, 1156, "udp"}, {"iascontrol", {NULL}, 1157, "tcp"}, {"iascontrol", {NULL}, 1157, "udp"}, {"dbcontrol-oms", {NULL}, 1158, "tcp"}, {"dbcontrol-oms", {NULL}, 1158, "udp"}, {"oracle-oms", {NULL}, 1159, "tcp"}, {"oracle-oms", {NULL}, 1159, "udp"}, {"olsv", {NULL}, 1160, "tcp"}, {"olsv", {NULL}, 1160, "udp"}, {"health-polling", {NULL}, 1161, "tcp"}, {"health-polling", {NULL}, 1161, "udp"}, {"health-trap", {NULL}, 1162, "tcp"}, {"health-trap", {NULL}, 1162, "udp"}, {"sddp", {NULL}, 1163, "tcp"}, {"sddp", {NULL}, 1163, "udp"}, {"qsm-proxy", {NULL}, 1164, "tcp"}, {"qsm-proxy", {NULL}, 1164, "udp"}, {"qsm-gui", {NULL}, 1165, "tcp"}, {"qsm-gui", {NULL}, 1165, "udp"}, {"qsm-remote", {NULL}, 1166, "tcp"}, {"qsm-remote", {NULL}, 1166, "udp"}, {"cisco-ipsla", {NULL}, 1167, "tcp"}, {"cisco-ipsla", {NULL}, 1167, "udp"}, {"cisco-ipsla", {NULL}, 1167, "sctp"}, {"vchat", {NULL}, 1168, "tcp"}, {"vchat", {NULL}, 1168, "udp"}, {"tripwire", {NULL}, 1169, "tcp"}, {"tripwire", {NULL}, 1169, "udp"}, {"atc-lm", {NULL}, 1170, "tcp"}, {"atc-lm", {NULL}, 1170, "udp"}, {"atc-appserver", {NULL}, 1171, "tcp"}, {"atc-appserver", {NULL}, 1171, "udp"}, {"dnap", {NULL}, 1172, "tcp"}, {"dnap", {NULL}, 1172, "udp"}, {"d-cinema-rrp", {NULL}, 1173, "tcp"}, {"d-cinema-rrp", {NULL}, 1173, "udp"}, {"fnet-remote-ui", {NULL}, 1174, "tcp"}, {"fnet-remote-ui", {NULL}, 1174, "udp"}, {"dossier", {NULL}, 1175, "tcp"}, {"dossier", {NULL}, 1175, "udp"}, {"indigo-server", {NULL}, 1176, "tcp"}, {"indigo-server", {NULL}, 1176, "udp"}, {"dkmessenger", {NULL}, 1177, "tcp"}, {"dkmessenger", {NULL}, 1177, "udp"}, {"sgi-storman", {NULL}, 1178, "tcp"}, {"sgi-storman", {NULL}, 1178, "udp"}, {"b2n", {NULL}, 1179, "tcp"}, {"b2n", {NULL}, 1179, "udp"}, {"mc-client", {NULL}, 1180, "tcp"}, {"mc-client", {NULL}, 1180, "udp"}, {"3comnetman", {NULL}, 1181, "tcp"}, {"3comnetman", {NULL}, 1181, "udp"}, {"accelenet", {NULL}, 1182, "tcp"}, {"accelenet-data", {NULL}, 1182, "udp"}, {"llsurfup-http", {NULL}, 1183, "tcp"}, {"llsurfup-http", {NULL}, 1183, "udp"}, {"llsurfup-https", {NULL}, 1184, "tcp"}, {"llsurfup-https", {NULL}, 1184, "udp"}, {"catchpole", {NULL}, 1185, "tcp"}, {"catchpole", {NULL}, 1185, "udp"}, {"mysql-cluster", {NULL}, 1186, "tcp"}, {"mysql-cluster", {NULL}, 1186, "udp"}, {"alias", {NULL}, 1187, "tcp"}, {"alias", {NULL}, 1187, "udp"}, {"hp-webadmin", {NULL}, 1188, "tcp"}, {"hp-webadmin", {NULL}, 1188, "udp"}, {"unet", {NULL}, 1189, "tcp"}, {"unet", {NULL}, 1189, "udp"}, {"commlinx-avl", {NULL}, 1190, "tcp"}, {"commlinx-avl", {NULL}, 1190, "udp"}, {"gpfs", {NULL}, 1191, "tcp"}, {"gpfs", {NULL}, 1191, "udp"}, {"caids-sensor", {NULL}, 1192, "tcp"}, {"caids-sensor", {NULL}, 1192, "udp"}, {"fiveacross", {NULL}, 1193, "tcp"}, {"fiveacross", {NULL}, 1193, "udp"}, {"openvpn", {NULL}, 1194, "tcp"}, {"openvpn", {NULL}, 1194, "udp"}, {"rsf-1", {NULL}, 1195, "tcp"}, {"rsf-1", {NULL}, 1195, "udp"}, {"netmagic", {NULL}, 1196, "tcp"}, {"netmagic", {NULL}, 1196, "udp"}, {"carrius-rshell", {NULL}, 1197, "tcp"}, {"carrius-rshell", {NULL}, 1197, "udp"}, {"cajo-discovery", {NULL}, 1198, "tcp"}, {"cajo-discovery", {NULL}, 1198, "udp"}, {"dmidi", {NULL}, 1199, "tcp"}, {"dmidi", {NULL}, 1199, "udp"}, {"scol", {NULL}, 1200, "tcp"}, {"scol", {NULL}, 1200, "udp"}, {"nucleus-sand", {NULL}, 1201, "tcp"}, {"nucleus-sand", {NULL}, 1201, "udp"}, {"caiccipc", {NULL}, 1202, "tcp"}, {"caiccipc", {NULL}, 1202, "udp"}, {"ssslic-mgr", {NULL}, 1203, "tcp"}, {"ssslic-mgr", {NULL}, 1203, "udp"}, {"ssslog-mgr", {NULL}, 1204, "tcp"}, {"ssslog-mgr", {NULL}, 1204, "udp"}, {"accord-mgc", {NULL}, 1205, "tcp"}, {"accord-mgc", {NULL}, 1205, "udp"}, {"anthony-data", {NULL}, 1206, "tcp"}, {"anthony-data", {NULL}, 1206, "udp"}, {"metasage", {NULL}, 1207, "tcp"}, {"metasage", {NULL}, 1207, "udp"}, {"seagull-ais", {NULL}, 1208, "tcp"}, {"seagull-ais", {NULL}, 1208, "udp"}, {"ipcd3", {NULL}, 1209, "tcp"}, {"ipcd3", {NULL}, 1209, "udp"}, {"eoss", {NULL}, 1210, "tcp"}, {"eoss", {NULL}, 1210, "udp"}, {"groove-dpp", {NULL}, 1211, "tcp"}, {"groove-dpp", {NULL}, 1211, "udp"}, {"lupa", {NULL}, 1212, "tcp"}, {"lupa", {NULL}, 1212, "udp"}, {"mpc-lifenet", {NULL}, 1213, "tcp"}, {"mpc-lifenet", {NULL}, 1213, "udp"}, {"kazaa", {NULL}, 1214, "tcp"}, {"kazaa", {NULL}, 1214, "udp"}, {"scanstat-1", {NULL}, 1215, "tcp"}, {"scanstat-1", {NULL}, 1215, "udp"}, {"etebac5", {NULL}, 1216, "tcp"}, {"etebac5", {NULL}, 1216, "udp"}, {"hpss-ndapi", {NULL}, 1217, "tcp"}, {"hpss-ndapi", {NULL}, 1217, "udp"}, {"aeroflight-ads", {NULL}, 1218, "tcp"}, {"aeroflight-ads", {NULL}, 1218, "udp"}, {"aeroflight-ret", {NULL}, 1219, "tcp"}, {"aeroflight-ret", {NULL}, 1219, "udp"}, {"qt-serveradmin", {NULL}, 1220, "tcp"}, {"qt-serveradmin", {NULL}, 1220, "udp"}, {"sweetware-apps", {NULL}, 1221, "tcp"}, {"sweetware-apps", {NULL}, 1221, "udp"}, {"nerv", {NULL}, 1222, "tcp"}, {"nerv", {NULL}, 1222, "udp"}, {"tgp", {NULL}, 1223, "tcp"}, {"tgp", {NULL}, 1223, "udp"}, {"vpnz", {NULL}, 1224, "tcp"}, {"vpnz", {NULL}, 1224, "udp"}, {"slinkysearch", {NULL}, 1225, "tcp"}, {"slinkysearch", {NULL}, 1225, "udp"}, {"stgxfws", {NULL}, 1226, "tcp"}, {"stgxfws", {NULL}, 1226, "udp"}, {"dns2go", {NULL}, 1227, "tcp"}, {"dns2go", {NULL}, 1227, "udp"}, {"florence", {NULL}, 1228, "tcp"}, {"florence", {NULL}, 1228, "udp"}, {"zented", {NULL}, 1229, "tcp"}, {"zented", {NULL}, 1229, "udp"}, {"periscope", {NULL}, 1230, "tcp"}, {"periscope", {NULL}, 1230, "udp"}, {"menandmice-lpm", {NULL}, 1231, "tcp"}, {"menandmice-lpm", {NULL}, 1231, "udp"}, {"univ-appserver", {NULL}, 1233, "tcp"}, {"univ-appserver", {NULL}, 1233, "udp"}, {"search-agent", {NULL}, 1234, "tcp"}, {"search-agent", {NULL}, 1234, "udp"}, {"mosaicsyssvc1", {NULL}, 1235, "tcp"}, {"mosaicsyssvc1", {NULL}, 1235, "udp"}, {"bvcontrol", {NULL}, 1236, "tcp"}, {"bvcontrol", {NULL}, 1236, "udp"}, {"tsdos390", {NULL}, 1237, "tcp"}, {"tsdos390", {NULL}, 1237, "udp"}, {"hacl-qs", {NULL}, 1238, "tcp"}, {"hacl-qs", {NULL}, 1238, "udp"}, {"nmsd", {NULL}, 1239, "tcp"}, {"nmsd", {NULL}, 1239, "udp"}, {"instantia", {NULL}, 1240, "tcp"}, {"instantia", {NULL}, 1240, "udp"}, {"nessus", {NULL}, 1241, "tcp"}, {"nessus", {NULL}, 1241, "udp"}, {"nmasoverip", {NULL}, 1242, "tcp"}, {"nmasoverip", {NULL}, 1242, "udp"}, {"serialgateway", {NULL}, 1243, "tcp"}, {"serialgateway", {NULL}, 1243, "udp"}, {"isbconference1", {NULL}, 1244, "tcp"}, {"isbconference1", {NULL}, 1244, "udp"}, {"isbconference2", {NULL}, 1245, "tcp"}, {"isbconference2", {NULL}, 1245, "udp"}, {"payrouter", {NULL}, 1246, "tcp"}, {"payrouter", {NULL}, 1246, "udp"}, {"visionpyramid", {NULL}, 1247, "tcp"}, {"visionpyramid", {NULL}, 1247, "udp"}, {"hermes", {NULL}, 1248, "tcp"}, {"hermes", {NULL}, 1248, "udp"}, {"mesavistaco", {NULL}, 1249, "tcp"}, {"mesavistaco", {NULL}, 1249, "udp"}, {"swldy-sias", {NULL}, 1250, "tcp"}, {"swldy-sias", {NULL}, 1250, "udp"}, {"servergraph", {NULL}, 1251, "tcp"}, {"servergraph", {NULL}, 1251, "udp"}, {"bspne-pcc", {NULL}, 1252, "tcp"}, {"bspne-pcc", {NULL}, 1252, "udp"}, {"q55-pcc", {NULL}, 1253, "tcp"}, {"q55-pcc", {NULL}, 1253, "udp"}, {"de-noc", {NULL}, 1254, "tcp"}, {"de-noc", {NULL}, 1254, "udp"}, {"de-cache-query", {NULL}, 1255, "tcp"}, {"de-cache-query", {NULL}, 1255, "udp"}, {"de-server", {NULL}, 1256, "tcp"}, {"de-server", {NULL}, 1256, "udp"}, {"shockwave2", {NULL}, 1257, "tcp"}, {"shockwave2", {NULL}, 1257, "udp"}, {"opennl", {NULL}, 1258, "tcp"}, {"opennl", {NULL}, 1258, "udp"}, {"opennl-voice", {NULL}, 1259, "tcp"}, {"opennl-voice", {NULL}, 1259, "udp"}, {"ibm-ssd", {NULL}, 1260, "tcp"}, {"ibm-ssd", {NULL}, 1260, "udp"}, {"mpshrsv", {NULL}, 1261, "tcp"}, {"mpshrsv", {NULL}, 1261, "udp"}, {"qnts-orb", {NULL}, 1262, "tcp"}, {"qnts-orb", {NULL}, 1262, "udp"}, {"dka", {NULL}, 1263, "tcp"}, {"dka", {NULL}, 1263, "udp"}, {"prat", {NULL}, 1264, "tcp"}, {"prat", {NULL}, 1264, "udp"}, {"dssiapi", {NULL}, 1265, "tcp"}, {"dssiapi", {NULL}, 1265, "udp"}, {"dellpwrappks", {NULL}, 1266, "tcp"}, {"dellpwrappks", {NULL}, 1266, "udp"}, {"epc", {NULL}, 1267, "tcp"}, {"epc", {NULL}, 1267, "udp"}, {"propel-msgsys", {NULL}, 1268, "tcp"}, {"propel-msgsys", {NULL}, 1268, "udp"}, {"watilapp", {NULL}, 1269, "tcp"}, {"watilapp", {NULL}, 1269, "udp"}, {"opsmgr", {NULL}, 1270, "tcp"}, {"opsmgr", {NULL}, 1270, "udp"}, {"excw", {NULL}, 1271, "tcp"}, {"excw", {NULL}, 1271, "udp"}, {"cspmlockmgr", {NULL}, 1272, "tcp"}, {"cspmlockmgr", {NULL}, 1272, "udp"}, {"emc-gateway", {NULL}, 1273, "tcp"}, {"emc-gateway", {NULL}, 1273, "udp"}, {"t1distproc", {NULL}, 1274, "tcp"}, {"t1distproc", {NULL}, 1274, "udp"}, {"ivcollector", {NULL}, 1275, "tcp"}, {"ivcollector", {NULL}, 1275, "udp"}, {"ivmanager", {NULL}, 1276, "tcp"}, {"ivmanager", {NULL}, 1276, "udp"}, {"miva-mqs", {NULL}, 1277, "tcp"}, {"miva-mqs", {NULL}, 1277, "udp"}, {"dellwebadmin-1", {NULL}, 1278, "tcp"}, {"dellwebadmin-1", {NULL}, 1278, "udp"}, {"dellwebadmin-2", {NULL}, 1279, "tcp"}, {"dellwebadmin-2", {NULL}, 1279, "udp"}, {"pictrography", {NULL}, 1280, "tcp"}, {"pictrography", {NULL}, 1280, "udp"}, {"healthd", {NULL}, 1281, "tcp"}, {"healthd", {NULL}, 1281, "udp"}, {"emperion", {NULL}, 1282, "tcp"}, {"emperion", {NULL}, 1282, "udp"}, {"productinfo", {NULL}, 1283, "tcp"}, {"productinfo", {NULL}, 1283, "udp"}, {"iee-qfx", {NULL}, 1284, "tcp"}, {"iee-qfx", {NULL}, 1284, "udp"}, {"neoiface", {NULL}, 1285, "tcp"}, {"neoiface", {NULL}, 1285, "udp"}, {"netuitive", {NULL}, 1286, "tcp"}, {"netuitive", {NULL}, 1286, "udp"}, {"routematch", {NULL}, 1287, "tcp"}, {"routematch", {NULL}, 1287, "udp"}, {"navbuddy", {NULL}, 1288, "tcp"}, {"navbuddy", {NULL}, 1288, "udp"}, {"jwalkserver", {NULL}, 1289, "tcp"}, {"jwalkserver", {NULL}, 1289, "udp"}, {"winjaserver", {NULL}, 1290, "tcp"}, {"winjaserver", {NULL}, 1290, "udp"}, {"seagulllms", {NULL}, 1291, "tcp"}, {"seagulllms", {NULL}, 1291, "udp"}, {"dsdn", {NULL}, 1292, "tcp"}, {"dsdn", {NULL}, 1292, "udp"}, {"pkt-krb-ipsec", {NULL}, 1293, "tcp"}, {"pkt-krb-ipsec", {NULL}, 1293, "udp"}, {"cmmdriver", {NULL}, 1294, "tcp"}, {"cmmdriver", {NULL}, 1294, "udp"}, {"ehtp", {NULL}, 1295, "tcp"}, {"ehtp", {NULL}, 1295, "udp"}, {"dproxy", {NULL}, 1296, "tcp"}, {"dproxy", {NULL}, 1296, "udp"}, {"sdproxy", {NULL}, 1297, "tcp"}, {"sdproxy", {NULL}, 1297, "udp"}, {"lpcp", {NULL}, 1298, "tcp"}, {"lpcp", {NULL}, 1298, "udp"}, {"hp-sci", {NULL}, 1299, "tcp"}, {"hp-sci", {NULL}, 1299, "udp"}, {"h323hostcallsc", {NULL}, 1300, "tcp"}, {"h323hostcallsc", {NULL}, 1300, "udp"}, {"ci3-software-1", {NULL}, 1301, "tcp"}, {"ci3-software-1", {NULL}, 1301, "udp"}, {"ci3-software-2", {NULL}, 1302, "tcp"}, {"ci3-software-2", {NULL}, 1302, "udp"}, {"sftsrv", {NULL}, 1303, "tcp"}, {"sftsrv", {NULL}, 1303, "udp"}, {"boomerang", {NULL}, 1304, "tcp"}, {"boomerang", {NULL}, 1304, "udp"}, {"pe-mike", {NULL}, 1305, "tcp"}, {"pe-mike", {NULL}, 1305, "udp"}, {"re-conn-proto", {NULL}, 1306, "tcp"}, {"re-conn-proto", {NULL}, 1306, "udp"}, {"pacmand", {NULL}, 1307, "tcp"}, {"pacmand", {NULL}, 1307, "udp"}, {"odsi", {NULL}, 1308, "tcp"}, {"odsi", {NULL}, 1308, "udp"}, {"jtag-server", {NULL}, 1309, "tcp"}, {"jtag-server", {NULL}, 1309, "udp"}, {"husky", {NULL}, 1310, "tcp"}, {"husky", {NULL}, 1310, "udp"}, {"rxmon", {NULL}, 1311, "tcp"}, {"rxmon", {NULL}, 1311, "udp"}, {"sti-envision", {NULL}, 1312, "tcp"}, {"sti-envision", {NULL}, 1312, "udp"}, {"bmc_patroldb", {NULL}, 1313, "tcp"}, {"bmc_patroldb", {NULL}, 1313, "udp"}, {"pdps", {NULL}, 1314, "tcp"}, {"pdps", {NULL}, 1314, "udp"}, {"els", {NULL}, 1315, "tcp"}, {"els", {NULL}, 1315, "udp"}, {"exbit-escp", {NULL}, 1316, "tcp"}, {"exbit-escp", {NULL}, 1316, "udp"}, {"vrts-ipcserver", {NULL}, 1317, "tcp"}, {"vrts-ipcserver", {NULL}, 1317, "udp"}, {"krb5gatekeeper", {NULL}, 1318, "tcp"}, {"krb5gatekeeper", {NULL}, 1318, "udp"}, {"amx-icsp", {NULL}, 1319, "tcp"}, {"amx-icsp", {NULL}, 1319, "udp"}, {"amx-axbnet", {NULL}, 1320, "tcp"}, {"amx-axbnet", {NULL}, 1320, "udp"}, {"pip", {NULL}, 1321, "tcp"}, {"pip", {NULL}, 1321, "udp"}, {"novation", {NULL}, 1322, "tcp"}, {"novation", {NULL}, 1322, "udp"}, {"brcd", {NULL}, 1323, "tcp"}, {"brcd", {NULL}, 1323, "udp"}, {"delta-mcp", {NULL}, 1324, "tcp"}, {"delta-mcp", {NULL}, 1324, "udp"}, {"dx-instrument", {NULL}, 1325, "tcp"}, {"dx-instrument", {NULL}, 1325, "udp"}, {"wimsic", {NULL}, 1326, "tcp"}, {"wimsic", {NULL}, 1326, "udp"}, {"ultrex", {NULL}, 1327, "tcp"}, {"ultrex", {NULL}, 1327, "udp"}, {"ewall", {NULL}, 1328, "tcp"}, {"ewall", {NULL}, 1328, "udp"}, {"netdb-export", {NULL}, 1329, "tcp"}, {"netdb-export", {NULL}, 1329, "udp"}, {"streetperfect", {NULL}, 1330, "tcp"}, {"streetperfect", {NULL}, 1330, "udp"}, {"intersan", {NULL}, 1331, "tcp"}, {"intersan", {NULL}, 1331, "udp"}, {"pcia-rxp-b", {NULL}, 1332, "tcp"}, {"pcia-rxp-b", {NULL}, 1332, "udp"}, {"passwrd-policy", {NULL}, 1333, "tcp"}, {"passwrd-policy", {NULL}, 1333, "udp"}, {"writesrv", {NULL}, 1334, "tcp"}, {"writesrv", {NULL}, 1334, "udp"}, {"digital-notary", {NULL}, 1335, "tcp"}, {"digital-notary", {NULL}, 1335, "udp"}, {"ischat", {NULL}, 1336, "tcp"}, {"ischat", {NULL}, 1336, "udp"}, {"menandmice-dns", {NULL}, 1337, "tcp"}, {"menandmice-dns", {NULL}, 1337, "udp"}, {"wmc-log-svc", {NULL}, 1338, "tcp"}, {"wmc-log-svc", {NULL}, 1338, "udp"}, {"kjtsiteserver", {NULL}, 1339, "tcp"}, {"kjtsiteserver", {NULL}, 1339, "udp"}, {"naap", {NULL}, 1340, "tcp"}, {"naap", {NULL}, 1340, "udp"}, {"qubes", {NULL}, 1341, "tcp"}, {"qubes", {NULL}, 1341, "udp"}, {"esbroker", {NULL}, 1342, "tcp"}, {"esbroker", {NULL}, 1342, "udp"}, {"re101", {NULL}, 1343, "tcp"}, {"re101", {NULL}, 1343, "udp"}, {"icap", {NULL}, 1344, "tcp"}, {"icap", {NULL}, 1344, "udp"}, {"vpjp", {NULL}, 1345, "tcp"}, {"vpjp", {NULL}, 1345, "udp"}, {"alta-ana-lm", {NULL}, 1346, "tcp"}, {"alta-ana-lm", {NULL}, 1346, "udp"}, {"bbn-mmc", {NULL}, 1347, "tcp"}, {"bbn-mmc", {NULL}, 1347, "udp"}, {"bbn-mmx", {NULL}, 1348, "tcp"}, {"bbn-mmx", {NULL}, 1348, "udp"}, {"sbook", {NULL}, 1349, "tcp"}, {"sbook", {NULL}, 1349, "udp"}, {"editbench", {NULL}, 1350, "tcp"}, {"editbench", {NULL}, 1350, "udp"}, {"equationbuilder", {NULL}, 1351, "tcp"}, {"equationbuilder", {NULL}, 1351, "udp"}, {"lotusnote", {NULL}, 1352, "tcp"}, {"lotusnote", {NULL}, 1352, "udp"}, {"relief", {NULL}, 1353, "tcp"}, {"relief", {NULL}, 1353, "udp"}, {"XSIP-network", {NULL}, 1354, "tcp"}, {"XSIP-network", {NULL}, 1354, "udp"}, {"intuitive-edge", {NULL}, 1355, "tcp"}, {"intuitive-edge", {NULL}, 1355, "udp"}, {"cuillamartin", {NULL}, 1356, "tcp"}, {"cuillamartin", {NULL}, 1356, "udp"}, {"pegboard", {NULL}, 1357, "tcp"}, {"pegboard", {NULL}, 1357, "udp"}, {"connlcli", {NULL}, 1358, "tcp"}, {"connlcli", {NULL}, 1358, "udp"}, {"ftsrv", {NULL}, 1359, "tcp"}, {"ftsrv", {NULL}, 1359, "udp"}, {"mimer", {NULL}, 1360, "tcp"}, {"mimer", {NULL}, 1360, "udp"}, {"linx", {NULL}, 1361, "tcp"}, {"linx", {NULL}, 1361, "udp"}, {"timeflies", {NULL}, 1362, "tcp"}, {"timeflies", {NULL}, 1362, "udp"}, {"ndm-requester", {NULL}, 1363, "tcp"}, {"ndm-requester", {NULL}, 1363, "udp"}, {"ndm-server", {NULL}, 1364, "tcp"}, {"ndm-server", {NULL}, 1364, "udp"}, {"adapt-sna", {NULL}, 1365, "tcp"}, {"adapt-sna", {NULL}, 1365, "udp"}, {"netware-csp", {NULL}, 1366, "tcp"}, {"netware-csp", {NULL}, 1366, "udp"}, {"dcs", {NULL}, 1367, "tcp"}, {"dcs", {NULL}, 1367, "udp"}, {"screencast", {NULL}, 1368, "tcp"}, {"screencast", {NULL}, 1368, "udp"}, {"gv-us", {NULL}, 1369, "tcp"}, {"gv-us", {NULL}, 1369, "udp"}, {"us-gv", {NULL}, 1370, "tcp"}, {"us-gv", {NULL}, 1370, "udp"}, {"fc-cli", {NULL}, 1371, "tcp"}, {"fc-cli", {NULL}, 1371, "udp"}, {"fc-ser", {NULL}, 1372, "tcp"}, {"fc-ser", {NULL}, 1372, "udp"}, {"chromagrafx", {NULL}, 1373, "tcp"}, {"chromagrafx", {NULL}, 1373, "udp"}, {"molly", {NULL}, 1374, "tcp"}, {"molly", {NULL}, 1374, "udp"}, {"bytex", {NULL}, 1375, "tcp"}, {"bytex", {NULL}, 1375, "udp"}, {"ibm-pps", {NULL}, 1376, "tcp"}, {"ibm-pps", {NULL}, 1376, "udp"}, {"cichlid", {NULL}, 1377, "tcp"}, {"cichlid", {NULL}, 1377, "udp"}, {"elan", {NULL}, 1378, "tcp"}, {"elan", {NULL}, 1378, "udp"}, {"dbreporter", {NULL}, 1379, "tcp"}, {"dbreporter", {NULL}, 1379, "udp"}, {"telesis-licman", {NULL}, 1380, "tcp"}, {"telesis-licman", {NULL}, 1380, "udp"}, {"apple-licman", {NULL}, 1381, "tcp"}, {"apple-licman", {NULL}, 1381, "udp"}, {"udt_os", {NULL}, 1382, "tcp"}, {"udt_os", {NULL}, 1382, "udp"}, {"gwha", {NULL}, 1383, "tcp"}, {"gwha", {NULL}, 1383, "udp"}, {"os-licman", {NULL}, 1384, "tcp"}, {"os-licman", {NULL}, 1384, "udp"}, {"atex_elmd", {NULL}, 1385, "tcp"}, {"atex_elmd", {NULL}, 1385, "udp"}, {"checksum", {NULL}, 1386, "tcp"}, {"checksum", {NULL}, 1386, "udp"}, {"cadsi-lm", {NULL}, 1387, "tcp"}, {"cadsi-lm", {NULL}, 1387, "udp"}, {"objective-dbc", {NULL}, 1388, "tcp"}, {"objective-dbc", {NULL}, 1388, "udp"}, {"iclpv-dm", {NULL}, 1389, "tcp"}, {"iclpv-dm", {NULL}, 1389, "udp"}, {"iclpv-sc", {NULL}, 1390, "tcp"}, {"iclpv-sc", {NULL}, 1390, "udp"}, {"iclpv-sas", {NULL}, 1391, "tcp"}, {"iclpv-sas", {NULL}, 1391, "udp"}, {"iclpv-pm", {NULL}, 1392, "tcp"}, {"iclpv-pm", {NULL}, 1392, "udp"}, {"iclpv-nls", {NULL}, 1393, "tcp"}, {"iclpv-nls", {NULL}, 1393, "udp"}, {"iclpv-nlc", {NULL}, 1394, "tcp"}, {"iclpv-nlc", {NULL}, 1394, "udp"}, {"iclpv-wsm", {NULL}, 1395, "tcp"}, {"iclpv-wsm", {NULL}, 1395, "udp"}, {"dvl-activemail", {NULL}, 1396, "tcp"}, {"dvl-activemail", {NULL}, 1396, "udp"}, {"audio-activmail", {NULL}, 1397, "tcp"}, {"audio-activmail", {NULL}, 1397, "udp"}, {"video-activmail", {NULL}, 1398, "tcp"}, {"video-activmail", {NULL}, 1398, "udp"}, {"cadkey-licman", {NULL}, 1399, "tcp"}, {"cadkey-licman", {NULL}, 1399, "udp"}, {"cadkey-tablet", {NULL}, 1400, "tcp"}, {"cadkey-tablet", {NULL}, 1400, "udp"}, {"goldleaf-licman", {NULL}, 1401, "tcp"}, {"goldleaf-licman", {NULL}, 1401, "udp"}, {"prm-sm-np", {NULL}, 1402, "tcp"}, {"prm-sm-np", {NULL}, 1402, "udp"}, {"prm-nm-np", {NULL}, 1403, "tcp"}, {"prm-nm-np", {NULL}, 1403, "udp"}, {"igi-lm", {NULL}, 1404, "tcp"}, {"igi-lm", {NULL}, 1404, "udp"}, {"ibm-res", {NULL}, 1405, "tcp"}, {"ibm-res", {NULL}, 1405, "udp"}, {"netlabs-lm", {NULL}, 1406, "tcp"}, {"netlabs-lm", {NULL}, 1406, "udp"}, {"dbsa-lm", {NULL}, 1407, "tcp"}, {"dbsa-lm", {NULL}, 1407, "udp"}, {"sophia-lm", {NULL}, 1408, "tcp"}, {"sophia-lm", {NULL}, 1408, "udp"}, {"here-lm", {NULL}, 1409, "tcp"}, {"here-lm", {NULL}, 1409, "udp"}, {"hiq", {NULL}, 1410, "tcp"}, {"hiq", {NULL}, 1410, "udp"}, {"af", {NULL}, 1411, "tcp"}, {"af", {NULL}, 1411, "udp"}, {"innosys", {NULL}, 1412, "tcp"}, {"innosys", {NULL}, 1412, "udp"}, {"innosys-acl", {NULL}, 1413, "tcp"}, {"innosys-acl", {NULL}, 1413, "udp"}, {"ibm-mqseries", {NULL}, 1414, "tcp"}, {"ibm-mqseries", {NULL}, 1414, "udp"}, {"dbstar", {NULL}, 1415, "tcp"}, {"dbstar", {NULL}, 1415, "udp"}, {"novell-lu6.2", {NULL}, 1416, "tcp"}, {"novell-lu6.2", {NULL}, 1416, "udp"}, {"timbuktu-srv1", {NULL}, 1417, "tcp"}, {"timbuktu-srv1", {NULL}, 1417, "udp"}, {"timbuktu-srv2", {NULL}, 1418, "tcp"}, {"timbuktu-srv2", {NULL}, 1418, "udp"}, {"timbuktu-srv3", {NULL}, 1419, "tcp"}, {"timbuktu-srv3", {NULL}, 1419, "udp"}, {"timbuktu-srv4", {NULL}, 1420, "tcp"}, {"timbuktu-srv4", {NULL}, 1420, "udp"}, {"gandalf-lm", {NULL}, 1421, "tcp"}, {"gandalf-lm", {NULL}, 1421, "udp"}, {"autodesk-lm", {NULL}, 1422, "tcp"}, {"autodesk-lm", {NULL}, 1422, "udp"}, {"essbase", {NULL}, 1423, "tcp"}, {"essbase", {NULL}, 1423, "udp"}, {"hybrid", {NULL}, 1424, "tcp"}, {"hybrid", {NULL}, 1424, "udp"}, {"zion-lm", {NULL}, 1425, "tcp"}, {"zion-lm", {NULL}, 1425, "udp"}, {"sais", {NULL}, 1426, "tcp"}, {"sais", {NULL}, 1426, "udp"}, {"mloadd", {NULL}, 1427, "tcp"}, {"mloadd", {NULL}, 1427, "udp"}, {"informatik-lm", {NULL}, 1428, "tcp"}, {"informatik-lm", {NULL}, 1428, "udp"}, {"nms", {NULL}, 1429, "tcp"}, {"nms", {NULL}, 1429, "udp"}, {"tpdu", {NULL}, 1430, "tcp"}, {"tpdu", {NULL}, 1430, "udp"}, {"rgtp", {NULL}, 1431, "tcp"}, {"rgtp", {NULL}, 1431, "udp"}, {"blueberry-lm", {NULL}, 1432, "tcp"}, {"blueberry-lm", {NULL}, 1432, "udp"}, {"ms-sql-s", {NULL}, 1433, "tcp"}, {"ms-sql-s", {NULL}, 1433, "udp"}, {"ms-sql-m", {NULL}, 1434, "tcp"}, {"ms-sql-m", {NULL}, 1434, "udp"}, {"ibm-cics", {NULL}, 1435, "tcp"}, {"ibm-cics", {NULL}, 1435, "udp"}, {"saism", {NULL}, 1436, "tcp"}, {"saism", {NULL}, 1436, "udp"}, {"tabula", {NULL}, 1437, "tcp"}, {"tabula", {NULL}, 1437, "udp"}, {"eicon-server", {NULL}, 1438, "tcp"}, {"eicon-server", {NULL}, 1438, "udp"}, {"eicon-x25", {NULL}, 1439, "tcp"}, {"eicon-x25", {NULL}, 1439, "udp"}, {"eicon-slp", {NULL}, 1440, "tcp"}, {"eicon-slp", {NULL}, 1440, "udp"}, {"cadis-1", {NULL}, 1441, "tcp"}, {"cadis-1", {NULL}, 1441, "udp"}, {"cadis-2", {NULL}, 1442, "tcp"}, {"cadis-2", {NULL}, 1442, "udp"}, {"ies-lm", {NULL}, 1443, "tcp"}, {"ies-lm", {NULL}, 1443, "udp"}, {"marcam-lm", {NULL}, 1444, "tcp"}, {"marcam-lm", {NULL}, 1444, "udp"}, {"proxima-lm", {NULL}, 1445, "tcp"}, {"proxima-lm", {NULL}, 1445, "udp"}, {"ora-lm", {NULL}, 1446, "tcp"}, {"ora-lm", {NULL}, 1446, "udp"}, {"apri-lm", {NULL}, 1447, "tcp"}, {"apri-lm", {NULL}, 1447, "udp"}, {"oc-lm", {NULL}, 1448, "tcp"}, {"oc-lm", {NULL}, 1448, "udp"}, {"peport", {NULL}, 1449, "tcp"}, {"peport", {NULL}, 1449, "udp"}, {"dwf", {NULL}, 1450, "tcp"}, {"dwf", {NULL}, 1450, "udp"}, {"infoman", {NULL}, 1451, "tcp"}, {"infoman", {NULL}, 1451, "udp"}, {"gtegsc-lm", {NULL}, 1452, "tcp"}, {"gtegsc-lm", {NULL}, 1452, "udp"}, {"genie-lm", {NULL}, 1453, "tcp"}, {"genie-lm", {NULL}, 1453, "udp"}, {"interhdl_elmd", {NULL}, 1454, "tcp"}, {"interhdl_elmd", {NULL}, 1454, "udp"}, {"esl-lm", {NULL}, 1455, "tcp"}, {"esl-lm", {NULL}, 1455, "udp"}, {"dca", {NULL}, 1456, "tcp"}, {"dca", {NULL}, 1456, "udp"}, {"valisys-lm", {NULL}, 1457, "tcp"}, {"valisys-lm", {NULL}, 1457, "udp"}, {"nrcabq-lm", {NULL}, 1458, "tcp"}, {"nrcabq-lm", {NULL}, 1458, "udp"}, {"proshare1", {NULL}, 1459, "tcp"}, {"proshare1", {NULL}, 1459, "udp"}, {"proshare2", {NULL}, 1460, "tcp"}, {"proshare2", {NULL}, 1460, "udp"}, {"ibm_wrless_lan", {NULL}, 1461, "tcp"}, {"ibm_wrless_lan", {NULL}, 1461, "udp"}, {"world-lm", {NULL}, 1462, "tcp"}, {"world-lm", {NULL}, 1462, "udp"}, {"nucleus", {NULL}, 1463, "tcp"}, {"nucleus", {NULL}, 1463, "udp"}, {"msl_lmd", {NULL}, 1464, "tcp"}, {"msl_lmd", {NULL}, 1464, "udp"}, {"pipes", {NULL}, 1465, "tcp"}, {"pipes", {NULL}, 1465, "udp"}, {"oceansoft-lm", {NULL}, 1466, "tcp"}, {"oceansoft-lm", {NULL}, 1466, "udp"}, {"csdmbase", {NULL}, 1467, "tcp"}, {"csdmbase", {NULL}, 1467, "udp"}, {"csdm", {NULL}, 1468, "tcp"}, {"csdm", {NULL}, 1468, "udp"}, {"aal-lm", {NULL}, 1469, "tcp"}, {"aal-lm", {NULL}, 1469, "udp"}, {"uaiact", {NULL}, 1470, "tcp"}, {"uaiact", {NULL}, 1470, "udp"}, {"csdmbase", {NULL}, 1471, "tcp"}, {"csdmbase", {NULL}, 1471, "udp"}, {"csdm", {NULL}, 1472, "tcp"}, {"csdm", {NULL}, 1472, "udp"}, {"openmath", {NULL}, 1473, "tcp"}, {"openmath", {NULL}, 1473, "udp"}, {"telefinder", {NULL}, 1474, "tcp"}, {"telefinder", {NULL}, 1474, "udp"}, {"taligent-lm", {NULL}, 1475, "tcp"}, {"taligent-lm", {NULL}, 1475, "udp"}, {"clvm-cfg", {NULL}, 1476, "tcp"}, {"clvm-cfg", {NULL}, 1476, "udp"}, {"ms-sna-server", {NULL}, 1477, "tcp"}, {"ms-sna-server", {NULL}, 1477, "udp"}, {"ms-sna-base", {NULL}, 1478, "tcp"}, {"ms-sna-base", {NULL}, 1478, "udp"}, {"dberegister", {NULL}, 1479, "tcp"}, {"dberegister", {NULL}, 1479, "udp"}, {"pacerforum", {NULL}, 1480, "tcp"}, {"pacerforum", {NULL}, 1480, "udp"}, {"airs", {NULL}, 1481, "tcp"}, {"airs", {NULL}, 1481, "udp"}, {"miteksys-lm", {NULL}, 1482, "tcp"}, {"miteksys-lm", {NULL}, 1482, "udp"}, {"afs", {NULL}, 1483, "tcp"}, {"afs", {NULL}, 1483, "udp"}, {"confluent", {NULL}, 1484, "tcp"}, {"confluent", {NULL}, 1484, "udp"}, {"lansource", {NULL}, 1485, "tcp"}, {"lansource", {NULL}, 1485, "udp"}, {"nms_topo_serv", {NULL}, 1486, "tcp"}, {"nms_topo_serv", {NULL}, 1486, "udp"}, {"localinfosrvr", {NULL}, 1487, "tcp"}, {"localinfosrvr", {NULL}, 1487, "udp"}, {"docstor", {NULL}, 1488, "tcp"}, {"docstor", {NULL}, 1488, "udp"}, {"dmdocbroker", {NULL}, 1489, "tcp"}, {"dmdocbroker", {NULL}, 1489, "udp"}, {"insitu-conf", {NULL}, 1490, "tcp"}, {"insitu-conf", {NULL}, 1490, "udp"}, {"stone-design-1", {NULL}, 1492, "tcp"}, {"stone-design-1", {NULL}, 1492, "udp"}, {"netmap_lm", {NULL}, 1493, "tcp"}, {"netmap_lm", {NULL}, 1493, "udp"}, {"ica", {NULL}, 1494, "tcp"}, {"ica", {NULL}, 1494, "udp"}, {"cvc", {NULL}, 1495, "tcp"}, {"cvc", {NULL}, 1495, "udp"}, {"liberty-lm", {NULL}, 1496, "tcp"}, {"liberty-lm", {NULL}, 1496, "udp"}, {"rfx-lm", {NULL}, 1497, "tcp"}, {"rfx-lm", {NULL}, 1497, "udp"}, {"sybase-sqlany", {NULL}, 1498, "tcp"}, {"sybase-sqlany", {NULL}, 1498, "udp"}, {"fhc", {NULL}, 1499, "tcp"}, {"fhc", {NULL}, 1499, "udp"}, {"vlsi-lm", {NULL}, 1500, "tcp"}, {"vlsi-lm", {NULL}, 1500, "udp"}, {"saiscm", {NULL}, 1501, "tcp"}, {"saiscm", {NULL}, 1501, "udp"}, {"shivadiscovery", {NULL}, 1502, "tcp"}, {"shivadiscovery", {NULL}, 1502, "udp"}, {"imtc-mcs", {NULL}, 1503, "tcp"}, {"imtc-mcs", {NULL}, 1503, "udp"}, {"evb-elm", {NULL}, 1504, "tcp"}, {"evb-elm", {NULL}, 1504, "udp"}, {"funkproxy", {NULL}, 1505, "tcp"}, {"funkproxy", {NULL}, 1505, "udp"}, {"utcd", {NULL}, 1506, "tcp"}, {"utcd", {NULL}, 1506, "udp"}, {"symplex", {NULL}, 1507, "tcp"}, {"symplex", {NULL}, 1507, "udp"}, {"diagmond", {NULL}, 1508, "tcp"}, {"diagmond", {NULL}, 1508, "udp"}, {"robcad-lm", {NULL}, 1509, "tcp"}, {"robcad-lm", {NULL}, 1509, "udp"}, {"mvx-lm", {NULL}, 1510, "tcp"}, {"mvx-lm", {NULL}, 1510, "udp"}, {"3l-l1", {NULL}, 1511, "tcp"}, {"3l-l1", {NULL}, 1511, "udp"}, {"wins", {NULL}, 1512, "tcp"}, {"wins", {NULL}, 1512, "udp"}, {"fujitsu-dtc", {NULL}, 1513, "tcp"}, {"fujitsu-dtc", {NULL}, 1513, "udp"}, {"fujitsu-dtcns", {NULL}, 1514, "tcp"}, {"fujitsu-dtcns", {NULL}, 1514, "udp"}, {"ifor-protocol", {NULL}, 1515, "tcp"}, {"ifor-protocol", {NULL}, 1515, "udp"}, {"vpad", {NULL}, 1516, "tcp"}, {"vpad", {NULL}, 1516, "udp"}, {"vpac", {NULL}, 1517, "tcp"}, {"vpac", {NULL}, 1517, "udp"}, {"vpvd", {NULL}, 1518, "tcp"}, {"vpvd", {NULL}, 1518, "udp"}, {"vpvc", {NULL}, 1519, "tcp"}, {"vpvc", {NULL}, 1519, "udp"}, {"atm-zip-office", {NULL}, 1520, "tcp"}, {"atm-zip-office", {NULL}, 1520, "udp"}, {"ncube-lm", {NULL}, 1521, "tcp"}, {"ncube-lm", {NULL}, 1521, "udp"}, {"ricardo-lm", {NULL}, 1522, "tcp"}, {"ricardo-lm", {NULL}, 1522, "udp"}, {"cichild-lm", {NULL}, 1523, "tcp"}, {"cichild-lm", {NULL}, 1523, "udp"}, {"ingreslock", {NULL}, 1524, "tcp"}, {"ingreslock", {NULL}, 1524, "udp"}, {"orasrv", {NULL}, 1525, "tcp"}, {"orasrv", {NULL}, 1525, "udp"}, {"prospero-np", {NULL}, 1525, "tcp"}, {"prospero-np", {NULL}, 1525, "udp"}, {"pdap-np", {NULL}, 1526, "tcp"}, {"pdap-np", {NULL}, 1526, "udp"}, {"tlisrv", {NULL}, 1527, "tcp"}, {"tlisrv", {NULL}, 1527, "udp"}, {"coauthor", {NULL}, 1529, "tcp"}, {"coauthor", {NULL}, 1529, "udp"}, {"rap-service", {NULL}, 1530, "tcp"}, {"rap-service", {NULL}, 1530, "udp"}, {"rap-listen", {NULL}, 1531, "tcp"}, {"rap-listen", {NULL}, 1531, "udp"}, {"miroconnect", {NULL}, 1532, "tcp"}, {"miroconnect", {NULL}, 1532, "udp"}, {"virtual-places", {NULL}, 1533, "tcp"}, {"virtual-places", {NULL}, 1533, "udp"}, {"micromuse-lm", {NULL}, 1534, "tcp"}, {"micromuse-lm", {NULL}, 1534, "udp"}, {"ampr-info", {NULL}, 1535, "tcp"}, {"ampr-info", {NULL}, 1535, "udp"}, {"ampr-inter", {NULL}, 1536, "tcp"}, {"ampr-inter", {NULL}, 1536, "udp"}, {"sdsc-lm", {NULL}, 1537, "tcp"}, {"sdsc-lm", {NULL}, 1537, "udp"}, {"3ds-lm", {NULL}, 1538, "tcp"}, {"3ds-lm", {NULL}, 1538, "udp"}, {"intellistor-lm", {NULL}, 1539, "tcp"}, {"intellistor-lm", {NULL}, 1539, "udp"}, {"rds", {NULL}, 1540, "tcp"}, {"rds", {NULL}, 1540, "udp"}, {"rds2", {NULL}, 1541, "tcp"}, {"rds2", {NULL}, 1541, "udp"}, {"gridgen-elmd", {NULL}, 1542, "tcp"}, {"gridgen-elmd", {NULL}, 1542, "udp"}, {"simba-cs", {NULL}, 1543, "tcp"}, {"simba-cs", {NULL}, 1543, "udp"}, {"aspeclmd", {NULL}, 1544, "tcp"}, {"aspeclmd", {NULL}, 1544, "udp"}, {"vistium-share", {NULL}, 1545, "tcp"}, {"vistium-share", {NULL}, 1545, "udp"}, {"abbaccuray", {NULL}, 1546, "tcp"}, {"abbaccuray", {NULL}, 1546, "udp"}, {"laplink", {NULL}, 1547, "tcp"}, {"laplink", {NULL}, 1547, "udp"}, {"axon-lm", {NULL}, 1548, "tcp"}, {"axon-lm", {NULL}, 1548, "udp"}, {"shivahose", {NULL}, 1549, "tcp"}, {"shivasound", {NULL}, 1549, "udp"}, {"3m-image-lm", {NULL}, 1550, "tcp"}, {"3m-image-lm", {NULL}, 1550, "udp"}, {"hecmtl-db", {NULL}, 1551, "tcp"}, {"hecmtl-db", {NULL}, 1551, "udp"}, {"pciarray", {NULL}, 1552, "tcp"}, {"pciarray", {NULL}, 1552, "udp"}, {"sna-cs", {NULL}, 1553, "tcp"}, {"sna-cs", {NULL}, 1553, "udp"}, {"caci-lm", {NULL}, 1554, "tcp"}, {"caci-lm", {NULL}, 1554, "udp"}, {"livelan", {NULL}, 1555, "tcp"}, {"livelan", {NULL}, 1555, "udp"}, {"veritas_pbx", {NULL}, 1556, "tcp"}, {"veritas_pbx", {NULL}, 1556, "udp"}, {"arbortext-lm", {NULL}, 1557, "tcp"}, {"arbortext-lm", {NULL}, 1557, "udp"}, {"xingmpeg", {NULL}, 1558, "tcp"}, {"xingmpeg", {NULL}, 1558, "udp"}, {"web2host", {NULL}, 1559, "tcp"}, {"web2host", {NULL}, 1559, "udp"}, {"asci-val", {NULL}, 1560, "tcp"}, {"asci-val", {NULL}, 1560, "udp"}, {"facilityview", {NULL}, 1561, "tcp"}, {"facilityview", {NULL}, 1561, "udp"}, {"pconnectmgr", {NULL}, 1562, "tcp"}, {"pconnectmgr", {NULL}, 1562, "udp"}, {"cadabra-lm", {NULL}, 1563, "tcp"}, {"cadabra-lm", {NULL}, 1563, "udp"}, {"pay-per-view", {NULL}, 1564, "tcp"}, {"pay-per-view", {NULL}, 1564, "udp"}, {"winddlb", {NULL}, 1565, "tcp"}, {"winddlb", {NULL}, 1565, "udp"}, {"corelvideo", {NULL}, 1566, "tcp"}, {"corelvideo", {NULL}, 1566, "udp"}, {"jlicelmd", {NULL}, 1567, "tcp"}, {"jlicelmd", {NULL}, 1567, "udp"}, {"tsspmap", {NULL}, 1568, "tcp"}, {"tsspmap", {NULL}, 1568, "udp"}, {"ets", {NULL}, 1569, "tcp"}, {"ets", {NULL}, 1569, "udp"}, {"orbixd", {NULL}, 1570, "tcp"}, {"orbixd", {NULL}, 1570, "udp"}, {"rdb-dbs-disp", {NULL}, 1571, "tcp"}, {"rdb-dbs-disp", {NULL}, 1571, "udp"}, {"chip-lm", {NULL}, 1572, "tcp"}, {"chip-lm", {NULL}, 1572, "udp"}, {"itscomm-ns", {NULL}, 1573, "tcp"}, {"itscomm-ns", {NULL}, 1573, "udp"}, {"mvel-lm", {NULL}, 1574, "tcp"}, {"mvel-lm", {NULL}, 1574, "udp"}, {"oraclenames", {NULL}, 1575, "tcp"}, {"oraclenames", {NULL}, 1575, "udp"}, {"moldflow-lm", {NULL}, 1576, "tcp"}, {"moldflow-lm", {NULL}, 1576, "udp"}, {"hypercube-lm", {NULL}, 1577, "tcp"}, {"hypercube-lm", {NULL}, 1577, "udp"}, {"jacobus-lm", {NULL}, 1578, "tcp"}, {"jacobus-lm", {NULL}, 1578, "udp"}, {"ioc-sea-lm", {NULL}, 1579, "tcp"}, {"ioc-sea-lm", {NULL}, 1579, "udp"}, {"tn-tl-r1", {NULL}, 1580, "tcp"}, {"tn-tl-r2", {NULL}, 1580, "udp"}, {"mil-2045-47001", {NULL}, 1581, "tcp"}, {"mil-2045-47001", {NULL}, 1581, "udp"}, {"msims", {NULL}, 1582, "tcp"}, {"msims", {NULL}, 1582, "udp"}, {"simbaexpress", {NULL}, 1583, "tcp"}, {"simbaexpress", {NULL}, 1583, "udp"}, {"tn-tl-fd2", {NULL}, 1584, "tcp"}, {"tn-tl-fd2", {NULL}, 1584, "udp"}, {"intv", {NULL}, 1585, "tcp"}, {"intv", {NULL}, 1585, "udp"}, {"ibm-abtact", {NULL}, 1586, "tcp"}, {"ibm-abtact", {NULL}, 1586, "udp"}, {"pra_elmd", {NULL}, 1587, "tcp"}, {"pra_elmd", {NULL}, 1587, "udp"}, {"triquest-lm", {NULL}, 1588, "tcp"}, {"triquest-lm", {NULL}, 1588, "udp"}, {"vqp", {NULL}, 1589, "tcp"}, {"vqp", {NULL}, 1589, "udp"}, {"gemini-lm", {NULL}, 1590, "tcp"}, {"gemini-lm", {NULL}, 1590, "udp"}, {"ncpm-pm", {NULL}, 1591, "tcp"}, {"ncpm-pm", {NULL}, 1591, "udp"}, {"commonspace", {NULL}, 1592, "tcp"}, {"commonspace", {NULL}, 1592, "udp"}, {"mainsoft-lm", {NULL}, 1593, "tcp"}, {"mainsoft-lm", {NULL}, 1593, "udp"}, {"sixtrak", {NULL}, 1594, "tcp"}, {"sixtrak", {NULL}, 1594, "udp"}, {"radio", {NULL}, 1595, "tcp"}, {"radio", {NULL}, 1595, "udp"}, {"radio-sm", {NULL}, 1596, "tcp"}, {"radio-bc", {NULL}, 1596, "udp"}, {"orbplus-iiop", {NULL}, 1597, "tcp"}, {"orbplus-iiop", {NULL}, 1597, "udp"}, {"picknfs", {NULL}, 1598, "tcp"}, {"picknfs", {NULL}, 1598, "udp"}, {"simbaservices", {NULL}, 1599, "tcp"}, {"simbaservices", {NULL}, 1599, "udp"}, {"issd", {NULL}, 1600, "tcp"}, {"issd", {NULL}, 1600, "udp"}, {"aas", {NULL}, 1601, "tcp"}, {"aas", {NULL}, 1601, "udp"}, {"inspect", {NULL}, 1602, "tcp"}, {"inspect", {NULL}, 1602, "udp"}, {"picodbc", {NULL}, 1603, "tcp"}, {"picodbc", {NULL}, 1603, "udp"}, {"icabrowser", {NULL}, 1604, "tcp"}, {"icabrowser", {NULL}, 1604, "udp"}, {"slp", {NULL}, 1605, "tcp"}, {"slp", {NULL}, 1605, "udp"}, {"slm-api", {NULL}, 1606, "tcp"}, {"slm-api", {NULL}, 1606, "udp"}, {"stt", {NULL}, 1607, "tcp"}, {"stt", {NULL}, 1607, "udp"}, {"smart-lm", {NULL}, 1608, "tcp"}, {"smart-lm", {NULL}, 1608, "udp"}, {"isysg-lm", {NULL}, 1609, "tcp"}, {"isysg-lm", {NULL}, 1609, "udp"}, {"taurus-wh", {NULL}, 1610, "tcp"}, {"taurus-wh", {NULL}, 1610, "udp"}, {"ill", {NULL}, 1611, "tcp"}, {"ill", {NULL}, 1611, "udp"}, {"netbill-trans", {NULL}, 1612, "tcp"}, {"netbill-trans", {NULL}, 1612, "udp"}, {"netbill-keyrep", {NULL}, 1613, "tcp"}, {"netbill-keyrep", {NULL}, 1613, "udp"}, {"netbill-cred", {NULL}, 1614, "tcp"}, {"netbill-cred", {NULL}, 1614, "udp"}, {"netbill-auth", {NULL}, 1615, "tcp"}, {"netbill-auth", {NULL}, 1615, "udp"}, {"netbill-prod", {NULL}, 1616, "tcp"}, {"netbill-prod", {NULL}, 1616, "udp"}, {"nimrod-agent", {NULL}, 1617, "tcp"}, {"nimrod-agent", {NULL}, 1617, "udp"}, {"skytelnet", {NULL}, 1618, "tcp"}, {"skytelnet", {NULL}, 1618, "udp"}, {"xs-openstorage", {NULL}, 1619, "tcp"}, {"xs-openstorage", {NULL}, 1619, "udp"}, {"faxportwinport", {NULL}, 1620, "tcp"}, {"faxportwinport", {NULL}, 1620, "udp"}, {"softdataphone", {NULL}, 1621, "tcp"}, {"softdataphone", {NULL}, 1621, "udp"}, {"ontime", {NULL}, 1622, "tcp"}, {"ontime", {NULL}, 1622, "udp"}, {"jaleosnd", {NULL}, 1623, "tcp"}, {"jaleosnd", {NULL}, 1623, "udp"}, {"udp-sr-port", {NULL}, 1624, "tcp"}, {"udp-sr-port", {NULL}, 1624, "udp"}, {"svs-omagent", {NULL}, 1625, "tcp"}, {"svs-omagent", {NULL}, 1625, "udp"}, {"shockwave", {NULL}, 1626, "tcp"}, {"shockwave", {NULL}, 1626, "udp"}, {"t128-gateway", {NULL}, 1627, "tcp"}, {"t128-gateway", {NULL}, 1627, "udp"}, {"lontalk-norm", {NULL}, 1628, "tcp"}, {"lontalk-norm", {NULL}, 1628, "udp"}, {"lontalk-urgnt", {NULL}, 1629, "tcp"}, {"lontalk-urgnt", {NULL}, 1629, "udp"}, {"oraclenet8cman", {NULL}, 1630, "tcp"}, {"oraclenet8cman", {NULL}, 1630, "udp"}, {"visitview", {NULL}, 1631, "tcp"}, {"visitview", {NULL}, 1631, "udp"}, {"pammratc", {NULL}, 1632, "tcp"}, {"pammratc", {NULL}, 1632, "udp"}, {"pammrpc", {NULL}, 1633, "tcp"}, {"pammrpc", {NULL}, 1633, "udp"}, {"loaprobe", {NULL}, 1634, "tcp"}, {"loaprobe", {NULL}, 1634, "udp"}, {"edb-server1", {NULL}, 1635, "tcp"}, {"edb-server1", {NULL}, 1635, "udp"}, {"isdc", {NULL}, 1636, "tcp"}, {"isdc", {NULL}, 1636, "udp"}, {"islc", {NULL}, 1637, "tcp"}, {"islc", {NULL}, 1637, "udp"}, {"ismc", {NULL}, 1638, "tcp"}, {"ismc", {NULL}, 1638, "udp"}, {"cert-initiator", {NULL}, 1639, "tcp"}, {"cert-initiator", {NULL}, 1639, "udp"}, {"cert-responder", {NULL}, 1640, "tcp"}, {"cert-responder", {NULL}, 1640, "udp"}, {"invision", {NULL}, 1641, "tcp"}, {"invision", {NULL}, 1641, "udp"}, {"isis-am", {NULL}, 1642, "tcp"}, {"isis-am", {NULL}, 1642, "udp"}, {"isis-ambc", {NULL}, 1643, "tcp"}, {"isis-ambc", {NULL}, 1643, "udp"}, {"saiseh", {NULL}, 1644, "tcp"}, {"sightline", {NULL}, 1645, "tcp"}, {"sightline", {NULL}, 1645, "udp"}, {"sa-msg-port", {NULL}, 1646, "tcp"}, {"sa-msg-port", {NULL}, 1646, "udp"}, {"rsap", {NULL}, 1647, "tcp"}, {"rsap", {NULL}, 1647, "udp"}, {"concurrent-lm", {NULL}, 1648, "tcp"}, {"concurrent-lm", {NULL}, 1648, "udp"}, {"kermit", {NULL}, 1649, "tcp"}, {"kermit", {NULL}, 1649, "udp"}, {"nkd", {NULL}, 1650, "tcp"}, {"nkd", {NULL}, 1650, "udp"}, {"shiva_confsrvr", {NULL}, 1651, "tcp"}, {"shiva_confsrvr", {NULL}, 1651, "udp"}, {"xnmp", {NULL}, 1652, "tcp"}, {"xnmp", {NULL}, 1652, "udp"}, {"alphatech-lm", {NULL}, 1653, "tcp"}, {"alphatech-lm", {NULL}, 1653, "udp"}, {"stargatealerts", {NULL}, 1654, "tcp"}, {"stargatealerts", {NULL}, 1654, "udp"}, {"dec-mbadmin", {NULL}, 1655, "tcp"}, {"dec-mbadmin", {NULL}, 1655, "udp"}, {"dec-mbadmin-h", {NULL}, 1656, "tcp"}, {"dec-mbadmin-h", {NULL}, 1656, "udp"}, {"fujitsu-mmpdc", {NULL}, 1657, "tcp"}, {"fujitsu-mmpdc", {NULL}, 1657, "udp"}, {"sixnetudr", {NULL}, 1658, "tcp"}, {"sixnetudr", {NULL}, 1658, "udp"}, {"sg-lm", {NULL}, 1659, "tcp"}, {"sg-lm", {NULL}, 1659, "udp"}, {"skip-mc-gikreq", {NULL}, 1660, "tcp"}, {"skip-mc-gikreq", {NULL}, 1660, "udp"}, {"netview-aix-1", {NULL}, 1661, "tcp"}, {"netview-aix-1", {NULL}, 1661, "udp"}, {"netview-aix-2", {NULL}, 1662, "tcp"}, {"netview-aix-2", {NULL}, 1662, "udp"}, {"netview-aix-3", {NULL}, 1663, "tcp"}, {"netview-aix-3", {NULL}, 1663, "udp"}, {"netview-aix-4", {NULL}, 1664, "tcp"}, {"netview-aix-4", {NULL}, 1664, "udp"}, {"netview-aix-5", {NULL}, 1665, "tcp"}, {"netview-aix-5", {NULL}, 1665, "udp"}, {"netview-aix-6", {NULL}, 1666, "tcp"}, {"netview-aix-6", {NULL}, 1666, "udp"}, {"netview-aix-7", {NULL}, 1667, "tcp"}, {"netview-aix-7", {NULL}, 1667, "udp"}, {"netview-aix-8", {NULL}, 1668, "tcp"}, {"netview-aix-8", {NULL}, 1668, "udp"}, {"netview-aix-9", {NULL}, 1669, "tcp"}, {"netview-aix-9", {NULL}, 1669, "udp"}, {"netview-aix-10", {NULL}, 1670, "tcp"}, {"netview-aix-10", {NULL}, 1670, "udp"}, {"netview-aix-11", {NULL}, 1671, "tcp"}, {"netview-aix-11", {NULL}, 1671, "udp"}, {"netview-aix-12", {NULL}, 1672, "tcp"}, {"netview-aix-12", {NULL}, 1672, "udp"}, {"proshare-mc-1", {NULL}, 1673, "tcp"}, {"proshare-mc-1", {NULL}, 1673, "udp"}, {"proshare-mc-2", {NULL}, 1674, "tcp"}, {"proshare-mc-2", {NULL}, 1674, "udp"}, {"pdp", {NULL}, 1675, "tcp"}, {"pdp", {NULL}, 1675, "udp"}, {"netcomm1", {NULL}, 1676, "tcp"}, {"netcomm2", {NULL}, 1676, "udp"}, {"groupwise", {NULL}, 1677, "tcp"}, {"groupwise", {NULL}, 1677, "udp"}, {"prolink", {NULL}, 1678, "tcp"}, {"prolink", {NULL}, 1678, "udp"}, {"darcorp-lm", {NULL}, 1679, "tcp"}, {"darcorp-lm", {NULL}, 1679, "udp"}, {"microcom-sbp", {NULL}, 1680, "tcp"}, {"microcom-sbp", {NULL}, 1680, "udp"}, {"sd-elmd", {NULL}, 1681, "tcp"}, {"sd-elmd", {NULL}, 1681, "udp"}, {"lanyon-lantern", {NULL}, 1682, "tcp"}, {"lanyon-lantern", {NULL}, 1682, "udp"}, {"ncpm-hip", {NULL}, 1683, "tcp"}, {"ncpm-hip", {NULL}, 1683, "udp"}, {"snaresecure", {NULL}, 1684, "tcp"}, {"snaresecure", {NULL}, 1684, "udp"}, {"n2nremote", {NULL}, 1685, "tcp"}, {"n2nremote", {NULL}, 1685, "udp"}, {"cvmon", {NULL}, 1686, "tcp"}, {"cvmon", {NULL}, 1686, "udp"}, {"nsjtp-ctrl", {NULL}, 1687, "tcp"}, {"nsjtp-ctrl", {NULL}, 1687, "udp"}, {"nsjtp-data", {NULL}, 1688, "tcp"}, {"nsjtp-data", {NULL}, 1688, "udp"}, {"firefox", {NULL}, 1689, "tcp"}, {"firefox", {NULL}, 1689, "udp"}, {"ng-umds", {NULL}, 1690, "tcp"}, {"ng-umds", {NULL}, 1690, "udp"}, {"empire-empuma", {NULL}, 1691, "tcp"}, {"empire-empuma", {NULL}, 1691, "udp"}, {"sstsys-lm", {NULL}, 1692, "tcp"}, {"sstsys-lm", {NULL}, 1692, "udp"}, {"rrirtr", {NULL}, 1693, "tcp"}, {"rrirtr", {NULL}, 1693, "udp"}, {"rrimwm", {NULL}, 1694, "tcp"}, {"rrimwm", {NULL}, 1694, "udp"}, {"rrilwm", {NULL}, 1695, "tcp"}, {"rrilwm", {NULL}, 1695, "udp"}, {"rrifmm", {NULL}, 1696, "tcp"}, {"rrifmm", {NULL}, 1696, "udp"}, {"rrisat", {NULL}, 1697, "tcp"}, {"rrisat", {NULL}, 1697, "udp"}, {"rsvp-encap-1", {NULL}, 1698, "tcp"}, {"rsvp-encap-1", {NULL}, 1698, "udp"}, {"rsvp-encap-2", {NULL}, 1699, "tcp"}, {"rsvp-encap-2", {NULL}, 1699, "udp"}, {"mps-raft", {NULL}, 1700, "tcp"}, {"mps-raft", {NULL}, 1700, "udp"}, {"l2f", {NULL}, 1701, "tcp"}, {"l2f", {NULL}, 1701, "udp"}, {"l2tp", {NULL}, 1701, "tcp"}, {"l2tp", {NULL}, 1701, "udp"}, {"deskshare", {NULL}, 1702, "tcp"}, {"deskshare", {NULL}, 1702, "udp"}, {"hb-engine", {NULL}, 1703, "tcp"}, {"hb-engine", {NULL}, 1703, "udp"}, {"bcs-broker", {NULL}, 1704, "tcp"}, {"bcs-broker", {NULL}, 1704, "udp"}, {"slingshot", {NULL}, 1705, "tcp"}, {"slingshot", {NULL}, 1705, "udp"}, {"jetform", {NULL}, 1706, "tcp"}, {"jetform", {NULL}, 1706, "udp"}, {"vdmplay", {NULL}, 1707, "tcp"}, {"vdmplay", {NULL}, 1707, "udp"}, {"gat-lmd", {NULL}, 1708, "tcp"}, {"gat-lmd", {NULL}, 1708, "udp"}, {"centra", {NULL}, 1709, "tcp"}, {"centra", {NULL}, 1709, "udp"}, {"impera", {NULL}, 1710, "tcp"}, {"impera", {NULL}, 1710, "udp"}, {"pptconference", {NULL}, 1711, "tcp"}, {"pptconference", {NULL}, 1711, "udp"}, {"registrar", {NULL}, 1712, "tcp"}, {"registrar", {NULL}, 1712, "udp"}, {"conferencetalk", {NULL}, 1713, "tcp"}, {"conferencetalk", {NULL}, 1713, "udp"}, {"sesi-lm", {NULL}, 1714, "tcp"}, {"sesi-lm", {NULL}, 1714, "udp"}, {"houdini-lm", {NULL}, 1715, "tcp"}, {"houdini-lm", {NULL}, 1715, "udp"}, {"xmsg", {NULL}, 1716, "tcp"}, {"xmsg", {NULL}, 1716, "udp"}, {"fj-hdnet", {NULL}, 1717, "tcp"}, {"fj-hdnet", {NULL}, 1717, "udp"}, {"h323gatedisc", {NULL}, 1718, "tcp"}, {"h323gatedisc", {NULL}, 1718, "udp"}, {"h323gatestat", {NULL}, 1719, "tcp"}, {"h323gatestat", {NULL}, 1719, "udp"}, {"h323hostcall", {NULL}, 1720, "tcp"}, {"h323hostcall", {NULL}, 1720, "udp"}, {"caicci", {NULL}, 1721, "tcp"}, {"caicci", {NULL}, 1721, "udp"}, {"hks-lm", {NULL}, 1722, "tcp"}, {"hks-lm", {NULL}, 1722, "udp"}, {"pptp", {NULL}, 1723, "tcp"}, {"pptp", {NULL}, 1723, "udp"}, {"csbphonemaster", {NULL}, 1724, "tcp"}, {"csbphonemaster", {NULL}, 1724, "udp"}, {"iden-ralp", {NULL}, 1725, "tcp"}, {"iden-ralp", {NULL}, 1725, "udp"}, {"iberiagames", {NULL}, 1726, "tcp"}, {"iberiagames", {NULL}, 1726, "udp"}, {"winddx", {NULL}, 1727, "tcp"}, {"winddx", {NULL}, 1727, "udp"}, {"telindus", {NULL}, 1728, "tcp"}, {"telindus", {NULL}, 1728, "udp"}, {"citynl", {NULL}, 1729, "tcp"}, {"citynl", {NULL}, 1729, "udp"}, {"roketz", {NULL}, 1730, "tcp"}, {"roketz", {NULL}, 1730, "udp"}, {"msiccp", {NULL}, 1731, "tcp"}, {"msiccp", {NULL}, 1731, "udp"}, {"proxim", {NULL}, 1732, "tcp"}, {"proxim", {NULL}, 1732, "udp"}, {"siipat", {NULL}, 1733, "tcp"}, {"siipat", {NULL}, 1733, "udp"}, {"cambertx-lm", {NULL}, 1734, "tcp"}, {"cambertx-lm", {NULL}, 1734, "udp"}, {"privatechat", {NULL}, 1735, "tcp"}, {"privatechat", {NULL}, 1735, "udp"}, {"street-stream", {NULL}, 1736, "tcp"}, {"street-stream", {NULL}, 1736, "udp"}, {"ultimad", {NULL}, 1737, "tcp"}, {"ultimad", {NULL}, 1737, "udp"}, {"gamegen1", {NULL}, 1738, "tcp"}, {"gamegen1", {NULL}, 1738, "udp"}, {"webaccess", {NULL}, 1739, "tcp"}, {"webaccess", {NULL}, 1739, "udp"}, {"encore", {NULL}, 1740, "tcp"}, {"encore", {NULL}, 1740, "udp"}, {"cisco-net-mgmt", {NULL}, 1741, "tcp"}, {"cisco-net-mgmt", {NULL}, 1741, "udp"}, {"3Com-nsd", {NULL}, 1742, "tcp"}, {"3Com-nsd", {NULL}, 1742, "udp"}, {"cinegrfx-lm", {NULL}, 1743, "tcp"}, {"cinegrfx-lm", {NULL}, 1743, "udp"}, {"ncpm-ft", {NULL}, 1744, "tcp"}, {"ncpm-ft", {NULL}, 1744, "udp"}, {"remote-winsock", {NULL}, 1745, "tcp"}, {"remote-winsock", {NULL}, 1745, "udp"}, {"ftrapid-1", {NULL}, 1746, "tcp"}, {"ftrapid-1", {NULL}, 1746, "udp"}, {"ftrapid-2", {NULL}, 1747, "tcp"}, {"ftrapid-2", {NULL}, 1747, "udp"}, {"oracle-em1", {NULL}, 1748, "tcp"}, {"oracle-em1", {NULL}, 1748, "udp"}, {"aspen-services", {NULL}, 1749, "tcp"}, {"aspen-services", {NULL}, 1749, "udp"}, {"sslp", {NULL}, 1750, "tcp"}, {"sslp", {NULL}, 1750, "udp"}, {"swiftnet", {NULL}, 1751, "tcp"}, {"swiftnet", {NULL}, 1751, "udp"}, {"lofr-lm", {NULL}, 1752, "tcp"}, {"lofr-lm", {NULL}, 1752, "udp"}, {"oracle-em2", {NULL}, 1754, "tcp"}, {"oracle-em2", {NULL}, 1754, "udp"}, {"ms-streaming", {NULL}, 1755, "tcp"}, {"ms-streaming", {NULL}, 1755, "udp"}, {"capfast-lmd", {NULL}, 1756, "tcp"}, {"capfast-lmd", {NULL}, 1756, "udp"}, {"cnhrp", {NULL}, 1757, "tcp"}, {"cnhrp", {NULL}, 1757, "udp"}, {"tftp-mcast", {NULL}, 1758, "tcp"}, {"tftp-mcast", {NULL}, 1758, "udp"}, {"spss-lm", {NULL}, 1759, "tcp"}, {"spss-lm", {NULL}, 1759, "udp"}, {"www-ldap-gw", {NULL}, 1760, "tcp"}, {"www-ldap-gw", {NULL}, 1760, "udp"}, {"cft-0", {NULL}, 1761, "tcp"}, {"cft-0", {NULL}, 1761, "udp"}, {"cft-1", {NULL}, 1762, "tcp"}, {"cft-1", {NULL}, 1762, "udp"}, {"cft-2", {NULL}, 1763, "tcp"}, {"cft-2", {NULL}, 1763, "udp"}, {"cft-3", {NULL}, 1764, "tcp"}, {"cft-3", {NULL}, 1764, "udp"}, {"cft-4", {NULL}, 1765, "tcp"}, {"cft-4", {NULL}, 1765, "udp"}, {"cft-5", {NULL}, 1766, "tcp"}, {"cft-5", {NULL}, 1766, "udp"}, {"cft-6", {NULL}, 1767, "tcp"}, {"cft-6", {NULL}, 1767, "udp"}, {"cft-7", {NULL}, 1768, "tcp"}, {"cft-7", {NULL}, 1768, "udp"}, {"bmc-net-adm", {NULL}, 1769, "tcp"}, {"bmc-net-adm", {NULL}, 1769, "udp"}, {"bmc-net-svc", {NULL}, 1770, "tcp"}, {"bmc-net-svc", {NULL}, 1770, "udp"}, {"vaultbase", {NULL}, 1771, "tcp"}, {"vaultbase", {NULL}, 1771, "udp"}, {"essweb-gw", {NULL}, 1772, "tcp"}, {"essweb-gw", {NULL}, 1772, "udp"}, {"kmscontrol", {NULL}, 1773, "tcp"}, {"kmscontrol", {NULL}, 1773, "udp"}, {"global-dtserv", {NULL}, 1774, "tcp"}, {"global-dtserv", {NULL}, 1774, "udp"}, {"femis", {NULL}, 1776, "tcp"}, {"femis", {NULL}, 1776, "udp"}, {"powerguardian", {NULL}, 1777, "tcp"}, {"powerguardian", {NULL}, 1777, "udp"}, {"prodigy-intrnet", {NULL}, 1778, "tcp"}, {"prodigy-intrnet", {NULL}, 1778, "udp"}, {"pharmasoft", {NULL}, 1779, "tcp"}, {"pharmasoft", {NULL}, 1779, "udp"}, {"dpkeyserv", {NULL}, 1780, "tcp"}, {"dpkeyserv", {NULL}, 1780, "udp"}, {"answersoft-lm", {NULL}, 1781, "tcp"}, {"answersoft-lm", {NULL}, 1781, "udp"}, {"hp-hcip", {NULL}, 1782, "tcp"}, {"hp-hcip", {NULL}, 1782, "udp"}, {"finle-lm", {NULL}, 1784, "tcp"}, {"finle-lm", {NULL}, 1784, "udp"}, {"windlm", {NULL}, 1785, "tcp"}, {"windlm", {NULL}, 1785, "udp"}, {"funk-logger", {NULL}, 1786, "tcp"}, {"funk-logger", {NULL}, 1786, "udp"}, {"funk-license", {NULL}, 1787, "tcp"}, {"funk-license", {NULL}, 1787, "udp"}, {"psmond", {NULL}, 1788, "tcp"}, {"psmond", {NULL}, 1788, "udp"}, {"hello", {NULL}, 1789, "tcp"}, {"hello", {NULL}, 1789, "udp"}, {"nmsp", {NULL}, 1790, "tcp"}, {"nmsp", {NULL}, 1790, "udp"}, {"ea1", {NULL}, 1791, "tcp"}, {"ea1", {NULL}, 1791, "udp"}, {"ibm-dt-2", {NULL}, 1792, "tcp"}, {"ibm-dt-2", {NULL}, 1792, "udp"}, {"rsc-robot", {NULL}, 1793, "tcp"}, {"rsc-robot", {NULL}, 1793, "udp"}, {"cera-bcm", {NULL}, 1794, "tcp"}, {"cera-bcm", {NULL}, 1794, "udp"}, {"dpi-proxy", {NULL}, 1795, "tcp"}, {"dpi-proxy", {NULL}, 1795, "udp"}, {"vocaltec-admin", {NULL}, 1796, "tcp"}, {"vocaltec-admin", {NULL}, 1796, "udp"}, {"uma", {NULL}, 1797, "tcp"}, {"uma", {NULL}, 1797, "udp"}, {"etp", {NULL}, 1798, "tcp"}, {"etp", {NULL}, 1798, "udp"}, {"netrisk", {NULL}, 1799, "tcp"}, {"netrisk", {NULL}, 1799, "udp"}, {"ansys-lm", {NULL}, 1800, "tcp"}, {"ansys-lm", {NULL}, 1800, "udp"}, {"msmq", {NULL}, 1801, "tcp"}, {"msmq", {NULL}, 1801, "udp"}, {"concomp1", {NULL}, 1802, "tcp"}, {"concomp1", {NULL}, 1802, "udp"}, {"hp-hcip-gwy", {NULL}, 1803, "tcp"}, {"hp-hcip-gwy", {NULL}, 1803, "udp"}, {"enl", {NULL}, 1804, "tcp"}, {"enl", {NULL}, 1804, "udp"}, {"enl-name", {NULL}, 1805, "tcp"}, {"enl-name", {NULL}, 1805, "udp"}, {"musiconline", {NULL}, 1806, "tcp"}, {"musiconline", {NULL}, 1806, "udp"}, {"fhsp", {NULL}, 1807, "tcp"}, {"fhsp", {NULL}, 1807, "udp"}, {"oracle-vp2", {NULL}, 1808, "tcp"}, {"oracle-vp2", {NULL}, 1808, "udp"}, {"oracle-vp1", {NULL}, 1809, "tcp"}, {"oracle-vp1", {NULL}, 1809, "udp"}, {"jerand-lm", {NULL}, 1810, "tcp"}, {"jerand-lm", {NULL}, 1810, "udp"}, {"scientia-sdb", {NULL}, 1811, "tcp"}, {"scientia-sdb", {NULL}, 1811, "udp"}, {"radius", {NULL}, 1812, "tcp"}, {"radius", {NULL}, 1812, "udp"}, {"radius-acct", {NULL}, 1813, "tcp"}, {"radius-acct", {NULL}, 1813, "udp"}, {"tdp-suite", {NULL}, 1814, "tcp"}, {"tdp-suite", {NULL}, 1814, "udp"}, {"mmpft", {NULL}, 1815, "tcp"}, {"mmpft", {NULL}, 1815, "udp"}, {"harp", {NULL}, 1816, "tcp"}, {"harp", {NULL}, 1816, "udp"}, {"rkb-oscs", {NULL}, 1817, "tcp"}, {"rkb-oscs", {NULL}, 1817, "udp"}, {"etftp", {NULL}, 1818, "tcp"}, {"etftp", {NULL}, 1818, "udp"}, {"plato-lm", {NULL}, 1819, "tcp"}, {"plato-lm", {NULL}, 1819, "udp"}, {"mcagent", {NULL}, 1820, "tcp"}, {"mcagent", {NULL}, 1820, "udp"}, {"donnyworld", {NULL}, 1821, "tcp"}, {"donnyworld", {NULL}, 1821, "udp"}, {"es-elmd", {NULL}, 1822, "tcp"}, {"es-elmd", {NULL}, 1822, "udp"}, {"unisys-lm", {NULL}, 1823, "tcp"}, {"unisys-lm", {NULL}, 1823, "udp"}, {"metrics-pas", {NULL}, 1824, "tcp"}, {"metrics-pas", {NULL}, 1824, "udp"}, {"direcpc-video", {NULL}, 1825, "tcp"}, {"direcpc-video", {NULL}, 1825, "udp"}, {"ardt", {NULL}, 1826, "tcp"}, {"ardt", {NULL}, 1826, "udp"}, {"asi", {NULL}, 1827, "tcp"}, {"asi", {NULL}, 1827, "udp"}, {"itm-mcell-u", {NULL}, 1828, "tcp"}, {"itm-mcell-u", {NULL}, 1828, "udp"}, {"optika-emedia", {NULL}, 1829, "tcp"}, {"optika-emedia", {NULL}, 1829, "udp"}, {"net8-cman", {NULL}, 1830, "tcp"}, {"net8-cman", {NULL}, 1830, "udp"}, {"myrtle", {NULL}, 1831, "tcp"}, {"myrtle", {NULL}, 1831, "udp"}, {"tht-treasure", {NULL}, 1832, "tcp"}, {"tht-treasure", {NULL}, 1832, "udp"}, {"udpradio", {NULL}, 1833, "tcp"}, {"udpradio", {NULL}, 1833, "udp"}, {"ardusuni", {NULL}, 1834, "tcp"}, {"ardusuni", {NULL}, 1834, "udp"}, {"ardusmul", {NULL}, 1835, "tcp"}, {"ardusmul", {NULL}, 1835, "udp"}, {"ste-smsc", {NULL}, 1836, "tcp"}, {"ste-smsc", {NULL}, 1836, "udp"}, {"csoft1", {NULL}, 1837, "tcp"}, {"csoft1", {NULL}, 1837, "udp"}, {"talnet", {NULL}, 1838, "tcp"}, {"talnet", {NULL}, 1838, "udp"}, {"netopia-vo1", {NULL}, 1839, "tcp"}, {"netopia-vo1", {NULL}, 1839, "udp"}, {"netopia-vo2", {NULL}, 1840, "tcp"}, {"netopia-vo2", {NULL}, 1840, "udp"}, {"netopia-vo3", {NULL}, 1841, "tcp"}, {"netopia-vo3", {NULL}, 1841, "udp"}, {"netopia-vo4", {NULL}, 1842, "tcp"}, {"netopia-vo4", {NULL}, 1842, "udp"}, {"netopia-vo5", {NULL}, 1843, "tcp"}, {"netopia-vo5", {NULL}, 1843, "udp"}, {"direcpc-dll", {NULL}, 1844, "tcp"}, {"direcpc-dll", {NULL}, 1844, "udp"}, {"altalink", {NULL}, 1845, "tcp"}, {"altalink", {NULL}, 1845, "udp"}, {"tunstall-pnc", {NULL}, 1846, "tcp"}, {"tunstall-pnc", {NULL}, 1846, "udp"}, {"slp-notify", {NULL}, 1847, "tcp"}, {"slp-notify", {NULL}, 1847, "udp"}, {"fjdocdist", {NULL}, 1848, "tcp"}, {"fjdocdist", {NULL}, 1848, "udp"}, {"alpha-sms", {NULL}, 1849, "tcp"}, {"alpha-sms", {NULL}, 1849, "udp"}, {"gsi", {NULL}, 1850, "tcp"}, {"gsi", {NULL}, 1850, "udp"}, {"ctcd", {NULL}, 1851, "tcp"}, {"ctcd", {NULL}, 1851, "udp"}, {"virtual-time", {NULL}, 1852, "tcp"}, {"virtual-time", {NULL}, 1852, "udp"}, {"vids-avtp", {NULL}, 1853, "tcp"}, {"vids-avtp", {NULL}, 1853, "udp"}, {"buddy-draw", {NULL}, 1854, "tcp"}, {"buddy-draw", {NULL}, 1854, "udp"}, {"fiorano-rtrsvc", {NULL}, 1855, "tcp"}, {"fiorano-rtrsvc", {NULL}, 1855, "udp"}, {"fiorano-msgsvc", {NULL}, 1856, "tcp"}, {"fiorano-msgsvc", {NULL}, 1856, "udp"}, {"datacaptor", {NULL}, 1857, "tcp"}, {"datacaptor", {NULL}, 1857, "udp"}, {"privateark", {NULL}, 1858, "tcp"}, {"privateark", {NULL}, 1858, "udp"}, {"gammafetchsvr", {NULL}, 1859, "tcp"}, {"gammafetchsvr", {NULL}, 1859, "udp"}, {"sunscalar-svc", {NULL}, 1860, "tcp"}, {"sunscalar-svc", {NULL}, 1860, "udp"}, {"lecroy-vicp", {NULL}, 1861, "tcp"}, {"lecroy-vicp", {NULL}, 1861, "udp"}, {"mysql-cm-agent", {NULL}, 1862, "tcp"}, {"mysql-cm-agent", {NULL}, 1862, "udp"}, {"msnp", {NULL}, 1863, "tcp"}, {"msnp", {NULL}, 1863, "udp"}, {"paradym-31port", {NULL}, 1864, "tcp"}, {"paradym-31port", {NULL}, 1864, "udp"}, {"entp", {NULL}, 1865, "tcp"}, {"entp", {NULL}, 1865, "udp"}, {"swrmi", {NULL}, 1866, "tcp"}, {"swrmi", {NULL}, 1866, "udp"}, {"udrive", {NULL}, 1867, "tcp"}, {"udrive", {NULL}, 1867, "udp"}, {"viziblebrowser", {NULL}, 1868, "tcp"}, {"viziblebrowser", {NULL}, 1868, "udp"}, {"transact", {NULL}, 1869, "tcp"}, {"transact", {NULL}, 1869, "udp"}, {"sunscalar-dns", {NULL}, 1870, "tcp"}, {"sunscalar-dns", {NULL}, 1870, "udp"}, {"canocentral0", {NULL}, 1871, "tcp"}, {"canocentral0", {NULL}, 1871, "udp"}, {"canocentral1", {NULL}, 1872, "tcp"}, {"canocentral1", {NULL}, 1872, "udp"}, {"fjmpjps", {NULL}, 1873, "tcp"}, {"fjmpjps", {NULL}, 1873, "udp"}, {"fjswapsnp", {NULL}, 1874, "tcp"}, {"fjswapsnp", {NULL}, 1874, "udp"}, {"westell-stats", {NULL}, 1875, "tcp"}, {"westell-stats", {NULL}, 1875, "udp"}, {"ewcappsrv", {NULL}, 1876, "tcp"}, {"ewcappsrv", {NULL}, 1876, "udp"}, {"hp-webqosdb", {NULL}, 1877, "tcp"}, {"hp-webqosdb", {NULL}, 1877, "udp"}, {"drmsmc", {NULL}, 1878, "tcp"}, {"drmsmc", {NULL}, 1878, "udp"}, {"nettgain-nms", {NULL}, 1879, "tcp"}, {"nettgain-nms", {NULL}, 1879, "udp"}, {"vsat-control", {NULL}, 1880, "tcp"}, {"vsat-control", {NULL}, 1880, "udp"}, {"ibm-mqseries2", {NULL}, 1881, "tcp"}, {"ibm-mqseries2", {NULL}, 1881, "udp"}, {"ecsqdmn", {NULL}, 1882, "tcp"}, {"ecsqdmn", {NULL}, 1882, "udp"}, {"ibm-mqisdp", {NULL}, 1883, "tcp"}, {"ibm-mqisdp", {NULL}, 1883, "udp"}, {"idmaps", {NULL}, 1884, "tcp"}, {"idmaps", {NULL}, 1884, "udp"}, {"vrtstrapserver", {NULL}, 1885, "tcp"}, {"vrtstrapserver", {NULL}, 1885, "udp"}, {"leoip", {NULL}, 1886, "tcp"}, {"leoip", {NULL}, 1886, "udp"}, {"filex-lport", {NULL}, 1887, "tcp"}, {"filex-lport", {NULL}, 1887, "udp"}, {"ncconfig", {NULL}, 1888, "tcp"}, {"ncconfig", {NULL}, 1888, "udp"}, {"unify-adapter", {NULL}, 1889, "tcp"}, {"unify-adapter", {NULL}, 1889, "udp"}, {"wilkenlistener", {NULL}, 1890, "tcp"}, {"wilkenlistener", {NULL}, 1890, "udp"}, {"childkey-notif", {NULL}, 1891, "tcp"}, {"childkey-notif", {NULL}, 1891, "udp"}, {"childkey-ctrl", {NULL}, 1892, "tcp"}, {"childkey-ctrl", {NULL}, 1892, "udp"}, {"elad", {NULL}, 1893, "tcp"}, {"elad", {NULL}, 1893, "udp"}, {"o2server-port", {NULL}, 1894, "tcp"}, {"o2server-port", {NULL}, 1894, "udp"}, {"b-novative-ls", {NULL}, 1896, "tcp"}, {"b-novative-ls", {NULL}, 1896, "udp"}, {"metaagent", {NULL}, 1897, "tcp"}, {"metaagent", {NULL}, 1897, "udp"}, {"cymtec-port", {NULL}, 1898, "tcp"}, {"cymtec-port", {NULL}, 1898, "udp"}, {"mc2studios", {NULL}, 1899, "tcp"}, {"mc2studios", {NULL}, 1899, "udp"}, {"ssdp", {NULL}, 1900, "tcp"}, {"ssdp", {NULL}, 1900, "udp"}, {"fjicl-tep-a", {NULL}, 1901, "tcp"}, {"fjicl-tep-a", {NULL}, 1901, "udp"}, {"fjicl-tep-b", {NULL}, 1902, "tcp"}, {"fjicl-tep-b", {NULL}, 1902, "udp"}, {"linkname", {NULL}, 1903, "tcp"}, {"linkname", {NULL}, 1903, "udp"}, {"fjicl-tep-c", {NULL}, 1904, "tcp"}, {"fjicl-tep-c", {NULL}, 1904, "udp"}, {"sugp", {NULL}, 1905, "tcp"}, {"sugp", {NULL}, 1905, "udp"}, {"tpmd", {NULL}, 1906, "tcp"}, {"tpmd", {NULL}, 1906, "udp"}, {"intrastar", {NULL}, 1907, "tcp"}, {"intrastar", {NULL}, 1907, "udp"}, {"dawn", {NULL}, 1908, "tcp"}, {"dawn", {NULL}, 1908, "udp"}, {"global-wlink", {NULL}, 1909, "tcp"}, {"global-wlink", {NULL}, 1909, "udp"}, {"ultrabac", {NULL}, 1910, "tcp"}, {"ultrabac", {NULL}, 1910, "udp"}, {"mtp", {NULL}, 1911, "tcp"}, {"mtp", {NULL}, 1911, "udp"}, {"rhp-iibp", {NULL}, 1912, "tcp"}, {"rhp-iibp", {NULL}, 1912, "udp"}, {"armadp", {NULL}, 1913, "tcp"}, {"armadp", {NULL}, 1913, "udp"}, {"elm-momentum", {NULL}, 1914, "tcp"}, {"elm-momentum", {NULL}, 1914, "udp"}, {"facelink", {NULL}, 1915, "tcp"}, {"facelink", {NULL}, 1915, "udp"}, {"persona", {NULL}, 1916, "tcp"}, {"persona", {NULL}, 1916, "udp"}, {"noagent", {NULL}, 1917, "tcp"}, {"noagent", {NULL}, 1917, "udp"}, {"can-nds", {NULL}, 1918, "tcp"}, {"can-nds", {NULL}, 1918, "udp"}, {"can-dch", {NULL}, 1919, "tcp"}, {"can-dch", {NULL}, 1919, "udp"}, {"can-ferret", {NULL}, 1920, "tcp"}, {"can-ferret", {NULL}, 1920, "udp"}, {"noadmin", {NULL}, 1921, "tcp"}, {"noadmin", {NULL}, 1921, "udp"}, {"tapestry", {NULL}, 1922, "tcp"}, {"tapestry", {NULL}, 1922, "udp"}, {"spice", {NULL}, 1923, "tcp"}, {"spice", {NULL}, 1923, "udp"}, {"xiip", {NULL}, 1924, "tcp"}, {"xiip", {NULL}, 1924, "udp"}, {"discovery-port", {NULL}, 1925, "tcp"}, {"discovery-port", {NULL}, 1925, "udp"}, {"egs", {NULL}, 1926, "tcp"}, {"egs", {NULL}, 1926, "udp"}, {"videte-cipc", {NULL}, 1927, "tcp"}, {"videte-cipc", {NULL}, 1927, "udp"}, {"emsd-port", {NULL}, 1928, "tcp"}, {"emsd-port", {NULL}, 1928, "udp"}, {"bandwiz-system", {NULL}, 1929, "tcp"}, {"bandwiz-system", {NULL}, 1929, "udp"}, {"driveappserver", {NULL}, 1930, "tcp"}, {"driveappserver", {NULL}, 1930, "udp"}, {"amdsched", {NULL}, 1931, "tcp"}, {"amdsched", {NULL}, 1931, "udp"}, {"ctt-broker", {NULL}, 1932, "tcp"}, {"ctt-broker", {NULL}, 1932, "udp"}, {"xmapi", {NULL}, 1933, "tcp"}, {"xmapi", {NULL}, 1933, "udp"}, {"xaapi", {NULL}, 1934, "tcp"}, {"xaapi", {NULL}, 1934, "udp"}, {"macromedia-fcs", {NULL}, 1935, "tcp"}, {"macromedia-fcs", {NULL}, 1935, "udp"}, {"jetcmeserver", {NULL}, 1936, "tcp"}, {"jetcmeserver", {NULL}, 1936, "udp"}, {"jwserver", {NULL}, 1937, "tcp"}, {"jwserver", {NULL}, 1937, "udp"}, {"jwclient", {NULL}, 1938, "tcp"}, {"jwclient", {NULL}, 1938, "udp"}, {"jvserver", {NULL}, 1939, "tcp"}, {"jvserver", {NULL}, 1939, "udp"}, {"jvclient", {NULL}, 1940, "tcp"}, {"jvclient", {NULL}, 1940, "udp"}, {"dic-aida", {NULL}, 1941, "tcp"}, {"dic-aida", {NULL}, 1941, "udp"}, {"res", {NULL}, 1942, "tcp"}, {"res", {NULL}, 1942, "udp"}, {"beeyond-media", {NULL}, 1943, "tcp"}, {"beeyond-media", {NULL}, 1943, "udp"}, {"close-combat", {NULL}, 1944, "tcp"}, {"close-combat", {NULL}, 1944, "udp"}, {"dialogic-elmd", {NULL}, 1945, "tcp"}, {"dialogic-elmd", {NULL}, 1945, "udp"}, {"tekpls", {NULL}, 1946, "tcp"}, {"tekpls", {NULL}, 1946, "udp"}, {"sentinelsrm", {NULL}, 1947, "tcp"}, {"sentinelsrm", {NULL}, 1947, "udp"}, {"eye2eye", {NULL}, 1948, "tcp"}, {"eye2eye", {NULL}, 1948, "udp"}, {"ismaeasdaqlive", {NULL}, 1949, "tcp"}, {"ismaeasdaqlive", {NULL}, 1949, "udp"}, {"ismaeasdaqtest", {NULL}, 1950, "tcp"}, {"ismaeasdaqtest", {NULL}, 1950, "udp"}, {"bcs-lmserver", {NULL}, 1951, "tcp"}, {"bcs-lmserver", {NULL}, 1951, "udp"}, {"mpnjsc", {NULL}, 1952, "tcp"}, {"mpnjsc", {NULL}, 1952, "udp"}, {"rapidbase", {NULL}, 1953, "tcp"}, {"rapidbase", {NULL}, 1953, "udp"}, {"abr-api", {NULL}, 1954, "tcp"}, {"abr-api", {NULL}, 1954, "udp"}, {"abr-secure", {NULL}, 1955, "tcp"}, {"abr-secure", {NULL}, 1955, "udp"}, {"vrtl-vmf-ds", {NULL}, 1956, "tcp"}, {"vrtl-vmf-ds", {NULL}, 1956, "udp"}, {"unix-status", {NULL}, 1957, "tcp"}, {"unix-status", {NULL}, 1957, "udp"}, {"dxadmind", {NULL}, 1958, "tcp"}, {"dxadmind", {NULL}, 1958, "udp"}, {"simp-all", {NULL}, 1959, "tcp"}, {"simp-all", {NULL}, 1959, "udp"}, {"nasmanager", {NULL}, 1960, "tcp"}, {"nasmanager", {NULL}, 1960, "udp"}, {"bts-appserver", {NULL}, 1961, "tcp"}, {"bts-appserver", {NULL}, 1961, "udp"}, {"biap-mp", {NULL}, 1962, "tcp"}, {"biap-mp", {NULL}, 1962, "udp"}, {"webmachine", {NULL}, 1963, "tcp"}, {"webmachine", {NULL}, 1963, "udp"}, {"solid-e-engine", {NULL}, 1964, "tcp"}, {"solid-e-engine", {NULL}, 1964, "udp"}, {"tivoli-npm", {NULL}, 1965, "tcp"}, {"tivoli-npm", {NULL}, 1965, "udp"}, {"slush", {NULL}, 1966, "tcp"}, {"slush", {NULL}, 1966, "udp"}, {"sns-quote", {NULL}, 1967, "tcp"}, {"sns-quote", {NULL}, 1967, "udp"}, {"lipsinc", {NULL}, 1968, "tcp"}, {"lipsinc", {NULL}, 1968, "udp"}, {"lipsinc1", {NULL}, 1969, "tcp"}, {"lipsinc1", {NULL}, 1969, "udp"}, {"netop-rc", {NULL}, 1970, "tcp"}, {"netop-rc", {NULL}, 1970, "udp"}, {"netop-school", {NULL}, 1971, "tcp"}, {"netop-school", {NULL}, 1971, "udp"}, {"intersys-cache", {NULL}, 1972, "tcp"}, {"intersys-cache", {NULL}, 1972, "udp"}, {"dlsrap", {NULL}, 1973, "tcp"}, {"dlsrap", {NULL}, 1973, "udp"}, {"drp", {NULL}, 1974, "tcp"}, {"drp", {NULL}, 1974, "udp"}, {"tcoflashagent", {NULL}, 1975, "tcp"}, {"tcoflashagent", {NULL}, 1975, "udp"}, {"tcoregagent", {NULL}, 1976, "tcp"}, {"tcoregagent", {NULL}, 1976, "udp"}, {"tcoaddressbook", {NULL}, 1977, "tcp"}, {"tcoaddressbook", {NULL}, 1977, "udp"}, {"unisql", {NULL}, 1978, "tcp"}, {"unisql", {NULL}, 1978, "udp"}, {"unisql-java", {NULL}, 1979, "tcp"}, {"unisql-java", {NULL}, 1979, "udp"}, {"pearldoc-xact", {NULL}, 1980, "tcp"}, {"pearldoc-xact", {NULL}, 1980, "udp"}, {"p2pq", {NULL}, 1981, "tcp"}, {"p2pq", {NULL}, 1981, "udp"}, {"estamp", {NULL}, 1982, "tcp"}, {"estamp", {NULL}, 1982, "udp"}, {"lhtp", {NULL}, 1983, "tcp"}, {"lhtp", {NULL}, 1983, "udp"}, {"bb", {NULL}, 1984, "tcp"}, {"bb", {NULL}, 1984, "udp"}, {"hsrp", {NULL}, 1985, "tcp"}, {"hsrp", {NULL}, 1985, "udp"}, {"licensedaemon", {NULL}, 1986, "tcp"}, {"licensedaemon", {NULL}, 1986, "udp"}, {"tr-rsrb-p1", {NULL}, 1987, "tcp"}, {"tr-rsrb-p1", {NULL}, 1987, "udp"}, {"tr-rsrb-p2", {NULL}, 1988, "tcp"}, {"tr-rsrb-p2", {NULL}, 1988, "udp"}, {"tr-rsrb-p3", {NULL}, 1989, "tcp"}, {"tr-rsrb-p3", {NULL}, 1989, "udp"}, {"mshnet", {NULL}, 1989, "tcp"}, {"mshnet", {NULL}, 1989, "udp"}, {"stun-p1", {NULL}, 1990, "tcp"}, {"stun-p1", {NULL}, 1990, "udp"}, {"stun-p2", {NULL}, 1991, "tcp"}, {"stun-p2", {NULL}, 1991, "udp"}, {"stun-p3", {NULL}, 1992, "tcp"}, {"stun-p3", {NULL}, 1992, "udp"}, {"ipsendmsg", {NULL}, 1992, "tcp"}, {"ipsendmsg", {NULL}, 1992, "udp"}, {"snmp-tcp-port", {NULL}, 1993, "tcp"}, {"snmp-tcp-port", {NULL}, 1993, "udp"}, {"stun-port", {NULL}, 1994, "tcp"}, {"stun-port", {NULL}, 1994, "udp"}, {"perf-port", {NULL}, 1995, "tcp"}, {"perf-port", {NULL}, 1995, "udp"}, {"tr-rsrb-port", {NULL}, 1996, "tcp"}, {"tr-rsrb-port", {NULL}, 1996, "udp"}, {"gdp-port", {NULL}, 1997, "tcp"}, {"gdp-port", {NULL}, 1997, "udp"}, {"x25-svc-port", {NULL}, 1998, "tcp"}, {"x25-svc-port", {NULL}, 1998, "udp"}, {"tcp-id-port", {NULL}, 1999, "tcp"}, {"tcp-id-port", {NULL}, 1999, "udp"}, {"cisco-sccp", {NULL}, 2000, "tcp"}, {"cisco-sccp", {NULL}, 2000, "udp"}, {"dc", {NULL}, 2001, "tcp"}, {"wizard", {NULL}, 2001, "udp"}, {"globe", {NULL}, 2002, "tcp"}, {"globe", {NULL}, 2002, "udp"}, {"brutus", {NULL}, 2003, "tcp"}, {"brutus", {NULL}, 2003, "udp"}, {"mailbox", {NULL}, 2004, "tcp"}, {"emce", {NULL}, 2004, "udp"}, {"berknet", {NULL}, 2005, "tcp"}, {"oracle", {NULL}, 2005, "udp"}, {"invokator", {NULL}, 2006, "tcp"}, {"raid-cd", {NULL}, 2006, "udp"}, {"dectalk", {NULL}, 2007, "tcp"}, {"raid-am", {NULL}, 2007, "udp"}, {"conf", {NULL}, 2008, "tcp"}, {"terminaldb", {NULL}, 2008, "udp"}, {"news", {NULL}, 2009, "tcp"}, {"whosockami", {NULL}, 2009, "udp"}, {"search", {NULL}, 2010, "tcp"}, {"pipe_server", {NULL}, 2010, "udp"}, {"raid-cc", {NULL}, 2011, "tcp"}, {"servserv", {NULL}, 2011, "udp"}, {"ttyinfo", {NULL}, 2012, "tcp"}, {"raid-ac", {NULL}, 2012, "udp"}, {"raid-am", {NULL}, 2013, "tcp"}, {"raid-cd", {NULL}, 2013, "udp"}, {"troff", {NULL}, 2014, "tcp"}, {"raid-sf", {NULL}, 2014, "udp"}, {"cypress", {NULL}, 2015, "tcp"}, {"raid-cs", {NULL}, 2015, "udp"}, {"bootserver", {NULL}, 2016, "tcp"}, {"bootserver", {NULL}, 2016, "udp"}, {"cypress-stat", {NULL}, 2017, "tcp"}, {"bootclient", {NULL}, 2017, "udp"}, {"terminaldb", {NULL}, 2018, "tcp"}, {"rellpack", {NULL}, 2018, "udp"}, {"whosockami", {NULL}, 2019, "tcp"}, {"about", {NULL}, 2019, "udp"}, {"xinupageserver", {NULL}, 2020, "tcp"}, {"xinupageserver", {NULL}, 2020, "udp"}, {"servexec", {NULL}, 2021, "tcp"}, {"xinuexpansion1", {NULL}, 2021, "udp"}, {"down", {NULL}, 2022, "tcp"}, {"xinuexpansion2", {NULL}, 2022, "udp"}, {"xinuexpansion3", {NULL}, 2023, "tcp"}, {"xinuexpansion3", {NULL}, 2023, "udp"}, {"xinuexpansion4", {NULL}, 2024, "tcp"}, {"xinuexpansion4", {NULL}, 2024, "udp"}, {"ellpack", {NULL}, 2025, "tcp"}, {"xribs", {NULL}, 2025, "udp"}, {"scrabble", {NULL}, 2026, "tcp"}, {"scrabble", {NULL}, 2026, "udp"}, {"shadowserver", {NULL}, 2027, "tcp"}, {"shadowserver", {NULL}, 2027, "udp"}, {"submitserver", {NULL}, 2028, "tcp"}, {"submitserver", {NULL}, 2028, "udp"}, {"hsrpv6", {NULL}, 2029, "tcp"}, {"hsrpv6", {NULL}, 2029, "udp"}, {"device2", {NULL}, 2030, "tcp"}, {"device2", {NULL}, 2030, "udp"}, {"mobrien-chat", {NULL}, 2031, "tcp"}, {"mobrien-chat", {NULL}, 2031, "udp"}, {"blackboard", {NULL}, 2032, "tcp"}, {"blackboard", {NULL}, 2032, "udp"}, {"glogger", {NULL}, 2033, "tcp"}, {"glogger", {NULL}, 2033, "udp"}, {"scoremgr", {NULL}, 2034, "tcp"}, {"scoremgr", {NULL}, 2034, "udp"}, {"imsldoc", {NULL}, 2035, "tcp"}, {"imsldoc", {NULL}, 2035, "udp"}, {"e-dpnet", {NULL}, 2036, "tcp"}, {"e-dpnet", {NULL}, 2036, "udp"}, {"applus", {NULL}, 2037, "tcp"}, {"applus", {NULL}, 2037, "udp"}, {"objectmanager", {NULL}, 2038, "tcp"}, {"objectmanager", {NULL}, 2038, "udp"}, {"prizma", {NULL}, 2039, "tcp"}, {"prizma", {NULL}, 2039, "udp"}, {"lam", {NULL}, 2040, "tcp"}, {"lam", {NULL}, 2040, "udp"}, {"interbase", {NULL}, 2041, "tcp"}, {"interbase", {NULL}, 2041, "udp"}, {"isis", {NULL}, 2042, "tcp"}, {"isis", {NULL}, 2042, "udp"}, {"isis-bcast", {NULL}, 2043, "tcp"}, {"isis-bcast", {NULL}, 2043, "udp"}, {"rimsl", {NULL}, 2044, "tcp"}, {"rimsl", {NULL}, 2044, "udp"}, {"cdfunc", {NULL}, 2045, "tcp"}, {"cdfunc", {NULL}, 2045, "udp"}, {"sdfunc", {NULL}, 2046, "tcp"}, {"sdfunc", {NULL}, 2046, "udp"}, {"dls", {NULL}, 2047, "tcp"}, {"dls", {NULL}, 2047, "udp"}, {"dls-monitor", {NULL}, 2048, "tcp"}, {"dls-monitor", {NULL}, 2048, "udp"}, {"shilp", {NULL}, 2049, "tcp"}, {"shilp", {NULL}, 2049, "udp"}, {"nfs", {NULL}, 2049, "tcp"}, {"nfs", {NULL}, 2049, "udp"}, {"nfs", {NULL}, 2049, "sctp"}, {"av-emb-config", {NULL}, 2050, "tcp"}, {"av-emb-config", {NULL}, 2050, "udp"}, {"epnsdp", {NULL}, 2051, "tcp"}, {"epnsdp", {NULL}, 2051, "udp"}, {"clearvisn", {NULL}, 2052, "tcp"}, {"clearvisn", {NULL}, 2052, "udp"}, {"lot105-ds-upd", {NULL}, 2053, "tcp"}, {"lot105-ds-upd", {NULL}, 2053, "udp"}, {"weblogin", {NULL}, 2054, "tcp"}, {"weblogin", {NULL}, 2054, "udp"}, {"iop", {NULL}, 2055, "tcp"}, {"iop", {NULL}, 2055, "udp"}, {"omnisky", {NULL}, 2056, "tcp"}, {"omnisky", {NULL}, 2056, "udp"}, {"rich-cp", {NULL}, 2057, "tcp"}, {"rich-cp", {NULL}, 2057, "udp"}, {"newwavesearch", {NULL}, 2058, "tcp"}, {"newwavesearch", {NULL}, 2058, "udp"}, {"bmc-messaging", {NULL}, 2059, "tcp"}, {"bmc-messaging", {NULL}, 2059, "udp"}, {"teleniumdaemon", {NULL}, 2060, "tcp"}, {"teleniumdaemon", {NULL}, 2060, "udp"}, {"netmount", {NULL}, 2061, "tcp"}, {"netmount", {NULL}, 2061, "udp"}, {"icg-swp", {NULL}, 2062, "tcp"}, {"icg-swp", {NULL}, 2062, "udp"}, {"icg-bridge", {NULL}, 2063, "tcp"}, {"icg-bridge", {NULL}, 2063, "udp"}, {"icg-iprelay", {NULL}, 2064, "tcp"}, {"icg-iprelay", {NULL}, 2064, "udp"}, {"dlsrpn", {NULL}, 2065, "tcp"}, {"dlsrpn", {NULL}, 2065, "udp"}, {"aura", {NULL}, 2066, "tcp"}, {"aura", {NULL}, 2066, "udp"}, {"dlswpn", {NULL}, 2067, "tcp"}, {"dlswpn", {NULL}, 2067, "udp"}, {"avauthsrvprtcl", {NULL}, 2068, "tcp"}, {"avauthsrvprtcl", {NULL}, 2068, "udp"}, {"event-port", {NULL}, 2069, "tcp"}, {"event-port", {NULL}, 2069, "udp"}, {"ah-esp-encap", {NULL}, 2070, "tcp"}, {"ah-esp-encap", {NULL}, 2070, "udp"}, {"acp-port", {NULL}, 2071, "tcp"}, {"acp-port", {NULL}, 2071, "udp"}, {"msync", {NULL}, 2072, "tcp"}, {"msync", {NULL}, 2072, "udp"}, {"gxs-data-port", {NULL}, 2073, "tcp"}, {"gxs-data-port", {NULL}, 2073, "udp"}, {"vrtl-vmf-sa", {NULL}, 2074, "tcp"}, {"vrtl-vmf-sa", {NULL}, 2074, "udp"}, {"newlixengine", {NULL}, 2075, "tcp"}, {"newlixengine", {NULL}, 2075, "udp"}, {"newlixconfig", {NULL}, 2076, "tcp"}, {"newlixconfig", {NULL}, 2076, "udp"}, {"tsrmagt", {NULL}, 2077, "tcp"}, {"tsrmagt", {NULL}, 2077, "udp"}, {"tpcsrvr", {NULL}, 2078, "tcp"}, {"tpcsrvr", {NULL}, 2078, "udp"}, {"idware-router", {NULL}, 2079, "tcp"}, {"idware-router", {NULL}, 2079, "udp"}, {"autodesk-nlm", {NULL}, 2080, "tcp"}, {"autodesk-nlm", {NULL}, 2080, "udp"}, {"kme-trap-port", {NULL}, 2081, "tcp"}, {"kme-trap-port", {NULL}, 2081, "udp"}, {"infowave", {NULL}, 2082, "tcp"}, {"infowave", {NULL}, 2082, "udp"}, {"radsec", {NULL}, 2083, "tcp"}, {"radsec", {NULL}, 2083, "udp"}, {"sunclustergeo", {NULL}, 2084, "tcp"}, {"sunclustergeo", {NULL}, 2084, "udp"}, {"ada-cip", {NULL}, 2085, "tcp"}, {"ada-cip", {NULL}, 2085, "udp"}, {"gnunet", {NULL}, 2086, "tcp"}, {"gnunet", {NULL}, 2086, "udp"}, {"eli", {NULL}, 2087, "tcp"}, {"eli", {NULL}, 2087, "udp"}, {"ip-blf", {NULL}, 2088, "tcp"}, {"ip-blf", {NULL}, 2088, "udp"}, {"sep", {NULL}, 2089, "tcp"}, {"sep", {NULL}, 2089, "udp"}, {"lrp", {NULL}, 2090, "tcp"}, {"lrp", {NULL}, 2090, "udp"}, {"prp", {NULL}, 2091, "tcp"}, {"prp", {NULL}, 2091, "udp"}, {"descent3", {NULL}, 2092, "tcp"}, {"descent3", {NULL}, 2092, "udp"}, {"nbx-cc", {NULL}, 2093, "tcp"}, {"nbx-cc", {NULL}, 2093, "udp"}, {"nbx-au", {NULL}, 2094, "tcp"}, {"nbx-au", {NULL}, 2094, "udp"}, {"nbx-ser", {NULL}, 2095, "tcp"}, {"nbx-ser", {NULL}, 2095, "udp"}, {"nbx-dir", {NULL}, 2096, "tcp"}, {"nbx-dir", {NULL}, 2096, "udp"}, {"jetformpreview", {NULL}, 2097, "tcp"}, {"jetformpreview", {NULL}, 2097, "udp"}, {"dialog-port", {NULL}, 2098, "tcp"}, {"dialog-port", {NULL}, 2098, "udp"}, {"h2250-annex-g", {NULL}, 2099, "tcp"}, {"h2250-annex-g", {NULL}, 2099, "udp"}, {"amiganetfs", {NULL}, 2100, "tcp"}, {"amiganetfs", {NULL}, 2100, "udp"}, {"rtcm-sc104", {NULL}, 2101, "tcp"}, {"rtcm-sc104", {NULL}, 2101, "udp"}, {"zephyr-srv", {NULL}, 2102, "tcp"}, {"zephyr-srv", {NULL}, 2102, "udp"}, {"zephyr-clt", {NULL}, 2103, "tcp"}, {"zephyr-clt", {NULL}, 2103, "udp"}, {"zephyr-hm", {NULL}, 2104, "tcp"}, {"zephyr-hm", {NULL}, 2104, "udp"}, {"minipay", {NULL}, 2105, "tcp"}, {"minipay", {NULL}, 2105, "udp"}, {"mzap", {NULL}, 2106, "tcp"}, {"mzap", {NULL}, 2106, "udp"}, {"bintec-admin", {NULL}, 2107, "tcp"}, {"bintec-admin", {NULL}, 2107, "udp"}, {"comcam", {NULL}, 2108, "tcp"}, {"comcam", {NULL}, 2108, "udp"}, {"ergolight", {NULL}, 2109, "tcp"}, {"ergolight", {NULL}, 2109, "udp"}, {"umsp", {NULL}, 2110, "tcp"}, {"umsp", {NULL}, 2110, "udp"}, {"dsatp", {NULL}, 2111, "tcp"}, {"dsatp", {NULL}, 2111, "udp"}, {"idonix-metanet", {NULL}, 2112, "tcp"}, {"idonix-metanet", {NULL}, 2112, "udp"}, {"hsl-storm", {NULL}, 2113, "tcp"}, {"hsl-storm", {NULL}, 2113, "udp"}, {"newheights", {NULL}, 2114, "tcp"}, {"newheights", {NULL}, 2114, "udp"}, {"kdm", {NULL}, 2115, "tcp"}, {"kdm", {NULL}, 2115, "udp"}, {"ccowcmr", {NULL}, 2116, "tcp"}, {"ccowcmr", {NULL}, 2116, "udp"}, {"mentaclient", {NULL}, 2117, "tcp"}, {"mentaclient", {NULL}, 2117, "udp"}, {"mentaserver", {NULL}, 2118, "tcp"}, {"mentaserver", {NULL}, 2118, "udp"}, {"gsigatekeeper", {NULL}, 2119, "tcp"}, {"gsigatekeeper", {NULL}, 2119, "udp"}, {"qencp", {NULL}, 2120, "tcp"}, {"qencp", {NULL}, 2120, "udp"}, {"scientia-ssdb", {NULL}, 2121, "tcp"}, {"scientia-ssdb", {NULL}, 2121, "udp"}, {"caupc-remote", {NULL}, 2122, "tcp"}, {"caupc-remote", {NULL}, 2122, "udp"}, {"gtp-control", {NULL}, 2123, "tcp"}, {"gtp-control", {NULL}, 2123, "udp"}, {"elatelink", {NULL}, 2124, "tcp"}, {"elatelink", {NULL}, 2124, "udp"}, {"lockstep", {NULL}, 2125, "tcp"}, {"lockstep", {NULL}, 2125, "udp"}, {"pktcable-cops", {NULL}, 2126, "tcp"}, {"pktcable-cops", {NULL}, 2126, "udp"}, {"index-pc-wb", {NULL}, 2127, "tcp"}, {"index-pc-wb", {NULL}, 2127, "udp"}, {"net-steward", {NULL}, 2128, "tcp"}, {"net-steward", {NULL}, 2128, "udp"}, {"cs-live", {NULL}, 2129, "tcp"}, {"cs-live", {NULL}, 2129, "udp"}, {"xds", {NULL}, 2130, "tcp"}, {"xds", {NULL}, 2130, "udp"}, {"avantageb2b", {NULL}, 2131, "tcp"}, {"avantageb2b", {NULL}, 2131, "udp"}, {"solera-epmap", {NULL}, 2132, "tcp"}, {"solera-epmap", {NULL}, 2132, "udp"}, {"zymed-zpp", {NULL}, 2133, "tcp"}, {"zymed-zpp", {NULL}, 2133, "udp"}, {"avenue", {NULL}, 2134, "tcp"}, {"avenue", {NULL}, 2134, "udp"}, {"gris", {NULL}, 2135, "tcp"}, {"gris", {NULL}, 2135, "udp"}, {"appworxsrv", {NULL}, 2136, "tcp"}, {"appworxsrv", {NULL}, 2136, "udp"}, {"connect", {NULL}, 2137, "tcp"}, {"connect", {NULL}, 2137, "udp"}, {"unbind-cluster", {NULL}, 2138, "tcp"}, {"unbind-cluster", {NULL}, 2138, "udp"}, {"ias-auth", {NULL}, 2139, "tcp"}, {"ias-auth", {NULL}, 2139, "udp"}, {"ias-reg", {NULL}, 2140, "tcp"}, {"ias-reg", {NULL}, 2140, "udp"}, {"ias-admind", {NULL}, 2141, "tcp"}, {"ias-admind", {NULL}, 2141, "udp"}, {"tdmoip", {NULL}, 2142, "tcp"}, {"tdmoip", {NULL}, 2142, "udp"}, {"lv-jc", {NULL}, 2143, "tcp"}, {"lv-jc", {NULL}, 2143, "udp"}, {"lv-ffx", {NULL}, 2144, "tcp"}, {"lv-ffx", {NULL}, 2144, "udp"}, {"lv-pici", {NULL}, 2145, "tcp"}, {"lv-pici", {NULL}, 2145, "udp"}, {"lv-not", {NULL}, 2146, "tcp"}, {"lv-not", {NULL}, 2146, "udp"}, {"lv-auth", {NULL}, 2147, "tcp"}, {"lv-auth", {NULL}, 2147, "udp"}, {"veritas-ucl", {NULL}, 2148, "tcp"}, {"veritas-ucl", {NULL}, 2148, "udp"}, {"acptsys", {NULL}, 2149, "tcp"}, {"acptsys", {NULL}, 2149, "udp"}, {"dynamic3d", {NULL}, 2150, "tcp"}, {"dynamic3d", {NULL}, 2150, "udp"}, {"docent", {NULL}, 2151, "tcp"}, {"docent", {NULL}, 2151, "udp"}, {"gtp-user", {NULL}, 2152, "tcp"}, {"gtp-user", {NULL}, 2152, "udp"}, {"ctlptc", {NULL}, 2153, "tcp"}, {"ctlptc", {NULL}, 2153, "udp"}, {"stdptc", {NULL}, 2154, "tcp"}, {"stdptc", {NULL}, 2154, "udp"}, {"brdptc", {NULL}, 2155, "tcp"}, {"brdptc", {NULL}, 2155, "udp"}, {"trp", {NULL}, 2156, "tcp"}, {"trp", {NULL}, 2156, "udp"}, {"xnds", {NULL}, 2157, "tcp"}, {"xnds", {NULL}, 2157, "udp"}, {"touchnetplus", {NULL}, 2158, "tcp"}, {"touchnetplus", {NULL}, 2158, "udp"}, {"gdbremote", {NULL}, 2159, "tcp"}, {"gdbremote", {NULL}, 2159, "udp"}, {"apc-2160", {NULL}, 2160, "tcp"}, {"apc-2160", {NULL}, 2160, "udp"}, {"apc-2161", {NULL}, 2161, "tcp"}, {"apc-2161", {NULL}, 2161, "udp"}, {"navisphere", {NULL}, 2162, "tcp"}, {"navisphere", {NULL}, 2162, "udp"}, {"navisphere-sec", {NULL}, 2163, "tcp"}, {"navisphere-sec", {NULL}, 2163, "udp"}, {"ddns-v3", {NULL}, 2164, "tcp"}, {"ddns-v3", {NULL}, 2164, "udp"}, {"x-bone-api", {NULL}, 2165, "tcp"}, {"x-bone-api", {NULL}, 2165, "udp"}, {"iwserver", {NULL}, 2166, "tcp"}, {"iwserver", {NULL}, 2166, "udp"}, {"raw-serial", {NULL}, 2167, "tcp"}, {"raw-serial", {NULL}, 2167, "udp"}, {"easy-soft-mux", {NULL}, 2168, "tcp"}, {"easy-soft-mux", {NULL}, 2168, "udp"}, {"brain", {NULL}, 2169, "tcp"}, {"brain", {NULL}, 2169, "udp"}, {"eyetv", {NULL}, 2170, "tcp"}, {"eyetv", {NULL}, 2170, "udp"}, {"msfw-storage", {NULL}, 2171, "tcp"}, {"msfw-storage", {NULL}, 2171, "udp"}, {"msfw-s-storage", {NULL}, 2172, "tcp"}, {"msfw-s-storage", {NULL}, 2172, "udp"}, {"msfw-replica", {NULL}, 2173, "tcp"}, {"msfw-replica", {NULL}, 2173, "udp"}, {"msfw-array", {NULL}, 2174, "tcp"}, {"msfw-array", {NULL}, 2174, "udp"}, {"airsync", {NULL}, 2175, "tcp"}, {"airsync", {NULL}, 2175, "udp"}, {"rapi", {NULL}, 2176, "tcp"}, {"rapi", {NULL}, 2176, "udp"}, {"qwave", {NULL}, 2177, "tcp"}, {"qwave", {NULL}, 2177, "udp"}, {"bitspeer", {NULL}, 2178, "tcp"}, {"bitspeer", {NULL}, 2178, "udp"}, {"vmrdp", {NULL}, 2179, "tcp"}, {"vmrdp", {NULL}, 2179, "udp"}, {"mc-gt-srv", {NULL}, 2180, "tcp"}, {"mc-gt-srv", {NULL}, 2180, "udp"}, {"eforward", {NULL}, 2181, "tcp"}, {"eforward", {NULL}, 2181, "udp"}, {"cgn-stat", {NULL}, 2182, "tcp"}, {"cgn-stat", {NULL}, 2182, "udp"}, {"cgn-config", {NULL}, 2183, "tcp"}, {"cgn-config", {NULL}, 2183, "udp"}, {"nvd", {NULL}, 2184, "tcp"}, {"nvd", {NULL}, 2184, "udp"}, {"onbase-dds", {NULL}, 2185, "tcp"}, {"onbase-dds", {NULL}, 2185, "udp"}, {"gtaua", {NULL}, 2186, "tcp"}, {"gtaua", {NULL}, 2186, "udp"}, {"ssmc", {NULL}, 2187, "tcp"}, {"ssmd", {NULL}, 2187, "udp"}, {"tivoconnect", {NULL}, 2190, "tcp"}, {"tivoconnect", {NULL}, 2190, "udp"}, {"tvbus", {NULL}, 2191, "tcp"}, {"tvbus", {NULL}, 2191, "udp"}, {"asdis", {NULL}, 2192, "tcp"}, {"asdis", {NULL}, 2192, "udp"}, {"drwcs", {NULL}, 2193, "tcp"}, {"drwcs", {NULL}, 2193, "udp"}, {"mnp-exchange", {NULL}, 2197, "tcp"}, {"mnp-exchange", {NULL}, 2197, "udp"}, {"onehome-remote", {NULL}, 2198, "tcp"}, {"onehome-remote", {NULL}, 2198, "udp"}, {"onehome-help", {NULL}, 2199, "tcp"}, {"onehome-help", {NULL}, 2199, "udp"}, {"ici", {NULL}, 2200, "tcp"}, {"ici", {NULL}, 2200, "udp"}, {"ats", {NULL}, 2201, "tcp"}, {"ats", {NULL}, 2201, "udp"}, {"imtc-map", {NULL}, 2202, "tcp"}, {"imtc-map", {NULL}, 2202, "udp"}, {"b2-runtime", {NULL}, 2203, "tcp"}, {"b2-runtime", {NULL}, 2203, "udp"}, {"b2-license", {NULL}, 2204, "tcp"}, {"b2-license", {NULL}, 2204, "udp"}, {"jps", {NULL}, 2205, "tcp"}, {"jps", {NULL}, 2205, "udp"}, {"hpocbus", {NULL}, 2206, "tcp"}, {"hpocbus", {NULL}, 2206, "udp"}, {"hpssd", {NULL}, 2207, "tcp"}, {"hpssd", {NULL}, 2207, "udp"}, {"hpiod", {NULL}, 2208, "tcp"}, {"hpiod", {NULL}, 2208, "udp"}, {"rimf-ps", {NULL}, 2209, "tcp"}, {"rimf-ps", {NULL}, 2209, "udp"}, {"noaaport", {NULL}, 2210, "tcp"}, {"noaaport", {NULL}, 2210, "udp"}, {"emwin", {NULL}, 2211, "tcp"}, {"emwin", {NULL}, 2211, "udp"}, {"leecoposserver", {NULL}, 2212, "tcp"}, {"leecoposserver", {NULL}, 2212, "udp"}, {"kali", {NULL}, 2213, "tcp"}, {"kali", {NULL}, 2213, "udp"}, {"rpi", {NULL}, 2214, "tcp"}, {"rpi", {NULL}, 2214, "udp"}, {"ipcore", {NULL}, 2215, "tcp"}, {"ipcore", {NULL}, 2215, "udp"}, {"vtu-comms", {NULL}, 2216, "tcp"}, {"vtu-comms", {NULL}, 2216, "udp"}, {"gotodevice", {NULL}, 2217, "tcp"}, {"gotodevice", {NULL}, 2217, "udp"}, {"bounzza", {NULL}, 2218, "tcp"}, {"bounzza", {NULL}, 2218, "udp"}, {"netiq-ncap", {NULL}, 2219, "tcp"}, {"netiq-ncap", {NULL}, 2219, "udp"}, {"netiq", {NULL}, 2220, "tcp"}, {"netiq", {NULL}, 2220, "udp"}, {"rockwell-csp1", {NULL}, 2221, "tcp"}, {"rockwell-csp1", {NULL}, 2221, "udp"}, {"EtherNet/IP-1", {NULL}, 2222, "tcp"}, {"EtherNet/IP-1", {NULL}, 2222, "udp"}, {"rockwell-csp2", {NULL}, 2223, "tcp"}, {"rockwell-csp2", {NULL}, 2223, "udp"}, {"efi-mg", {NULL}, 2224, "tcp"}, {"efi-mg", {NULL}, 2224, "udp"}, {"rcip-itu", {NULL}, 2225, "tcp"}, {"rcip-itu", {NULL}, 2225, "sctp"}, {"di-drm", {NULL}, 2226, "tcp"}, {"di-drm", {NULL}, 2226, "udp"}, {"di-msg", {NULL}, 2227, "tcp"}, {"di-msg", {NULL}, 2227, "udp"}, {"ehome-ms", {NULL}, 2228, "tcp"}, {"ehome-ms", {NULL}, 2228, "udp"}, {"datalens", {NULL}, 2229, "tcp"}, {"datalens", {NULL}, 2229, "udp"}, {"queueadm", {NULL}, 2230, "tcp"}, {"queueadm", {NULL}, 2230, "udp"}, {"wimaxasncp", {NULL}, 2231, "tcp"}, {"wimaxasncp", {NULL}, 2231, "udp"}, {"ivs-video", {NULL}, 2232, "tcp"}, {"ivs-video", {NULL}, 2232, "udp"}, {"infocrypt", {NULL}, 2233, "tcp"}, {"infocrypt", {NULL}, 2233, "udp"}, {"directplay", {NULL}, 2234, "tcp"}, {"directplay", {NULL}, 2234, "udp"}, {"sercomm-wlink", {NULL}, 2235, "tcp"}, {"sercomm-wlink", {NULL}, 2235, "udp"}, {"nani", {NULL}, 2236, "tcp"}, {"nani", {NULL}, 2236, "udp"}, {"optech-port1-lm", {NULL}, 2237, "tcp"}, {"optech-port1-lm", {NULL}, 2237, "udp"}, {"aviva-sna", {NULL}, 2238, "tcp"}, {"aviva-sna", {NULL}, 2238, "udp"}, {"imagequery", {NULL}, 2239, "tcp"}, {"imagequery", {NULL}, 2239, "udp"}, {"recipe", {NULL}, 2240, "tcp"}, {"recipe", {NULL}, 2240, "udp"}, {"ivsd", {NULL}, 2241, "tcp"}, {"ivsd", {NULL}, 2241, "udp"}, {"foliocorp", {NULL}, 2242, "tcp"}, {"foliocorp", {NULL}, 2242, "udp"}, {"magicom", {NULL}, 2243, "tcp"}, {"magicom", {NULL}, 2243, "udp"}, {"nmsserver", {NULL}, 2244, "tcp"}, {"nmsserver", {NULL}, 2244, "udp"}, {"hao", {NULL}, 2245, "tcp"}, {"hao", {NULL}, 2245, "udp"}, {"pc-mta-addrmap", {NULL}, 2246, "tcp"}, {"pc-mta-addrmap", {NULL}, 2246, "udp"}, {"antidotemgrsvr", {NULL}, 2247, "tcp"}, {"antidotemgrsvr", {NULL}, 2247, "udp"}, {"ums", {NULL}, 2248, "tcp"}, {"ums", {NULL}, 2248, "udp"}, {"rfmp", {NULL}, 2249, "tcp"}, {"rfmp", {NULL}, 2249, "udp"}, {"remote-collab", {NULL}, 2250, "tcp"}, {"remote-collab", {NULL}, 2250, "udp"}, {"dif-port", {NULL}, 2251, "tcp"}, {"dif-port", {NULL}, 2251, "udp"}, {"njenet-ssl", {NULL}, 2252, "tcp"}, {"njenet-ssl", {NULL}, 2252, "udp"}, {"dtv-chan-req", {NULL}, 2253, "tcp"}, {"dtv-chan-req", {NULL}, 2253, "udp"}, {"seispoc", {NULL}, 2254, "tcp"}, {"seispoc", {NULL}, 2254, "udp"}, {"vrtp", {NULL}, 2255, "tcp"}, {"vrtp", {NULL}, 2255, "udp"}, {"pcc-mfp", {NULL}, 2256, "tcp"}, {"pcc-mfp", {NULL}, 2256, "udp"}, {"simple-tx-rx", {NULL}, 2257, "tcp"}, {"simple-tx-rx", {NULL}, 2257, "udp"}, {"rcts", {NULL}, 2258, "tcp"}, {"rcts", {NULL}, 2258, "udp"}, {"acd-pm", {NULL}, 2259, "tcp"}, {"acd-pm", {NULL}, 2259, "udp"}, {"apc-2260", {NULL}, 2260, "tcp"}, {"apc-2260", {NULL}, 2260, "udp"}, {"comotionmaster", {NULL}, 2261, "tcp"}, {"comotionmaster", {NULL}, 2261, "udp"}, {"comotionback", {NULL}, 2262, "tcp"}, {"comotionback", {NULL}, 2262, "udp"}, {"ecwcfg", {NULL}, 2263, "tcp"}, {"ecwcfg", {NULL}, 2263, "udp"}, {"apx500api-1", {NULL}, 2264, "tcp"}, {"apx500api-1", {NULL}, 2264, "udp"}, {"apx500api-2", {NULL}, 2265, "tcp"}, {"apx500api-2", {NULL}, 2265, "udp"}, {"mfserver", {NULL}, 2266, "tcp"}, {"mfserver", {NULL}, 2266, "udp"}, {"ontobroker", {NULL}, 2267, "tcp"}, {"ontobroker", {NULL}, 2267, "udp"}, {"amt", {NULL}, 2268, "tcp"}, {"amt", {NULL}, 2268, "udp"}, {"mikey", {NULL}, 2269, "tcp"}, {"mikey", {NULL}, 2269, "udp"}, {"starschool", {NULL}, 2270, "tcp"}, {"starschool", {NULL}, 2270, "udp"}, {"mmcals", {NULL}, 2271, "tcp"}, {"mmcals", {NULL}, 2271, "udp"}, {"mmcal", {NULL}, 2272, "tcp"}, {"mmcal", {NULL}, 2272, "udp"}, {"mysql-im", {NULL}, 2273, "tcp"}, {"mysql-im", {NULL}, 2273, "udp"}, {"pcttunnell", {NULL}, 2274, "tcp"}, {"pcttunnell", {NULL}, 2274, "udp"}, {"ibridge-data", {NULL}, 2275, "tcp"}, {"ibridge-data", {NULL}, 2275, "udp"}, {"ibridge-mgmt", {NULL}, 2276, "tcp"}, {"ibridge-mgmt", {NULL}, 2276, "udp"}, {"bluectrlproxy", {NULL}, 2277, "tcp"}, {"bluectrlproxy", {NULL}, 2277, "udp"}, {"s3db", {NULL}, 2278, "tcp"}, {"s3db", {NULL}, 2278, "udp"}, {"xmquery", {NULL}, 2279, "tcp"}, {"xmquery", {NULL}, 2279, "udp"}, {"lnvpoller", {NULL}, 2280, "tcp"}, {"lnvpoller", {NULL}, 2280, "udp"}, {"lnvconsole", {NULL}, 2281, "tcp"}, {"lnvconsole", {NULL}, 2281, "udp"}, {"lnvalarm", {NULL}, 2282, "tcp"}, {"lnvalarm", {NULL}, 2282, "udp"}, {"lnvstatus", {NULL}, 2283, "tcp"}, {"lnvstatus", {NULL}, 2283, "udp"}, {"lnvmaps", {NULL}, 2284, "tcp"}, {"lnvmaps", {NULL}, 2284, "udp"}, {"lnvmailmon", {NULL}, 2285, "tcp"}, {"lnvmailmon", {NULL}, 2285, "udp"}, {"nas-metering", {NULL}, 2286, "tcp"}, {"nas-metering", {NULL}, 2286, "udp"}, {"dna", {NULL}, 2287, "tcp"}, {"dna", {NULL}, 2287, "udp"}, {"netml", {NULL}, 2288, "tcp"}, {"netml", {NULL}, 2288, "udp"}, {"dict-lookup", {NULL}, 2289, "tcp"}, {"dict-lookup", {NULL}, 2289, "udp"}, {"sonus-logging", {NULL}, 2290, "tcp"}, {"sonus-logging", {NULL}, 2290, "udp"}, {"eapsp", {NULL}, 2291, "tcp"}, {"eapsp", {NULL}, 2291, "udp"}, {"mib-streaming", {NULL}, 2292, "tcp"}, {"mib-streaming", {NULL}, 2292, "udp"}, {"npdbgmngr", {NULL}, 2293, "tcp"}, {"npdbgmngr", {NULL}, 2293, "udp"}, {"konshus-lm", {NULL}, 2294, "tcp"}, {"konshus-lm", {NULL}, 2294, "udp"}, {"advant-lm", {NULL}, 2295, "tcp"}, {"advant-lm", {NULL}, 2295, "udp"}, {"theta-lm", {NULL}, 2296, "tcp"}, {"theta-lm", {NULL}, 2296, "udp"}, {"d2k-datamover1", {NULL}, 2297, "tcp"}, {"d2k-datamover1", {NULL}, 2297, "udp"}, {"d2k-datamover2", {NULL}, 2298, "tcp"}, {"d2k-datamover2", {NULL}, 2298, "udp"}, {"pc-telecommute", {NULL}, 2299, "tcp"}, {"pc-telecommute", {NULL}, 2299, "udp"}, {"cvmmon", {NULL}, 2300, "tcp"}, {"cvmmon", {NULL}, 2300, "udp"}, {"cpq-wbem", {NULL}, 2301, "tcp"}, {"cpq-wbem", {NULL}, 2301, "udp"}, {"binderysupport", {NULL}, 2302, "tcp"}, {"binderysupport", {NULL}, 2302, "udp"}, {"proxy-gateway", {NULL}, 2303, "tcp"}, {"proxy-gateway", {NULL}, 2303, "udp"}, {"attachmate-uts", {NULL}, 2304, "tcp"}, {"attachmate-uts", {NULL}, 2304, "udp"}, {"mt-scaleserver", {NULL}, 2305, "tcp"}, {"mt-scaleserver", {NULL}, 2305, "udp"}, {"tappi-boxnet", {NULL}, 2306, "tcp"}, {"tappi-boxnet", {NULL}, 2306, "udp"}, {"pehelp", {NULL}, 2307, "tcp"}, {"pehelp", {NULL}, 2307, "udp"}, {"sdhelp", {NULL}, 2308, "tcp"}, {"sdhelp", {NULL}, 2308, "udp"}, {"sdserver", {NULL}, 2309, "tcp"}, {"sdserver", {NULL}, 2309, "udp"}, {"sdclient", {NULL}, 2310, "tcp"}, {"sdclient", {NULL}, 2310, "udp"}, {"messageservice", {NULL}, 2311, "tcp"}, {"messageservice", {NULL}, 2311, "udp"}, {"wanscaler", {NULL}, 2312, "tcp"}, {"wanscaler", {NULL}, 2312, "udp"}, {"iapp", {NULL}, 2313, "tcp"}, {"iapp", {NULL}, 2313, "udp"}, {"cr-websystems", {NULL}, 2314, "tcp"}, {"cr-websystems", {NULL}, 2314, "udp"}, {"precise-sft", {NULL}, 2315, "tcp"}, {"precise-sft", {NULL}, 2315, "udp"}, {"sent-lm", {NULL}, 2316, "tcp"}, {"sent-lm", {NULL}, 2316, "udp"}, {"attachmate-g32", {NULL}, 2317, "tcp"}, {"attachmate-g32", {NULL}, 2317, "udp"}, {"cadencecontrol", {NULL}, 2318, "tcp"}, {"cadencecontrol", {NULL}, 2318, "udp"}, {"infolibria", {NULL}, 2319, "tcp"}, {"infolibria", {NULL}, 2319, "udp"}, {"siebel-ns", {NULL}, 2320, "tcp"}, {"siebel-ns", {NULL}, 2320, "udp"}, {"rdlap", {NULL}, 2321, "tcp"}, {"rdlap", {NULL}, 2321, "udp"}, {"ofsd", {NULL}, 2322, "tcp"}, {"ofsd", {NULL}, 2322, "udp"}, {"3d-nfsd", {NULL}, 2323, "tcp"}, {"3d-nfsd", {NULL}, 2323, "udp"}, {"cosmocall", {NULL}, 2324, "tcp"}, {"cosmocall", {NULL}, 2324, "udp"}, {"ansysli", {NULL}, 2325, "tcp"}, {"ansysli", {NULL}, 2325, "udp"}, {"idcp", {NULL}, 2326, "tcp"}, {"idcp", {NULL}, 2326, "udp"}, {"xingcsm", {NULL}, 2327, "tcp"}, {"xingcsm", {NULL}, 2327, "udp"}, {"netrix-sftm", {NULL}, 2328, "tcp"}, {"netrix-sftm", {NULL}, 2328, "udp"}, {"nvd", {NULL}, 2329, "tcp"}, {"nvd", {NULL}, 2329, "udp"}, {"tscchat", {NULL}, 2330, "tcp"}, {"tscchat", {NULL}, 2330, "udp"}, {"agentview", {NULL}, 2331, "tcp"}, {"agentview", {NULL}, 2331, "udp"}, {"rcc-host", {NULL}, 2332, "tcp"}, {"rcc-host", {NULL}, 2332, "udp"}, {"snapp", {NULL}, 2333, "tcp"}, {"snapp", {NULL}, 2333, "udp"}, {"ace-client", {NULL}, 2334, "tcp"}, {"ace-client", {NULL}, 2334, "udp"}, {"ace-proxy", {NULL}, 2335, "tcp"}, {"ace-proxy", {NULL}, 2335, "udp"}, {"appleugcontrol", {NULL}, 2336, "tcp"}, {"appleugcontrol", {NULL}, 2336, "udp"}, {"ideesrv", {NULL}, 2337, "tcp"}, {"ideesrv", {NULL}, 2337, "udp"}, {"norton-lambert", {NULL}, 2338, "tcp"}, {"norton-lambert", {NULL}, 2338, "udp"}, {"3com-webview", {NULL}, 2339, "tcp"}, {"3com-webview", {NULL}, 2339, "udp"}, {"wrs_registry", {NULL}, 2340, "tcp"}, {"wrs_registry", {NULL}, 2340, "udp"}, {"xiostatus", {NULL}, 2341, "tcp"}, {"xiostatus", {NULL}, 2341, "udp"}, {"manage-exec", {NULL}, 2342, "tcp"}, {"manage-exec", {NULL}, 2342, "udp"}, {"nati-logos", {NULL}, 2343, "tcp"}, {"nati-logos", {NULL}, 2343, "udp"}, {"fcmsys", {NULL}, 2344, "tcp"}, {"fcmsys", {NULL}, 2344, "udp"}, {"dbm", {NULL}, 2345, "tcp"}, {"dbm", {NULL}, 2345, "udp"}, {"redstorm_join", {NULL}, 2346, "tcp"}, {"redstorm_join", {NULL}, 2346, "udp"}, {"redstorm_find", {NULL}, 2347, "tcp"}, {"redstorm_find", {NULL}, 2347, "udp"}, {"redstorm_info", {NULL}, 2348, "tcp"}, {"redstorm_info", {NULL}, 2348, "udp"}, {"redstorm_diag", {NULL}, 2349, "tcp"}, {"redstorm_diag", {NULL}, 2349, "udp"}, {"psbserver", {NULL}, 2350, "tcp"}, {"psbserver", {NULL}, 2350, "udp"}, {"psrserver", {NULL}, 2351, "tcp"}, {"psrserver", {NULL}, 2351, "udp"}, {"pslserver", {NULL}, 2352, "tcp"}, {"pslserver", {NULL}, 2352, "udp"}, {"pspserver", {NULL}, 2353, "tcp"}, {"pspserver", {NULL}, 2353, "udp"}, {"psprserver", {NULL}, 2354, "tcp"}, {"psprserver", {NULL}, 2354, "udp"}, {"psdbserver", {NULL}, 2355, "tcp"}, {"psdbserver", {NULL}, 2355, "udp"}, {"gxtelmd", {NULL}, 2356, "tcp"}, {"gxtelmd", {NULL}, 2356, "udp"}, {"unihub-server", {NULL}, 2357, "tcp"}, {"unihub-server", {NULL}, 2357, "udp"}, {"futrix", {NULL}, 2358, "tcp"}, {"futrix", {NULL}, 2358, "udp"}, {"flukeserver", {NULL}, 2359, "tcp"}, {"flukeserver", {NULL}, 2359, "udp"}, {"nexstorindltd", {NULL}, 2360, "tcp"}, {"nexstorindltd", {NULL}, 2360, "udp"}, {"tl1", {NULL}, 2361, "tcp"}, {"tl1", {NULL}, 2361, "udp"}, {"digiman", {NULL}, 2362, "tcp"}, {"digiman", {NULL}, 2362, "udp"}, {"mediacntrlnfsd", {NULL}, 2363, "tcp"}, {"mediacntrlnfsd", {NULL}, 2363, "udp"}, {"oi-2000", {NULL}, 2364, "tcp"}, {"oi-2000", {NULL}, 2364, "udp"}, {"dbref", {NULL}, 2365, "tcp"}, {"dbref", {NULL}, 2365, "udp"}, {"qip-login", {NULL}, 2366, "tcp"}, {"qip-login", {NULL}, 2366, "udp"}, {"service-ctrl", {NULL}, 2367, "tcp"}, {"service-ctrl", {NULL}, 2367, "udp"}, {"opentable", {NULL}, 2368, "tcp"}, {"opentable", {NULL}, 2368, "udp"}, {"l3-hbmon", {NULL}, 2370, "tcp"}, {"l3-hbmon", {NULL}, 2370, "udp"}, {"worldwire", {NULL}, 2371, "tcp"}, {"worldwire", {NULL}, 2371, "udp"}, {"lanmessenger", {NULL}, 2372, "tcp"}, {"lanmessenger", {NULL}, 2372, "udp"}, {"remographlm", {NULL}, 2373, "tcp"}, {"hydra", {NULL}, 2374, "tcp"}, {"compaq-https", {NULL}, 2381, "tcp"}, {"compaq-https", {NULL}, 2381, "udp"}, {"ms-olap3", {NULL}, 2382, "tcp"}, {"ms-olap3", {NULL}, 2382, "udp"}, {"ms-olap4", {NULL}, 2383, "tcp"}, {"ms-olap4", {NULL}, 2383, "udp"}, {"sd-request", {NULL}, 2384, "tcp"}, {"sd-capacity", {NULL}, 2384, "udp"}, {"sd-data", {NULL}, 2385, "tcp"}, {"sd-data", {NULL}, 2385, "udp"}, {"virtualtape", {NULL}, 2386, "tcp"}, {"virtualtape", {NULL}, 2386, "udp"}, {"vsamredirector", {NULL}, 2387, "tcp"}, {"vsamredirector", {NULL}, 2387, "udp"}, {"mynahautostart", {NULL}, 2388, "tcp"}, {"mynahautostart", {NULL}, 2388, "udp"}, {"ovsessionmgr", {NULL}, 2389, "tcp"}, {"ovsessionmgr", {NULL}, 2389, "udp"}, {"rsmtp", {NULL}, 2390, "tcp"}, {"rsmtp", {NULL}, 2390, "udp"}, {"3com-net-mgmt", {NULL}, 2391, "tcp"}, {"3com-net-mgmt", {NULL}, 2391, "udp"}, {"tacticalauth", {NULL}, 2392, "tcp"}, {"tacticalauth", {NULL}, 2392, "udp"}, {"ms-olap1", {NULL}, 2393, "tcp"}, {"ms-olap1", {NULL}, 2393, "udp"}, {"ms-olap2", {NULL}, 2394, "tcp"}, {"ms-olap2", {NULL}, 2394, "udp"}, {"lan900_remote", {NULL}, 2395, "tcp"}, {"lan900_remote", {NULL}, 2395, "udp"}, {"wusage", {NULL}, 2396, "tcp"}, {"wusage", {NULL}, 2396, "udp"}, {"ncl", {NULL}, 2397, "tcp"}, {"ncl", {NULL}, 2397, "udp"}, {"orbiter", {NULL}, 2398, "tcp"}, {"orbiter", {NULL}, 2398, "udp"}, {"fmpro-fdal", {NULL}, 2399, "tcp"}, {"fmpro-fdal", {NULL}, 2399, "udp"}, {"opequus-server", {NULL}, 2400, "tcp"}, {"opequus-server", {NULL}, 2400, "udp"}, {"cvspserver", {NULL}, 2401, "tcp"}, {"cvspserver", {NULL}, 2401, "udp"}, {"taskmaster2000", {NULL}, 2402, "tcp"}, {"taskmaster2000", {NULL}, 2402, "udp"}, {"taskmaster2000", {NULL}, 2403, "tcp"}, {"taskmaster2000", {NULL}, 2403, "udp"}, {"iec-104", {NULL}, 2404, "tcp"}, {"iec-104", {NULL}, 2404, "udp"}, {"trc-netpoll", {NULL}, 2405, "tcp"}, {"trc-netpoll", {NULL}, 2405, "udp"}, {"jediserver", {NULL}, 2406, "tcp"}, {"jediserver", {NULL}, 2406, "udp"}, {"orion", {NULL}, 2407, "tcp"}, {"orion", {NULL}, 2407, "udp"}, {"optimanet", {NULL}, 2408, "tcp"}, {"optimanet", {NULL}, 2408, "udp"}, {"sns-protocol", {NULL}, 2409, "tcp"}, {"sns-protocol", {NULL}, 2409, "udp"}, {"vrts-registry", {NULL}, 2410, "tcp"}, {"vrts-registry", {NULL}, 2410, "udp"}, {"netwave-ap-mgmt", {NULL}, 2411, "tcp"}, {"netwave-ap-mgmt", {NULL}, 2411, "udp"}, {"cdn", {NULL}, 2412, "tcp"}, {"cdn", {NULL}, 2412, "udp"}, {"orion-rmi-reg", {NULL}, 2413, "tcp"}, {"orion-rmi-reg", {NULL}, 2413, "udp"}, {"beeyond", {NULL}, 2414, "tcp"}, {"beeyond", {NULL}, 2414, "udp"}, {"codima-rtp", {NULL}, 2415, "tcp"}, {"codima-rtp", {NULL}, 2415, "udp"}, {"rmtserver", {NULL}, 2416, "tcp"}, {"rmtserver", {NULL}, 2416, "udp"}, {"composit-server", {NULL}, 2417, "tcp"}, {"composit-server", {NULL}, 2417, "udp"}, {"cas", {NULL}, 2418, "tcp"}, {"cas", {NULL}, 2418, "udp"}, {"attachmate-s2s", {NULL}, 2419, "tcp"}, {"attachmate-s2s", {NULL}, 2419, "udp"}, {"dslremote-mgmt", {NULL}, 2420, "tcp"}, {"dslremote-mgmt", {NULL}, 2420, "udp"}, {"g-talk", {NULL}, 2421, "tcp"}, {"g-talk", {NULL}, 2421, "udp"}, {"crmsbits", {NULL}, 2422, "tcp"}, {"crmsbits", {NULL}, 2422, "udp"}, {"rnrp", {NULL}, 2423, "tcp"}, {"rnrp", {NULL}, 2423, "udp"}, {"kofax-svr", {NULL}, 2424, "tcp"}, {"kofax-svr", {NULL}, 2424, "udp"}, {"fjitsuappmgr", {NULL}, 2425, "tcp"}, {"fjitsuappmgr", {NULL}, 2425, "udp"}, {"mgcp-gateway", {NULL}, 2427, "tcp"}, {"mgcp-gateway", {NULL}, 2427, "udp"}, {"ott", {NULL}, 2428, "tcp"}, {"ott", {NULL}, 2428, "udp"}, {"ft-role", {NULL}, 2429, "tcp"}, {"ft-role", {NULL}, 2429, "udp"}, {"venus", {NULL}, 2430, "tcp"}, {"venus", {NULL}, 2430, "udp"}, {"venus-se", {NULL}, 2431, "tcp"}, {"venus-se", {NULL}, 2431, "udp"}, {"codasrv", {NULL}, 2432, "tcp"}, {"codasrv", {NULL}, 2432, "udp"}, {"codasrv-se", {NULL}, 2433, "tcp"}, {"codasrv-se", {NULL}, 2433, "udp"}, {"pxc-epmap", {NULL}, 2434, "tcp"}, {"pxc-epmap", {NULL}, 2434, "udp"}, {"optilogic", {NULL}, 2435, "tcp"}, {"optilogic", {NULL}, 2435, "udp"}, {"topx", {NULL}, 2436, "tcp"}, {"topx", {NULL}, 2436, "udp"}, {"unicontrol", {NULL}, 2437, "tcp"}, {"unicontrol", {NULL}, 2437, "udp"}, {"msp", {NULL}, 2438, "tcp"}, {"msp", {NULL}, 2438, "udp"}, {"sybasedbsynch", {NULL}, 2439, "tcp"}, {"sybasedbsynch", {NULL}, 2439, "udp"}, {"spearway", {NULL}, 2440, "tcp"}, {"spearway", {NULL}, 2440, "udp"}, {"pvsw-inet", {NULL}, 2441, "tcp"}, {"pvsw-inet", {NULL}, 2441, "udp"}, {"netangel", {NULL}, 2442, "tcp"}, {"netangel", {NULL}, 2442, "udp"}, {"powerclientcsf", {NULL}, 2443, "tcp"}, {"powerclientcsf", {NULL}, 2443, "udp"}, {"btpp2sectrans", {NULL}, 2444, "tcp"}, {"btpp2sectrans", {NULL}, 2444, "udp"}, {"dtn1", {NULL}, 2445, "tcp"}, {"dtn1", {NULL}, 2445, "udp"}, {"bues_service", {NULL}, 2446, "tcp"}, {"bues_service", {NULL}, 2446, "udp"}, {"ovwdb", {NULL}, 2447, "tcp"}, {"ovwdb", {NULL}, 2447, "udp"}, {"hpppssvr", {NULL}, 2448, "tcp"}, {"hpppssvr", {NULL}, 2448, "udp"}, {"ratl", {NULL}, 2449, "tcp"}, {"ratl", {NULL}, 2449, "udp"}, {"netadmin", {NULL}, 2450, "tcp"}, {"netadmin", {NULL}, 2450, "udp"}, {"netchat", {NULL}, 2451, "tcp"}, {"netchat", {NULL}, 2451, "udp"}, {"snifferclient", {NULL}, 2452, "tcp"}, {"snifferclient", {NULL}, 2452, "udp"}, {"madge-ltd", {NULL}, 2453, "tcp"}, {"madge-ltd", {NULL}, 2453, "udp"}, {"indx-dds", {NULL}, 2454, "tcp"}, {"indx-dds", {NULL}, 2454, "udp"}, {"wago-io-system", {NULL}, 2455, "tcp"}, {"wago-io-system", {NULL}, 2455, "udp"}, {"altav-remmgt", {NULL}, 2456, "tcp"}, {"altav-remmgt", {NULL}, 2456, "udp"}, {"rapido-ip", {NULL}, 2457, "tcp"}, {"rapido-ip", {NULL}, 2457, "udp"}, {"griffin", {NULL}, 2458, "tcp"}, {"griffin", {NULL}, 2458, "udp"}, {"community", {NULL}, 2459, "tcp"}, {"community", {NULL}, 2459, "udp"}, {"ms-theater", {NULL}, 2460, "tcp"}, {"ms-theater", {NULL}, 2460, "udp"}, {"qadmifoper", {NULL}, 2461, "tcp"}, {"qadmifoper", {NULL}, 2461, "udp"}, {"qadmifevent", {NULL}, 2462, "tcp"}, {"qadmifevent", {NULL}, 2462, "udp"}, {"lsi-raid-mgmt", {NULL}, 2463, "tcp"}, {"lsi-raid-mgmt", {NULL}, 2463, "udp"}, {"direcpc-si", {NULL}, 2464, "tcp"}, {"direcpc-si", {NULL}, 2464, "udp"}, {"lbm", {NULL}, 2465, "tcp"}, {"lbm", {NULL}, 2465, "udp"}, {"lbf", {NULL}, 2466, "tcp"}, {"lbf", {NULL}, 2466, "udp"}, {"high-criteria", {NULL}, 2467, "tcp"}, {"high-criteria", {NULL}, 2467, "udp"}, {"qip-msgd", {NULL}, 2468, "tcp"}, {"qip-msgd", {NULL}, 2468, "udp"}, {"mti-tcs-comm", {NULL}, 2469, "tcp"}, {"mti-tcs-comm", {NULL}, 2469, "udp"}, {"taskman-port", {NULL}, 2470, "tcp"}, {"taskman-port", {NULL}, 2470, "udp"}, {"seaodbc", {NULL}, 2471, "tcp"}, {"seaodbc", {NULL}, 2471, "udp"}, {"c3", {NULL}, 2472, "tcp"}, {"c3", {NULL}, 2472, "udp"}, {"aker-cdp", {NULL}, 2473, "tcp"}, {"aker-cdp", {NULL}, 2473, "udp"}, {"vitalanalysis", {NULL}, 2474, "tcp"}, {"vitalanalysis", {NULL}, 2474, "udp"}, {"ace-server", {NULL}, 2475, "tcp"}, {"ace-server", {NULL}, 2475, "udp"}, {"ace-svr-prop", {NULL}, 2476, "tcp"}, {"ace-svr-prop", {NULL}, 2476, "udp"}, {"ssm-cvs", {NULL}, 2477, "tcp"}, {"ssm-cvs", {NULL}, 2477, "udp"}, {"ssm-cssps", {NULL}, 2478, "tcp"}, {"ssm-cssps", {NULL}, 2478, "udp"}, {"ssm-els", {NULL}, 2479, "tcp"}, {"ssm-els", {NULL}, 2479, "udp"}, {"powerexchange", {NULL}, 2480, "tcp"}, {"powerexchange", {NULL}, 2480, "udp"}, {"giop", {NULL}, 2481, "tcp"}, {"giop", {NULL}, 2481, "udp"}, {"giop-ssl", {NULL}, 2482, "tcp"}, {"giop-ssl", {NULL}, 2482, "udp"}, {"ttc", {NULL}, 2483, "tcp"}, {"ttc", {NULL}, 2483, "udp"}, {"ttc-ssl", {NULL}, 2484, "tcp"}, {"ttc-ssl", {NULL}, 2484, "udp"}, {"netobjects1", {NULL}, 2485, "tcp"}, {"netobjects1", {NULL}, 2485, "udp"}, {"netobjects2", {NULL}, 2486, "tcp"}, {"netobjects2", {NULL}, 2486, "udp"}, {"pns", {NULL}, 2487, "tcp"}, {"pns", {NULL}, 2487, "udp"}, {"moy-corp", {NULL}, 2488, "tcp"}, {"moy-corp", {NULL}, 2488, "udp"}, {"tsilb", {NULL}, 2489, "tcp"}, {"tsilb", {NULL}, 2489, "udp"}, {"qip-qdhcp", {NULL}, 2490, "tcp"}, {"qip-qdhcp", {NULL}, 2490, "udp"}, {"conclave-cpp", {NULL}, 2491, "tcp"}, {"conclave-cpp", {NULL}, 2491, "udp"}, {"groove", {NULL}, 2492, "tcp"}, {"groove", {NULL}, 2492, "udp"}, {"talarian-mqs", {NULL}, 2493, "tcp"}, {"talarian-mqs", {NULL}, 2493, "udp"}, {"bmc-ar", {NULL}, 2494, "tcp"}, {"bmc-ar", {NULL}, 2494, "udp"}, {"fast-rem-serv", {NULL}, 2495, "tcp"}, {"fast-rem-serv", {NULL}, 2495, "udp"}, {"dirgis", {NULL}, 2496, "tcp"}, {"dirgis", {NULL}, 2496, "udp"}, {"quaddb", {NULL}, 2497, "tcp"}, {"quaddb", {NULL}, 2497, "udp"}, {"odn-castraq", {NULL}, 2498, "tcp"}, {"odn-castraq", {NULL}, 2498, "udp"}, {"unicontrol", {NULL}, 2499, "tcp"}, {"unicontrol", {NULL}, 2499, "udp"}, {"rtsserv", {NULL}, 2500, "tcp"}, {"rtsserv", {NULL}, 2500, "udp"}, {"rtsclient", {NULL}, 2501, "tcp"}, {"rtsclient", {NULL}, 2501, "udp"}, {"kentrox-prot", {NULL}, 2502, "tcp"}, {"kentrox-prot", {NULL}, 2502, "udp"}, {"nms-dpnss", {NULL}, 2503, "tcp"}, {"nms-dpnss", {NULL}, 2503, "udp"}, {"wlbs", {NULL}, 2504, "tcp"}, {"wlbs", {NULL}, 2504, "udp"}, {"ppcontrol", {NULL}, 2505, "tcp"}, {"ppcontrol", {NULL}, 2505, "udp"}, {"jbroker", {NULL}, 2506, "tcp"}, {"jbroker", {NULL}, 2506, "udp"}, {"spock", {NULL}, 2507, "tcp"}, {"spock", {NULL}, 2507, "udp"}, {"jdatastore", {NULL}, 2508, "tcp"}, {"jdatastore", {NULL}, 2508, "udp"}, {"fjmpss", {NULL}, 2509, "tcp"}, {"fjmpss", {NULL}, 2509, "udp"}, {"fjappmgrbulk", {NULL}, 2510, "tcp"}, {"fjappmgrbulk", {NULL}, 2510, "udp"}, {"metastorm", {NULL}, 2511, "tcp"}, {"metastorm", {NULL}, 2511, "udp"}, {"citrixima", {NULL}, 2512, "tcp"}, {"citrixima", {NULL}, 2512, "udp"}, {"citrixadmin", {NULL}, 2513, "tcp"}, {"citrixadmin", {NULL}, 2513, "udp"}, {"facsys-ntp", {NULL}, 2514, "tcp"}, {"facsys-ntp", {NULL}, 2514, "udp"}, {"facsys-router", {NULL}, 2515, "tcp"}, {"facsys-router", {NULL}, 2515, "udp"}, {"maincontrol", {NULL}, 2516, "tcp"}, {"maincontrol", {NULL}, 2516, "udp"}, {"call-sig-trans", {NULL}, 2517, "tcp"}, {"call-sig-trans", {NULL}, 2517, "udp"}, {"willy", {NULL}, 2518, "tcp"}, {"willy", {NULL}, 2518, "udp"}, {"globmsgsvc", {NULL}, 2519, "tcp"}, {"globmsgsvc", {NULL}, 2519, "udp"}, {"pvsw", {NULL}, 2520, "tcp"}, {"pvsw", {NULL}, 2520, "udp"}, {"adaptecmgr", {NULL}, 2521, "tcp"}, {"adaptecmgr", {NULL}, 2521, "udp"}, {"windb", {NULL}, 2522, "tcp"}, {"windb", {NULL}, 2522, "udp"}, {"qke-llc-v3", {NULL}, 2523, "tcp"}, {"qke-llc-v3", {NULL}, 2523, "udp"}, {"optiwave-lm", {NULL}, 2524, "tcp"}, {"optiwave-lm", {NULL}, 2524, "udp"}, {"ms-v-worlds", {NULL}, 2525, "tcp"}, {"ms-v-worlds", {NULL}, 2525, "udp"}, {"ema-sent-lm", {NULL}, 2526, "tcp"}, {"ema-sent-lm", {NULL}, 2526, "udp"}, {"iqserver", {NULL}, 2527, "tcp"}, {"iqserver", {NULL}, 2527, "udp"}, {"ncr_ccl", {NULL}, 2528, "tcp"}, {"ncr_ccl", {NULL}, 2528, "udp"}, {"utsftp", {NULL}, 2529, "tcp"}, {"utsftp", {NULL}, 2529, "udp"}, {"vrcommerce", {NULL}, 2530, "tcp"}, {"vrcommerce", {NULL}, 2530, "udp"}, {"ito-e-gui", {NULL}, 2531, "tcp"}, {"ito-e-gui", {NULL}, 2531, "udp"}, {"ovtopmd", {NULL}, 2532, "tcp"}, {"ovtopmd", {NULL}, 2532, "udp"}, {"snifferserver", {NULL}, 2533, "tcp"}, {"snifferserver", {NULL}, 2533, "udp"}, {"combox-web-acc", {NULL}, 2534, "tcp"}, {"combox-web-acc", {NULL}, 2534, "udp"}, {"madcap", {NULL}, 2535, "tcp"}, {"madcap", {NULL}, 2535, "udp"}, {"btpp2audctr1", {NULL}, 2536, "tcp"}, {"btpp2audctr1", {NULL}, 2536, "udp"}, {"upgrade", {NULL}, 2537, "tcp"}, {"upgrade", {NULL}, 2537, "udp"}, {"vnwk-prapi", {NULL}, 2538, "tcp"}, {"vnwk-prapi", {NULL}, 2538, "udp"}, {"vsiadmin", {NULL}, 2539, "tcp"}, {"vsiadmin", {NULL}, 2539, "udp"}, {"lonworks", {NULL}, 2540, "tcp"}, {"lonworks", {NULL}, 2540, "udp"}, {"lonworks2", {NULL}, 2541, "tcp"}, {"lonworks2", {NULL}, 2541, "udp"}, {"udrawgraph", {NULL}, 2542, "tcp"}, {"udrawgraph", {NULL}, 2542, "udp"}, {"reftek", {NULL}, 2543, "tcp"}, {"reftek", {NULL}, 2543, "udp"}, {"novell-zen", {NULL}, 2544, "tcp"}, {"novell-zen", {NULL}, 2544, "udp"}, {"sis-emt", {NULL}, 2545, "tcp"}, {"sis-emt", {NULL}, 2545, "udp"}, {"vytalvaultbrtp", {NULL}, 2546, "tcp"}, {"vytalvaultbrtp", {NULL}, 2546, "udp"}, {"vytalvaultvsmp", {NULL}, 2547, "tcp"}, {"vytalvaultvsmp", {NULL}, 2547, "udp"}, {"vytalvaultpipe", {NULL}, 2548, "tcp"}, {"vytalvaultpipe", {NULL}, 2548, "udp"}, {"ipass", {NULL}, 2549, "tcp"}, {"ipass", {NULL}, 2549, "udp"}, {"ads", {NULL}, 2550, "tcp"}, {"ads", {NULL}, 2550, "udp"}, {"isg-uda-server", {NULL}, 2551, "tcp"}, {"isg-uda-server", {NULL}, 2551, "udp"}, {"call-logging", {NULL}, 2552, "tcp"}, {"call-logging", {NULL}, 2552, "udp"}, {"efidiningport", {NULL}, 2553, "tcp"}, {"efidiningport", {NULL}, 2553, "udp"}, {"vcnet-link-v10", {NULL}, 2554, "tcp"}, {"vcnet-link-v10", {NULL}, 2554, "udp"}, {"compaq-wcp", {NULL}, 2555, "tcp"}, {"compaq-wcp", {NULL}, 2555, "udp"}, {"nicetec-nmsvc", {NULL}, 2556, "tcp"}, {"nicetec-nmsvc", {NULL}, 2556, "udp"}, {"nicetec-mgmt", {NULL}, 2557, "tcp"}, {"nicetec-mgmt", {NULL}, 2557, "udp"}, {"pclemultimedia", {NULL}, 2558, "tcp"}, {"pclemultimedia", {NULL}, 2558, "udp"}, {"lstp", {NULL}, 2559, "tcp"}, {"lstp", {NULL}, 2559, "udp"}, {"labrat", {NULL}, 2560, "tcp"}, {"labrat", {NULL}, 2560, "udp"}, {"mosaixcc", {NULL}, 2561, "tcp"}, {"mosaixcc", {NULL}, 2561, "udp"}, {"delibo", {NULL}, 2562, "tcp"}, {"delibo", {NULL}, 2562, "udp"}, {"cti-redwood", {NULL}, 2563, "tcp"}, {"cti-redwood", {NULL}, 2563, "udp"}, {"hp-3000-telnet", {NULL}, 2564, "tcp"}, {"coord-svr", {NULL}, 2565, "tcp"}, {"coord-svr", {NULL}, 2565, "udp"}, {"pcs-pcw", {NULL}, 2566, "tcp"}, {"pcs-pcw", {NULL}, 2566, "udp"}, {"clp", {NULL}, 2567, "tcp"}, {"clp", {NULL}, 2567, "udp"}, {"spamtrap", {NULL}, 2568, "tcp"}, {"spamtrap", {NULL}, 2568, "udp"}, {"sonuscallsig", {NULL}, 2569, "tcp"}, {"sonuscallsig", {NULL}, 2569, "udp"}, {"hs-port", {NULL}, 2570, "tcp"}, {"hs-port", {NULL}, 2570, "udp"}, {"cecsvc", {NULL}, 2571, "tcp"}, {"cecsvc", {NULL}, 2571, "udp"}, {"ibp", {NULL}, 2572, "tcp"}, {"ibp", {NULL}, 2572, "udp"}, {"trustestablish", {NULL}, 2573, "tcp"}, {"trustestablish", {NULL}, 2573, "udp"}, {"blockade-bpsp", {NULL}, 2574, "tcp"}, {"blockade-bpsp", {NULL}, 2574, "udp"}, {"hl7", {NULL}, 2575, "tcp"}, {"hl7", {NULL}, 2575, "udp"}, {"tclprodebugger", {NULL}, 2576, "tcp"}, {"tclprodebugger", {NULL}, 2576, "udp"}, {"scipticslsrvr", {NULL}, 2577, "tcp"}, {"scipticslsrvr", {NULL}, 2577, "udp"}, {"rvs-isdn-dcp", {NULL}, 2578, "tcp"}, {"rvs-isdn-dcp", {NULL}, 2578, "udp"}, {"mpfoncl", {NULL}, 2579, "tcp"}, {"mpfoncl", {NULL}, 2579, "udp"}, {"tributary", {NULL}, 2580, "tcp"}, {"tributary", {NULL}, 2580, "udp"}, {"argis-te", {NULL}, 2581, "tcp"}, {"argis-te", {NULL}, 2581, "udp"}, {"argis-ds", {NULL}, 2582, "tcp"}, {"argis-ds", {NULL}, 2582, "udp"}, {"mon", {NULL}, 2583, "tcp"}, {"mon", {NULL}, 2583, "udp"}, {"cyaserv", {NULL}, 2584, "tcp"}, {"cyaserv", {NULL}, 2584, "udp"}, {"netx-server", {NULL}, 2585, "tcp"}, {"netx-server", {NULL}, 2585, "udp"}, {"netx-agent", {NULL}, 2586, "tcp"}, {"netx-agent", {NULL}, 2586, "udp"}, {"masc", {NULL}, 2587, "tcp"}, {"masc", {NULL}, 2587, "udp"}, {"privilege", {NULL}, 2588, "tcp"}, {"privilege", {NULL}, 2588, "udp"}, {"quartus-tcl", {NULL}, 2589, "tcp"}, {"quartus-tcl", {NULL}, 2589, "udp"}, {"idotdist", {NULL}, 2590, "tcp"}, {"idotdist", {NULL}, 2590, "udp"}, {"maytagshuffle", {NULL}, 2591, "tcp"}, {"maytagshuffle", {NULL}, 2591, "udp"}, {"netrek", {NULL}, 2592, "tcp"}, {"netrek", {NULL}, 2592, "udp"}, {"mns-mail", {NULL}, 2593, "tcp"}, {"mns-mail", {NULL}, 2593, "udp"}, {"dts", {NULL}, 2594, "tcp"}, {"dts", {NULL}, 2594, "udp"}, {"worldfusion1", {NULL}, 2595, "tcp"}, {"worldfusion1", {NULL}, 2595, "udp"}, {"worldfusion2", {NULL}, 2596, "tcp"}, {"worldfusion2", {NULL}, 2596, "udp"}, {"homesteadglory", {NULL}, 2597, "tcp"}, {"homesteadglory", {NULL}, 2597, "udp"}, {"citriximaclient", {NULL}, 2598, "tcp"}, {"citriximaclient", {NULL}, 2598, "udp"}, {"snapd", {NULL}, 2599, "tcp"}, {"snapd", {NULL}, 2599, "udp"}, {"hpstgmgr", {NULL}, 2600, "tcp"}, {"hpstgmgr", {NULL}, 2600, "udp"}, {"discp-client", {NULL}, 2601, "tcp"}, {"discp-client", {NULL}, 2601, "udp"}, {"discp-server", {NULL}, 2602, "tcp"}, {"discp-server", {NULL}, 2602, "udp"}, {"servicemeter", {NULL}, 2603, "tcp"}, {"servicemeter", {NULL}, 2603, "udp"}, {"nsc-ccs", {NULL}, 2604, "tcp"}, {"nsc-ccs", {NULL}, 2604, "udp"}, {"nsc-posa", {NULL}, 2605, "tcp"}, {"nsc-posa", {NULL}, 2605, "udp"}, {"netmon", {NULL}, 2606, "tcp"}, {"netmon", {NULL}, 2606, "udp"}, {"connection", {NULL}, 2607, "tcp"}, {"connection", {NULL}, 2607, "udp"}, {"wag-service", {NULL}, 2608, "tcp"}, {"wag-service", {NULL}, 2608, "udp"}, {"system-monitor", {NULL}, 2609, "tcp"}, {"system-monitor", {NULL}, 2609, "udp"}, {"versa-tek", {NULL}, 2610, "tcp"}, {"versa-tek", {NULL}, 2610, "udp"}, {"lionhead", {NULL}, 2611, "tcp"}, {"lionhead", {NULL}, 2611, "udp"}, {"qpasa-agent", {NULL}, 2612, "tcp"}, {"qpasa-agent", {NULL}, 2612, "udp"}, {"smntubootstrap", {NULL}, 2613, "tcp"}, {"smntubootstrap", {NULL}, 2613, "udp"}, {"neveroffline", {NULL}, 2614, "tcp"}, {"neveroffline", {NULL}, 2614, "udp"}, {"firepower", {NULL}, 2615, "tcp"}, {"firepower", {NULL}, 2615, "udp"}, {"appswitch-emp", {NULL}, 2616, "tcp"}, {"appswitch-emp", {NULL}, 2616, "udp"}, {"cmadmin", {NULL}, 2617, "tcp"}, {"cmadmin", {NULL}, 2617, "udp"}, {"priority-e-com", {NULL}, 2618, "tcp"}, {"priority-e-com", {NULL}, 2618, "udp"}, {"bruce", {NULL}, 2619, "tcp"}, {"bruce", {NULL}, 2619, "udp"}, {"lpsrecommender", {NULL}, 2620, "tcp"}, {"lpsrecommender", {NULL}, 2620, "udp"}, {"miles-apart", {NULL}, 2621, "tcp"}, {"miles-apart", {NULL}, 2621, "udp"}, {"metricadbc", {NULL}, 2622, "tcp"}, {"metricadbc", {NULL}, 2622, "udp"}, {"lmdp", {NULL}, 2623, "tcp"}, {"lmdp", {NULL}, 2623, "udp"}, {"aria", {NULL}, 2624, "tcp"}, {"aria", {NULL}, 2624, "udp"}, {"blwnkl-port", {NULL}, 2625, "tcp"}, {"blwnkl-port", {NULL}, 2625, "udp"}, {"gbjd816", {NULL}, 2626, "tcp"}, {"gbjd816", {NULL}, 2626, "udp"}, {"moshebeeri", {NULL}, 2627, "tcp"}, {"moshebeeri", {NULL}, 2627, "udp"}, {"dict", {NULL}, 2628, "tcp"}, {"dict", {NULL}, 2628, "udp"}, {"sitaraserver", {NULL}, 2629, "tcp"}, {"sitaraserver", {NULL}, 2629, "udp"}, {"sitaramgmt", {NULL}, 2630, "tcp"}, {"sitaramgmt", {NULL}, 2630, "udp"}, {"sitaradir", {NULL}, 2631, "tcp"}, {"sitaradir", {NULL}, 2631, "udp"}, {"irdg-post", {NULL}, 2632, "tcp"}, {"irdg-post", {NULL}, 2632, "udp"}, {"interintelli", {NULL}, 2633, "tcp"}, {"interintelli", {NULL}, 2633, "udp"}, {"pk-electronics", {NULL}, 2634, "tcp"}, {"pk-electronics", {NULL}, 2634, "udp"}, {"backburner", {NULL}, 2635, "tcp"}, {"backburner", {NULL}, 2635, "udp"}, {"solve", {NULL}, 2636, "tcp"}, {"solve", {NULL}, 2636, "udp"}, {"imdocsvc", {NULL}, 2637, "tcp"}, {"imdocsvc", {NULL}, 2637, "udp"}, {"sybaseanywhere", {NULL}, 2638, "tcp"}, {"sybaseanywhere", {NULL}, 2638, "udp"}, {"aminet", {NULL}, 2639, "tcp"}, {"aminet", {NULL}, 2639, "udp"}, {"sai_sentlm", {NULL}, 2640, "tcp"}, {"sai_sentlm", {NULL}, 2640, "udp"}, {"hdl-srv", {NULL}, 2641, "tcp"}, {"hdl-srv", {NULL}, 2641, "udp"}, {"tragic", {NULL}, 2642, "tcp"}, {"tragic", {NULL}, 2642, "udp"}, {"gte-samp", {NULL}, 2643, "tcp"}, {"gte-samp", {NULL}, 2643, "udp"}, {"travsoft-ipx-t", {NULL}, 2644, "tcp"}, {"travsoft-ipx-t", {NULL}, 2644, "udp"}, {"novell-ipx-cmd", {NULL}, 2645, "tcp"}, {"novell-ipx-cmd", {NULL}, 2645, "udp"}, {"and-lm", {NULL}, 2646, "tcp"}, {"and-lm", {NULL}, 2646, "udp"}, {"syncserver", {NULL}, 2647, "tcp"}, {"syncserver", {NULL}, 2647, "udp"}, {"upsnotifyprot", {NULL}, 2648, "tcp"}, {"upsnotifyprot", {NULL}, 2648, "udp"}, {"vpsipport", {NULL}, 2649, "tcp"}, {"vpsipport", {NULL}, 2649, "udp"}, {"eristwoguns", {NULL}, 2650, "tcp"}, {"eristwoguns", {NULL}, 2650, "udp"}, {"ebinsite", {NULL}, 2651, "tcp"}, {"ebinsite", {NULL}, 2651, "udp"}, {"interpathpanel", {NULL}, 2652, "tcp"}, {"interpathpanel", {NULL}, 2652, "udp"}, {"sonus", {NULL}, 2653, "tcp"}, {"sonus", {NULL}, 2653, "udp"}, {"corel_vncadmin", {NULL}, 2654, "tcp"}, {"corel_vncadmin", {NULL}, 2654, "udp"}, {"unglue", {NULL}, 2655, "tcp"}, {"unglue", {NULL}, 2655, "udp"}, {"kana", {NULL}, 2656, "tcp"}, {"kana", {NULL}, 2656, "udp"}, {"sns-dispatcher", {NULL}, 2657, "tcp"}, {"sns-dispatcher", {NULL}, 2657, "udp"}, {"sns-admin", {NULL}, 2658, "tcp"}, {"sns-admin", {NULL}, 2658, "udp"}, {"sns-query", {NULL}, 2659, "tcp"}, {"sns-query", {NULL}, 2659, "udp"}, {"gcmonitor", {NULL}, 2660, "tcp"}, {"gcmonitor", {NULL}, 2660, "udp"}, {"olhost", {NULL}, 2661, "tcp"}, {"olhost", {NULL}, 2661, "udp"}, {"bintec-capi", {NULL}, 2662, "tcp"}, {"bintec-capi", {NULL}, 2662, "udp"}, {"bintec-tapi", {NULL}, 2663, "tcp"}, {"bintec-tapi", {NULL}, 2663, "udp"}, {"patrol-mq-gm", {NULL}, 2664, "tcp"}, {"patrol-mq-gm", {NULL}, 2664, "udp"}, {"patrol-mq-nm", {NULL}, 2665, "tcp"}, {"patrol-mq-nm", {NULL}, 2665, "udp"}, {"extensis", {NULL}, 2666, "tcp"}, {"extensis", {NULL}, 2666, "udp"}, {"alarm-clock-s", {NULL}, 2667, "tcp"}, {"alarm-clock-s", {NULL}, 2667, "udp"}, {"alarm-clock-c", {NULL}, 2668, "tcp"}, {"alarm-clock-c", {NULL}, 2668, "udp"}, {"toad", {NULL}, 2669, "tcp"}, {"toad", {NULL}, 2669, "udp"}, {"tve-announce", {NULL}, 2670, "tcp"}, {"tve-announce", {NULL}, 2670, "udp"}, {"newlixreg", {NULL}, 2671, "tcp"}, {"newlixreg", {NULL}, 2671, "udp"}, {"nhserver", {NULL}, 2672, "tcp"}, {"nhserver", {NULL}, 2672, "udp"}, {"firstcall42", {NULL}, 2673, "tcp"}, {"firstcall42", {NULL}, 2673, "udp"}, {"ewnn", {NULL}, 2674, "tcp"}, {"ewnn", {NULL}, 2674, "udp"}, {"ttc-etap", {NULL}, 2675, "tcp"}, {"ttc-etap", {NULL}, 2675, "udp"}, {"simslink", {NULL}, 2676, "tcp"}, {"simslink", {NULL}, 2676, "udp"}, {"gadgetgate1way", {NULL}, 2677, "tcp"}, {"gadgetgate1way", {NULL}, 2677, "udp"}, {"gadgetgate2way", {NULL}, 2678, "tcp"}, {"gadgetgate2way", {NULL}, 2678, "udp"}, {"syncserverssl", {NULL}, 2679, "tcp"}, {"syncserverssl", {NULL}, 2679, "udp"}, {"pxc-sapxom", {NULL}, 2680, "tcp"}, {"pxc-sapxom", {NULL}, 2680, "udp"}, {"mpnjsomb", {NULL}, 2681, "tcp"}, {"mpnjsomb", {NULL}, 2681, "udp"}, {"ncdloadbalance", {NULL}, 2683, "tcp"}, {"ncdloadbalance", {NULL}, 2683, "udp"}, {"mpnjsosv", {NULL}, 2684, "tcp"}, {"mpnjsosv", {NULL}, 2684, "udp"}, {"mpnjsocl", {NULL}, 2685, "tcp"}, {"mpnjsocl", {NULL}, 2685, "udp"}, {"mpnjsomg", {NULL}, 2686, "tcp"}, {"mpnjsomg", {NULL}, 2686, "udp"}, {"pq-lic-mgmt", {NULL}, 2687, "tcp"}, {"pq-lic-mgmt", {NULL}, 2687, "udp"}, {"md-cg-http", {NULL}, 2688, "tcp"}, {"md-cg-http", {NULL}, 2688, "udp"}, {"fastlynx", {NULL}, 2689, "tcp"}, {"fastlynx", {NULL}, 2689, "udp"}, {"hp-nnm-data", {NULL}, 2690, "tcp"}, {"hp-nnm-data", {NULL}, 2690, "udp"}, {"itinternet", {NULL}, 2691, "tcp"}, {"itinternet", {NULL}, 2691, "udp"}, {"admins-lms", {NULL}, 2692, "tcp"}, {"admins-lms", {NULL}, 2692, "udp"}, {"pwrsevent", {NULL}, 2694, "tcp"}, {"pwrsevent", {NULL}, 2694, "udp"}, {"vspread", {NULL}, 2695, "tcp"}, {"vspread", {NULL}, 2695, "udp"}, {"unifyadmin", {NULL}, 2696, "tcp"}, {"unifyadmin", {NULL}, 2696, "udp"}, {"oce-snmp-trap", {NULL}, 2697, "tcp"}, {"oce-snmp-trap", {NULL}, 2697, "udp"}, {"mck-ivpip", {NULL}, 2698, "tcp"}, {"mck-ivpip", {NULL}, 2698, "udp"}, {"csoft-plusclnt", {NULL}, 2699, "tcp"}, {"csoft-plusclnt", {NULL}, 2699, "udp"}, {"tqdata", {NULL}, 2700, "tcp"}, {"tqdata", {NULL}, 2700, "udp"}, {"sms-rcinfo", {NULL}, 2701, "tcp"}, {"sms-rcinfo", {NULL}, 2701, "udp"}, {"sms-xfer", {NULL}, 2702, "tcp"}, {"sms-xfer", {NULL}, 2702, "udp"}, {"sms-chat", {NULL}, 2703, "tcp"}, {"sms-chat", {NULL}, 2703, "udp"}, {"sms-remctrl", {NULL}, 2704, "tcp"}, {"sms-remctrl", {NULL}, 2704, "udp"}, {"sds-admin", {NULL}, 2705, "tcp"}, {"sds-admin", {NULL}, 2705, "udp"}, {"ncdmirroring", {NULL}, 2706, "tcp"}, {"ncdmirroring", {NULL}, 2706, "udp"}, {"emcsymapiport", {NULL}, 2707, "tcp"}, {"emcsymapiport", {NULL}, 2707, "udp"}, {"banyan-net", {NULL}, 2708, "tcp"}, {"banyan-net", {NULL}, 2708, "udp"}, {"supermon", {NULL}, 2709, "tcp"}, {"supermon", {NULL}, 2709, "udp"}, {"sso-service", {NULL}, 2710, "tcp"}, {"sso-service", {NULL}, 2710, "udp"}, {"sso-control", {NULL}, 2711, "tcp"}, {"sso-control", {NULL}, 2711, "udp"}, {"aocp", {NULL}, 2712, "tcp"}, {"aocp", {NULL}, 2712, "udp"}, {"raventbs", {NULL}, 2713, "tcp"}, {"raventbs", {NULL}, 2713, "udp"}, {"raventdm", {NULL}, 2714, "tcp"}, {"raventdm", {NULL}, 2714, "udp"}, {"hpstgmgr2", {NULL}, 2715, "tcp"}, {"hpstgmgr2", {NULL}, 2715, "udp"}, {"inova-ip-disco", {NULL}, 2716, "tcp"}, {"inova-ip-disco", {NULL}, 2716, "udp"}, {"pn-requester", {NULL}, 2717, "tcp"}, {"pn-requester", {NULL}, 2717, "udp"}, {"pn-requester2", {NULL}, 2718, "tcp"}, {"pn-requester2", {NULL}, 2718, "udp"}, {"scan-change", {NULL}, 2719, "tcp"}, {"scan-change", {NULL}, 2719, "udp"}, {"wkars", {NULL}, 2720, "tcp"}, {"wkars", {NULL}, 2720, "udp"}, {"smart-diagnose", {NULL}, 2721, "tcp"}, {"smart-diagnose", {NULL}, 2721, "udp"}, {"proactivesrvr", {NULL}, 2722, "tcp"}, {"proactivesrvr", {NULL}, 2722, "udp"}, {"watchdog-nt", {NULL}, 2723, "tcp"}, {"watchdog-nt", {NULL}, 2723, "udp"}, {"qotps", {NULL}, 2724, "tcp"}, {"qotps", {NULL}, 2724, "udp"}, {"msolap-ptp2", {NULL}, 2725, "tcp"}, {"msolap-ptp2", {NULL}, 2725, "udp"}, {"tams", {NULL}, 2726, "tcp"}, {"tams", {NULL}, 2726, "udp"}, {"mgcp-callagent", {NULL}, 2727, "tcp"}, {"mgcp-callagent", {NULL}, 2727, "udp"}, {"sqdr", {NULL}, 2728, "tcp"}, {"sqdr", {NULL}, 2728, "udp"}, {"tcim-control", {NULL}, 2729, "tcp"}, {"tcim-control", {NULL}, 2729, "udp"}, {"nec-raidplus", {NULL}, 2730, "tcp"}, {"nec-raidplus", {NULL}, 2730, "udp"}, {"fyre-messanger", {NULL}, 2731, "tcp"}, {"fyre-messanger", {NULL}, 2731, "udp"}, {"g5m", {NULL}, 2732, "tcp"}, {"g5m", {NULL}, 2732, "udp"}, {"signet-ctf", {NULL}, 2733, "tcp"}, {"signet-ctf", {NULL}, 2733, "udp"}, {"ccs-software", {NULL}, 2734, "tcp"}, {"ccs-software", {NULL}, 2734, "udp"}, {"netiq-mc", {NULL}, 2735, "tcp"}, {"netiq-mc", {NULL}, 2735, "udp"}, {"radwiz-nms-srv", {NULL}, 2736, "tcp"}, {"radwiz-nms-srv", {NULL}, 2736, "udp"}, {"srp-feedback", {NULL}, 2737, "tcp"}, {"srp-feedback", {NULL}, 2737, "udp"}, {"ndl-tcp-ois-gw", {NULL}, 2738, "tcp"}, {"ndl-tcp-ois-gw", {NULL}, 2738, "udp"}, {"tn-timing", {NULL}, 2739, "tcp"}, {"tn-timing", {NULL}, 2739, "udp"}, {"alarm", {NULL}, 2740, "tcp"}, {"alarm", {NULL}, 2740, "udp"}, {"tsb", {NULL}, 2741, "tcp"}, {"tsb", {NULL}, 2741, "udp"}, {"tsb2", {NULL}, 2742, "tcp"}, {"tsb2", {NULL}, 2742, "udp"}, {"murx", {NULL}, 2743, "tcp"}, {"murx", {NULL}, 2743, "udp"}, {"honyaku", {NULL}, 2744, "tcp"}, {"honyaku", {NULL}, 2744, "udp"}, {"urbisnet", {NULL}, 2745, "tcp"}, {"urbisnet", {NULL}, 2745, "udp"}, {"cpudpencap", {NULL}, 2746, "tcp"}, {"cpudpencap", {NULL}, 2746, "udp"}, {"fjippol-swrly", {NULL}, 2747, "tcp"}, {"fjippol-swrly", {NULL}, 2747, "udp"}, {"fjippol-polsvr", {NULL}, 2748, "tcp"}, {"fjippol-polsvr", {NULL}, 2748, "udp"}, {"fjippol-cnsl", {NULL}, 2749, "tcp"}, {"fjippol-cnsl", {NULL}, 2749, "udp"}, {"fjippol-port1", {NULL}, 2750, "tcp"}, {"fjippol-port1", {NULL}, 2750, "udp"}, {"fjippol-port2", {NULL}, 2751, "tcp"}, {"fjippol-port2", {NULL}, 2751, "udp"}, {"rsisysaccess", {NULL}, 2752, "tcp"}, {"rsisysaccess", {NULL}, 2752, "udp"}, {"de-spot", {NULL}, 2753, "tcp"}, {"de-spot", {NULL}, 2753, "udp"}, {"apollo-cc", {NULL}, 2754, "tcp"}, {"apollo-cc", {NULL}, 2754, "udp"}, {"expresspay", {NULL}, 2755, "tcp"}, {"expresspay", {NULL}, 2755, "udp"}, {"simplement-tie", {NULL}, 2756, "tcp"}, {"simplement-tie", {NULL}, 2756, "udp"}, {"cnrp", {NULL}, 2757, "tcp"}, {"cnrp", {NULL}, 2757, "udp"}, {"apollo-status", {NULL}, 2758, "tcp"}, {"apollo-status", {NULL}, 2758, "udp"}, {"apollo-gms", {NULL}, 2759, "tcp"}, {"apollo-gms", {NULL}, 2759, "udp"}, {"sabams", {NULL}, 2760, "tcp"}, {"sabams", {NULL}, 2760, "udp"}, {"dicom-iscl", {NULL}, 2761, "tcp"}, {"dicom-iscl", {NULL}, 2761, "udp"}, {"dicom-tls", {NULL}, 2762, "tcp"}, {"dicom-tls", {NULL}, 2762, "udp"}, {"desktop-dna", {NULL}, 2763, "tcp"}, {"desktop-dna", {NULL}, 2763, "udp"}, {"data-insurance", {NULL}, 2764, "tcp"}, {"data-insurance", {NULL}, 2764, "udp"}, {"qip-audup", {NULL}, 2765, "tcp"}, {"qip-audup", {NULL}, 2765, "udp"}, {"compaq-scp", {NULL}, 2766, "tcp"}, {"compaq-scp", {NULL}, 2766, "udp"}, {"uadtc", {NULL}, 2767, "tcp"}, {"uadtc", {NULL}, 2767, "udp"}, {"uacs", {NULL}, 2768, "tcp"}, {"uacs", {NULL}, 2768, "udp"}, {"exce", {NULL}, 2769, "tcp"}, {"exce", {NULL}, 2769, "udp"}, {"veronica", {NULL}, 2770, "tcp"}, {"veronica", {NULL}, 2770, "udp"}, {"vergencecm", {NULL}, 2771, "tcp"}, {"vergencecm", {NULL}, 2771, "udp"}, {"auris", {NULL}, 2772, "tcp"}, {"auris", {NULL}, 2772, "udp"}, {"rbakcup1", {NULL}, 2773, "tcp"}, {"rbakcup1", {NULL}, 2773, "udp"}, {"rbakcup2", {NULL}, 2774, "tcp"}, {"rbakcup2", {NULL}, 2774, "udp"}, {"smpp", {NULL}, 2775, "tcp"}, {"smpp", {NULL}, 2775, "udp"}, {"ridgeway1", {NULL}, 2776, "tcp"}, {"ridgeway1", {NULL}, 2776, "udp"}, {"ridgeway2", {NULL}, 2777, "tcp"}, {"ridgeway2", {NULL}, 2777, "udp"}, {"gwen-sonya", {NULL}, 2778, "tcp"}, {"gwen-sonya", {NULL}, 2778, "udp"}, {"lbc-sync", {NULL}, 2779, "tcp"}, {"lbc-sync", {NULL}, 2779, "udp"}, {"lbc-control", {NULL}, 2780, "tcp"}, {"lbc-control", {NULL}, 2780, "udp"}, {"whosells", {NULL}, 2781, "tcp"}, {"whosells", {NULL}, 2781, "udp"}, {"everydayrc", {NULL}, 2782, "tcp"}, {"everydayrc", {NULL}, 2782, "udp"}, {"aises", {NULL}, 2783, "tcp"}, {"aises", {NULL}, 2783, "udp"}, {"www-dev", {NULL}, 2784, "tcp"}, {"www-dev", {NULL}, 2784, "udp"}, {"aic-np", {NULL}, 2785, "tcp"}, {"aic-np", {NULL}, 2785, "udp"}, {"aic-oncrpc", {NULL}, 2786, "tcp"}, {"aic-oncrpc", {NULL}, 2786, "udp"}, {"piccolo", {NULL}, 2787, "tcp"}, {"piccolo", {NULL}, 2787, "udp"}, {"fryeserv", {NULL}, 2788, "tcp"}, {"fryeserv", {NULL}, 2788, "udp"}, {"media-agent", {NULL}, 2789, "tcp"}, {"media-agent", {NULL}, 2789, "udp"}, {"plgproxy", {NULL}, 2790, "tcp"}, {"plgproxy", {NULL}, 2790, "udp"}, {"mtport-regist", {NULL}, 2791, "tcp"}, {"mtport-regist", {NULL}, 2791, "udp"}, {"f5-globalsite", {NULL}, 2792, "tcp"}, {"f5-globalsite", {NULL}, 2792, "udp"}, {"initlsmsad", {NULL}, 2793, "tcp"}, {"initlsmsad", {NULL}, 2793, "udp"}, {"livestats", {NULL}, 2795, "tcp"}, {"livestats", {NULL}, 2795, "udp"}, {"ac-tech", {NULL}, 2796, "tcp"}, {"ac-tech", {NULL}, 2796, "udp"}, {"esp-encap", {NULL}, 2797, "tcp"}, {"esp-encap", {NULL}, 2797, "udp"}, {"tmesis-upshot", {NULL}, 2798, "tcp"}, {"tmesis-upshot", {NULL}, 2798, "udp"}, {"icon-discover", {NULL}, 2799, "tcp"}, {"icon-discover", {NULL}, 2799, "udp"}, {"acc-raid", {NULL}, 2800, "tcp"}, {"acc-raid", {NULL}, 2800, "udp"}, {"igcp", {NULL}, 2801, "tcp"}, {"igcp", {NULL}, 2801, "udp"}, {"veritas-tcp1", {NULL}, 2802, "tcp"}, {"veritas-udp1", {NULL}, 2802, "udp"}, {"btprjctrl", {NULL}, 2803, "tcp"}, {"btprjctrl", {NULL}, 2803, "udp"}, {"dvr-esm", {NULL}, 2804, "tcp"}, {"dvr-esm", {NULL}, 2804, "udp"}, {"wta-wsp-s", {NULL}, 2805, "tcp"}, {"wta-wsp-s", {NULL}, 2805, "udp"}, {"cspuni", {NULL}, 2806, "tcp"}, {"cspuni", {NULL}, 2806, "udp"}, {"cspmulti", {NULL}, 2807, "tcp"}, {"cspmulti", {NULL}, 2807, "udp"}, {"j-lan-p", {NULL}, 2808, "tcp"}, {"j-lan-p", {NULL}, 2808, "udp"}, {"corbaloc", {NULL}, 2809, "tcp"}, {"corbaloc", {NULL}, 2809, "udp"}, {"netsteward", {NULL}, 2810, "tcp"}, {"netsteward", {NULL}, 2810, "udp"}, {"gsiftp", {NULL}, 2811, "tcp"}, {"gsiftp", {NULL}, 2811, "udp"}, {"atmtcp", {NULL}, 2812, "tcp"}, {"atmtcp", {NULL}, 2812, "udp"}, {"llm-pass", {NULL}, 2813, "tcp"}, {"llm-pass", {NULL}, 2813, "udp"}, {"llm-csv", {NULL}, 2814, "tcp"}, {"llm-csv", {NULL}, 2814, "udp"}, {"lbc-measure", {NULL}, 2815, "tcp"}, {"lbc-measure", {NULL}, 2815, "udp"}, {"lbc-watchdog", {NULL}, 2816, "tcp"}, {"lbc-watchdog", {NULL}, 2816, "udp"}, {"nmsigport", {NULL}, 2817, "tcp"}, {"nmsigport", {NULL}, 2817, "udp"}, {"rmlnk", {NULL}, 2818, "tcp"}, {"rmlnk", {NULL}, 2818, "udp"}, {"fc-faultnotify", {NULL}, 2819, "tcp"}, {"fc-faultnotify", {NULL}, 2819, "udp"}, {"univision", {NULL}, 2820, "tcp"}, {"univision", {NULL}, 2820, "udp"}, {"vrts-at-port", {NULL}, 2821, "tcp"}, {"vrts-at-port", {NULL}, 2821, "udp"}, {"ka0wuc", {NULL}, 2822, "tcp"}, {"ka0wuc", {NULL}, 2822, "udp"}, {"cqg-netlan", {NULL}, 2823, "tcp"}, {"cqg-netlan", {NULL}, 2823, "udp"}, {"cqg-netlan-1", {NULL}, 2824, "tcp"}, {"cqg-netlan-1", {NULL}, 2824, "udp"}, {"slc-systemlog", {NULL}, 2826, "tcp"}, {"slc-systemlog", {NULL}, 2826, "udp"}, {"slc-ctrlrloops", {NULL}, 2827, "tcp"}, {"slc-ctrlrloops", {NULL}, 2827, "udp"}, {"itm-lm", {NULL}, 2828, "tcp"}, {"itm-lm", {NULL}, 2828, "udp"}, {"silkp1", {NULL}, 2829, "tcp"}, {"silkp1", {NULL}, 2829, "udp"}, {"silkp2", {NULL}, 2830, "tcp"}, {"silkp2", {NULL}, 2830, "udp"}, {"silkp3", {NULL}, 2831, "tcp"}, {"silkp3", {NULL}, 2831, "udp"}, {"silkp4", {NULL}, 2832, "tcp"}, {"silkp4", {NULL}, 2832, "udp"}, {"glishd", {NULL}, 2833, "tcp"}, {"glishd", {NULL}, 2833, "udp"}, {"evtp", {NULL}, 2834, "tcp"}, {"evtp", {NULL}, 2834, "udp"}, {"evtp-data", {NULL}, 2835, "tcp"}, {"evtp-data", {NULL}, 2835, "udp"}, {"catalyst", {NULL}, 2836, "tcp"}, {"catalyst", {NULL}, 2836, "udp"}, {"repliweb", {NULL}, 2837, "tcp"}, {"repliweb", {NULL}, 2837, "udp"}, {"starbot", {NULL}, 2838, "tcp"}, {"starbot", {NULL}, 2838, "udp"}, {"nmsigport", {NULL}, 2839, "tcp"}, {"nmsigport", {NULL}, 2839, "udp"}, {"l3-exprt", {NULL}, 2840, "tcp"}, {"l3-exprt", {NULL}, 2840, "udp"}, {"l3-ranger", {NULL}, 2841, "tcp"}, {"l3-ranger", {NULL}, 2841, "udp"}, {"l3-hawk", {NULL}, 2842, "tcp"}, {"l3-hawk", {NULL}, 2842, "udp"}, {"pdnet", {NULL}, 2843, "tcp"}, {"pdnet", {NULL}, 2843, "udp"}, {"bpcp-poll", {NULL}, 2844, "tcp"}, {"bpcp-poll", {NULL}, 2844, "udp"}, {"bpcp-trap", {NULL}, 2845, "tcp"}, {"bpcp-trap", {NULL}, 2845, "udp"}, {"aimpp-hello", {NULL}, 2846, "tcp"}, {"aimpp-hello", {NULL}, 2846, "udp"}, {"aimpp-port-req", {NULL}, 2847, "tcp"}, {"aimpp-port-req", {NULL}, 2847, "udp"}, {"amt-blc-port", {NULL}, 2848, "tcp"}, {"amt-blc-port", {NULL}, 2848, "udp"}, {"fxp", {NULL}, 2849, "tcp"}, {"fxp", {NULL}, 2849, "udp"}, {"metaconsole", {NULL}, 2850, "tcp"}, {"metaconsole", {NULL}, 2850, "udp"}, {"webemshttp", {NULL}, 2851, "tcp"}, {"webemshttp", {NULL}, 2851, "udp"}, {"bears-01", {NULL}, 2852, "tcp"}, {"bears-01", {NULL}, 2852, "udp"}, {"ispipes", {NULL}, 2853, "tcp"}, {"ispipes", {NULL}, 2853, "udp"}, {"infomover", {NULL}, 2854, "tcp"}, {"infomover", {NULL}, 2854, "udp"}, {"msrp", {NULL}, 2855, "tcp"}, {"msrp", {NULL}, 2855, "udp"}, {"cesdinv", {NULL}, 2856, "tcp"}, {"cesdinv", {NULL}, 2856, "udp"}, {"simctlp", {NULL}, 2857, "tcp"}, {"simctlp", {NULL}, 2857, "udp"}, {"ecnp", {NULL}, 2858, "tcp"}, {"ecnp", {NULL}, 2858, "udp"}, {"activememory", {NULL}, 2859, "tcp"}, {"activememory", {NULL}, 2859, "udp"}, {"dialpad-voice1", {NULL}, 2860, "tcp"}, {"dialpad-voice1", {NULL}, 2860, "udp"}, {"dialpad-voice2", {NULL}, 2861, "tcp"}, {"dialpad-voice2", {NULL}, 2861, "udp"}, {"ttg-protocol", {NULL}, 2862, "tcp"}, {"ttg-protocol", {NULL}, 2862, "udp"}, {"sonardata", {NULL}, 2863, "tcp"}, {"sonardata", {NULL}, 2863, "udp"}, {"astromed-main", {NULL}, 2864, "tcp"}, {"astromed-main", {NULL}, 2864, "udp"}, {"pit-vpn", {NULL}, 2865, "tcp"}, {"pit-vpn", {NULL}, 2865, "udp"}, {"iwlistener", {NULL}, 2866, "tcp"}, {"iwlistener", {NULL}, 2866, "udp"}, {"esps-portal", {NULL}, 2867, "tcp"}, {"esps-portal", {NULL}, 2867, "udp"}, {"npep-messaging", {NULL}, 2868, "tcp"}, {"npep-messaging", {NULL}, 2868, "udp"}, {"icslap", {NULL}, 2869, "tcp"}, {"icslap", {NULL}, 2869, "udp"}, {"daishi", {NULL}, 2870, "tcp"}, {"daishi", {NULL}, 2870, "udp"}, {"msi-selectplay", {NULL}, 2871, "tcp"}, {"msi-selectplay", {NULL}, 2871, "udp"}, {"radix", {NULL}, 2872, "tcp"}, {"radix", {NULL}, 2872, "udp"}, {"dxmessagebase1", {NULL}, 2874, "tcp"}, {"dxmessagebase1", {NULL}, 2874, "udp"}, {"dxmessagebase2", {NULL}, 2875, "tcp"}, {"dxmessagebase2", {NULL}, 2875, "udp"}, {"sps-tunnel", {NULL}, 2876, "tcp"}, {"sps-tunnel", {NULL}, 2876, "udp"}, {"bluelance", {NULL}, 2877, "tcp"}, {"bluelance", {NULL}, 2877, "udp"}, {"aap", {NULL}, 2878, "tcp"}, {"aap", {NULL}, 2878, "udp"}, {"ucentric-ds", {NULL}, 2879, "tcp"}, {"ucentric-ds", {NULL}, 2879, "udp"}, {"synapse", {NULL}, 2880, "tcp"}, {"synapse", {NULL}, 2880, "udp"}, {"ndsp", {NULL}, 2881, "tcp"}, {"ndsp", {NULL}, 2881, "udp"}, {"ndtp", {NULL}, 2882, "tcp"}, {"ndtp", {NULL}, 2882, "udp"}, {"ndnp", {NULL}, 2883, "tcp"}, {"ndnp", {NULL}, 2883, "udp"}, {"flashmsg", {NULL}, 2884, "tcp"}, {"flashmsg", {NULL}, 2884, "udp"}, {"topflow", {NULL}, 2885, "tcp"}, {"topflow", {NULL}, 2885, "udp"}, {"responselogic", {NULL}, 2886, "tcp"}, {"responselogic", {NULL}, 2886, "udp"}, {"aironetddp", {NULL}, 2887, "tcp"}, {"aironetddp", {NULL}, 2887, "udp"}, {"spcsdlobby", {NULL}, 2888, "tcp"}, {"spcsdlobby", {NULL}, 2888, "udp"}, {"rsom", {NULL}, 2889, "tcp"}, {"rsom", {NULL}, 2889, "udp"}, {"cspclmulti", {NULL}, 2890, "tcp"}, {"cspclmulti", {NULL}, 2890, "udp"}, {"cinegrfx-elmd", {NULL}, 2891, "tcp"}, {"cinegrfx-elmd", {NULL}, 2891, "udp"}, {"snifferdata", {NULL}, 2892, "tcp"}, {"snifferdata", {NULL}, 2892, "udp"}, {"vseconnector", {NULL}, 2893, "tcp"}, {"vseconnector", {NULL}, 2893, "udp"}, {"abacus-remote", {NULL}, 2894, "tcp"}, {"abacus-remote", {NULL}, 2894, "udp"}, {"natuslink", {NULL}, 2895, "tcp"}, {"natuslink", {NULL}, 2895, "udp"}, {"ecovisiong6-1", {NULL}, 2896, "tcp"}, {"ecovisiong6-1", {NULL}, 2896, "udp"}, {"citrix-rtmp", {NULL}, 2897, "tcp"}, {"citrix-rtmp", {NULL}, 2897, "udp"}, {"appliance-cfg", {NULL}, 2898, "tcp"}, {"appliance-cfg", {NULL}, 2898, "udp"}, {"powergemplus", {NULL}, 2899, "tcp"}, {"powergemplus", {NULL}, 2899, "udp"}, {"quicksuite", {NULL}, 2900, "tcp"}, {"quicksuite", {NULL}, 2900, "udp"}, {"allstorcns", {NULL}, 2901, "tcp"}, {"allstorcns", {NULL}, 2901, "udp"}, {"netaspi", {NULL}, 2902, "tcp"}, {"netaspi", {NULL}, 2902, "udp"}, {"suitcase", {NULL}, 2903, "tcp"}, {"suitcase", {NULL}, 2903, "udp"}, {"m2ua", {NULL}, 2904, "tcp"}, {"m2ua", {NULL}, 2904, "udp"}, {"m2ua", {NULL}, 2904, "sctp"}, {"m3ua", {NULL}, 2905, "tcp"}, {"m3ua", {NULL}, 2905, "sctp"}, {"caller9", {NULL}, 2906, "tcp"}, {"caller9", {NULL}, 2906, "udp"}, {"webmethods-b2b", {NULL}, 2907, "tcp"}, {"webmethods-b2b", {NULL}, 2907, "udp"}, {"mao", {NULL}, 2908, "tcp"}, {"mao", {NULL}, 2908, "udp"}, {"funk-dialout", {NULL}, 2909, "tcp"}, {"funk-dialout", {NULL}, 2909, "udp"}, {"tdaccess", {NULL}, 2910, "tcp"}, {"tdaccess", {NULL}, 2910, "udp"}, {"blockade", {NULL}, 2911, "tcp"}, {"blockade", {NULL}, 2911, "udp"}, {"epicon", {NULL}, 2912, "tcp"}, {"epicon", {NULL}, 2912, "udp"}, {"boosterware", {NULL}, 2913, "tcp"}, {"boosterware", {NULL}, 2913, "udp"}, {"gamelobby", {NULL}, 2914, "tcp"}, {"gamelobby", {NULL}, 2914, "udp"}, {"tksocket", {NULL}, 2915, "tcp"}, {"tksocket", {NULL}, 2915, "udp"}, {"elvin_server", {NULL}, 2916, "tcp"}, {"elvin_server", {NULL}, 2916, "udp"}, {"elvin_client", {NULL}, 2917, "tcp"}, {"elvin_client", {NULL}, 2917, "udp"}, {"kastenchasepad", {NULL}, 2918, "tcp"}, {"kastenchasepad", {NULL}, 2918, "udp"}, {"roboer", {NULL}, 2919, "tcp"}, {"roboer", {NULL}, 2919, "udp"}, {"roboeda", {NULL}, 2920, "tcp"}, {"roboeda", {NULL}, 2920, "udp"}, {"cesdcdman", {NULL}, 2921, "tcp"}, {"cesdcdman", {NULL}, 2921, "udp"}, {"cesdcdtrn", {NULL}, 2922, "tcp"}, {"cesdcdtrn", {NULL}, 2922, "udp"}, {"wta-wsp-wtp-s", {NULL}, 2923, "tcp"}, {"wta-wsp-wtp-s", {NULL}, 2923, "udp"}, {"precise-vip", {NULL}, 2924, "tcp"}, {"precise-vip", {NULL}, 2924, "udp"}, {"mobile-file-dl", {NULL}, 2926, "tcp"}, {"mobile-file-dl", {NULL}, 2926, "udp"}, {"unimobilectrl", {NULL}, 2927, "tcp"}, {"unimobilectrl", {NULL}, 2927, "udp"}, {"redstone-cpss", {NULL}, 2928, "tcp"}, {"redstone-cpss", {NULL}, 2928, "udp"}, {"amx-webadmin", {NULL}, 2929, "tcp"}, {"amx-webadmin", {NULL}, 2929, "udp"}, {"amx-weblinx", {NULL}, 2930, "tcp"}, {"amx-weblinx", {NULL}, 2930, "udp"}, {"circle-x", {NULL}, 2931, "tcp"}, {"circle-x", {NULL}, 2931, "udp"}, {"incp", {NULL}, 2932, "tcp"}, {"incp", {NULL}, 2932, "udp"}, {"4-tieropmgw", {NULL}, 2933, "tcp"}, {"4-tieropmgw", {NULL}, 2933, "udp"}, {"4-tieropmcli", {NULL}, 2934, "tcp"}, {"4-tieropmcli", {NULL}, 2934, "udp"}, {"qtp", {NULL}, 2935, "tcp"}, {"qtp", {NULL}, 2935, "udp"}, {"otpatch", {NULL}, 2936, "tcp"}, {"otpatch", {NULL}, 2936, "udp"}, {"pnaconsult-lm", {NULL}, 2937, "tcp"}, {"pnaconsult-lm", {NULL}, 2937, "udp"}, {"sm-pas-1", {NULL}, 2938, "tcp"}, {"sm-pas-1", {NULL}, 2938, "udp"}, {"sm-pas-2", {NULL}, 2939, "tcp"}, {"sm-pas-2", {NULL}, 2939, "udp"}, {"sm-pas-3", {NULL}, 2940, "tcp"}, {"sm-pas-3", {NULL}, 2940, "udp"}, {"sm-pas-4", {NULL}, 2941, "tcp"}, {"sm-pas-4", {NULL}, 2941, "udp"}, {"sm-pas-5", {NULL}, 2942, "tcp"}, {"sm-pas-5", {NULL}, 2942, "udp"}, {"ttnrepository", {NULL}, 2943, "tcp"}, {"ttnrepository", {NULL}, 2943, "udp"}, {"megaco-h248", {NULL}, 2944, "tcp"}, {"megaco-h248", {NULL}, 2944, "udp"}, {"megaco-h248", {NULL}, 2944, "sctp"}, {"h248-binary", {NULL}, 2945, "tcp"}, {"h248-binary", {NULL}, 2945, "udp"}, {"h248-binary", {NULL}, 2945, "sctp"}, {"fjsvmpor", {NULL}, 2946, "tcp"}, {"fjsvmpor", {NULL}, 2946, "udp"}, {"gpsd", {NULL}, 2947, "tcp"}, {"gpsd", {NULL}, 2947, "udp"}, {"wap-push", {NULL}, 2948, "tcp"}, {"wap-push", {NULL}, 2948, "udp"}, {"wap-pushsecure", {NULL}, 2949, "tcp"}, {"wap-pushsecure", {NULL}, 2949, "udp"}, {"esip", {NULL}, 2950, "tcp"}, {"esip", {NULL}, 2950, "udp"}, {"ottp", {NULL}, 2951, "tcp"}, {"ottp", {NULL}, 2951, "udp"}, {"mpfwsas", {NULL}, 2952, "tcp"}, {"mpfwsas", {NULL}, 2952, "udp"}, {"ovalarmsrv", {NULL}, 2953, "tcp"}, {"ovalarmsrv", {NULL}, 2953, "udp"}, {"ovalarmsrv-cmd", {NULL}, 2954, "tcp"}, {"ovalarmsrv-cmd", {NULL}, 2954, "udp"}, {"csnotify", {NULL}, 2955, "tcp"}, {"csnotify", {NULL}, 2955, "udp"}, {"ovrimosdbman", {NULL}, 2956, "tcp"}, {"ovrimosdbman", {NULL}, 2956, "udp"}, {"jmact5", {NULL}, 2957, "tcp"}, {"jmact5", {NULL}, 2957, "udp"}, {"jmact6", {NULL}, 2958, "tcp"}, {"jmact6", {NULL}, 2958, "udp"}, {"rmopagt", {NULL}, 2959, "tcp"}, {"rmopagt", {NULL}, 2959, "udp"}, {"dfoxserver", {NULL}, 2960, "tcp"}, {"dfoxserver", {NULL}, 2960, "udp"}, {"boldsoft-lm", {NULL}, 2961, "tcp"}, {"boldsoft-lm", {NULL}, 2961, "udp"}, {"iph-policy-cli", {NULL}, 2962, "tcp"}, {"iph-policy-cli", {NULL}, 2962, "udp"}, {"iph-policy-adm", {NULL}, 2963, "tcp"}, {"iph-policy-adm", {NULL}, 2963, "udp"}, {"bullant-srap", {NULL}, 2964, "tcp"}, {"bullant-srap", {NULL}, 2964, "udp"}, {"bullant-rap", {NULL}, 2965, "tcp"}, {"bullant-rap", {NULL}, 2965, "udp"}, {"idp-infotrieve", {NULL}, 2966, "tcp"}, {"idp-infotrieve", {NULL}, 2966, "udp"}, {"ssc-agent", {NULL}, 2967, "tcp"}, {"ssc-agent", {NULL}, 2967, "udp"}, {"enpp", {NULL}, 2968, "tcp"}, {"enpp", {NULL}, 2968, "udp"}, {"essp", {NULL}, 2969, "tcp"}, {"essp", {NULL}, 2969, "udp"}, {"index-net", {NULL}, 2970, "tcp"}, {"index-net", {NULL}, 2970, "udp"}, {"netclip", {NULL}, 2971, "tcp"}, {"netclip", {NULL}, 2971, "udp"}, {"pmsm-webrctl", {NULL}, 2972, "tcp"}, {"pmsm-webrctl", {NULL}, 2972, "udp"}, {"svnetworks", {NULL}, 2973, "tcp"}, {"svnetworks", {NULL}, 2973, "udp"}, {"signal", {NULL}, 2974, "tcp"}, {"signal", {NULL}, 2974, "udp"}, {"fjmpcm", {NULL}, 2975, "tcp"}, {"fjmpcm", {NULL}, 2975, "udp"}, {"cns-srv-port", {NULL}, 2976, "tcp"}, {"cns-srv-port", {NULL}, 2976, "udp"}, {"ttc-etap-ns", {NULL}, 2977, "tcp"}, {"ttc-etap-ns", {NULL}, 2977, "udp"}, {"ttc-etap-ds", {NULL}, 2978, "tcp"}, {"ttc-etap-ds", {NULL}, 2978, "udp"}, {"h263-video", {NULL}, 2979, "tcp"}, {"h263-video", {NULL}, 2979, "udp"}, {"wimd", {NULL}, 2980, "tcp"}, {"wimd", {NULL}, 2980, "udp"}, {"mylxamport", {NULL}, 2981, "tcp"}, {"mylxamport", {NULL}, 2981, "udp"}, {"iwb-whiteboard", {NULL}, 2982, "tcp"}, {"iwb-whiteboard", {NULL}, 2982, "udp"}, {"netplan", {NULL}, 2983, "tcp"}, {"netplan", {NULL}, 2983, "udp"}, {"hpidsadmin", {NULL}, 2984, "tcp"}, {"hpidsadmin", {NULL}, 2984, "udp"}, {"hpidsagent", {NULL}, 2985, "tcp"}, {"hpidsagent", {NULL}, 2985, "udp"}, {"stonefalls", {NULL}, 2986, "tcp"}, {"stonefalls", {NULL}, 2986, "udp"}, {"identify", {NULL}, 2987, "tcp"}, {"identify", {NULL}, 2987, "udp"}, {"hippad", {NULL}, 2988, "tcp"}, {"hippad", {NULL}, 2988, "udp"}, {"zarkov", {NULL}, 2989, "tcp"}, {"zarkov", {NULL}, 2989, "udp"}, {"boscap", {NULL}, 2990, "tcp"}, {"boscap", {NULL}, 2990, "udp"}, {"wkstn-mon", {NULL}, 2991, "tcp"}, {"wkstn-mon", {NULL}, 2991, "udp"}, {"avenyo", {NULL}, 2992, "tcp"}, {"avenyo", {NULL}, 2992, "udp"}, {"veritas-vis1", {NULL}, 2993, "tcp"}, {"veritas-vis1", {NULL}, 2993, "udp"}, {"veritas-vis2", {NULL}, 2994, "tcp"}, {"veritas-vis2", {NULL}, 2994, "udp"}, {"idrs", {NULL}, 2995, "tcp"}, {"idrs", {NULL}, 2995, "udp"}, {"vsixml", {NULL}, 2996, "tcp"}, {"vsixml", {NULL}, 2996, "udp"}, {"rebol", {NULL}, 2997, "tcp"}, {"rebol", {NULL}, 2997, "udp"}, {"realsecure", {NULL}, 2998, "tcp"}, {"realsecure", {NULL}, 2998, "udp"}, {"remoteware-un", {NULL}, 2999, "tcp"}, {"remoteware-un", {NULL}, 2999, "udp"}, {"hbci", {NULL}, 3000, "tcp"}, {"hbci", {NULL}, 3000, "udp"}, {"remoteware-cl", {NULL}, 3000, "tcp"}, {"remoteware-cl", {NULL}, 3000, "udp"}, {"exlm-agent", {NULL}, 3002, "tcp"}, {"exlm-agent", {NULL}, 3002, "udp"}, {"remoteware-srv", {NULL}, 3002, "tcp"}, {"remoteware-srv", {NULL}, 3002, "udp"}, {"cgms", {NULL}, 3003, "tcp"}, {"cgms", {NULL}, 3003, "udp"}, {"csoftragent", {NULL}, 3004, "tcp"}, {"csoftragent", {NULL}, 3004, "udp"}, {"geniuslm", {NULL}, 3005, "tcp"}, {"geniuslm", {NULL}, 3005, "udp"}, {"ii-admin", {NULL}, 3006, "tcp"}, {"ii-admin", {NULL}, 3006, "udp"}, {"lotusmtap", {NULL}, 3007, "tcp"}, {"lotusmtap", {NULL}, 3007, "udp"}, {"midnight-tech", {NULL}, 3008, "tcp"}, {"midnight-tech", {NULL}, 3008, "udp"}, {"pxc-ntfy", {NULL}, 3009, "tcp"}, {"pxc-ntfy", {NULL}, 3009, "udp"}, {"gw", {NULL}, 3010, "tcp"}, {"ping-pong", {NULL}, 3010, "udp"}, {"trusted-web", {NULL}, 3011, "tcp"}, {"trusted-web", {NULL}, 3011, "udp"}, {"twsdss", {NULL}, 3012, "tcp"}, {"twsdss", {NULL}, 3012, "udp"}, {"gilatskysurfer", {NULL}, 3013, "tcp"}, {"gilatskysurfer", {NULL}, 3013, "udp"}, {"broker_service", {NULL}, 3014, "tcp"}, {"broker_service", {NULL}, 3014, "udp"}, {"nati-dstp", {NULL}, 3015, "tcp"}, {"nati-dstp", {NULL}, 3015, "udp"}, {"notify_srvr", {NULL}, 3016, "tcp"}, {"notify_srvr", {NULL}, 3016, "udp"}, {"event_listener", {NULL}, 3017, "tcp"}, {"event_listener", {NULL}, 3017, "udp"}, {"srvc_registry", {NULL}, 3018, "tcp"}, {"srvc_registry", {NULL}, 3018, "udp"}, {"resource_mgr", {NULL}, 3019, "tcp"}, {"resource_mgr", {NULL}, 3019, "udp"}, {"cifs", {NULL}, 3020, "tcp"}, {"cifs", {NULL}, 3020, "udp"}, {"agriserver", {NULL}, 3021, "tcp"}, {"agriserver", {NULL}, 3021, "udp"}, {"csregagent", {NULL}, 3022, "tcp"}, {"csregagent", {NULL}, 3022, "udp"}, {"magicnotes", {NULL}, 3023, "tcp"}, {"magicnotes", {NULL}, 3023, "udp"}, {"nds_sso", {NULL}, 3024, "tcp"}, {"nds_sso", {NULL}, 3024, "udp"}, {"arepa-raft", {NULL}, 3025, "tcp"}, {"arepa-raft", {NULL}, 3025, "udp"}, {"agri-gateway", {NULL}, 3026, "tcp"}, {"agri-gateway", {NULL}, 3026, "udp"}, {"LiebDevMgmt_C", {NULL}, 3027, "tcp"}, {"LiebDevMgmt_C", {NULL}, 3027, "udp"}, {"LiebDevMgmt_DM", {NULL}, 3028, "tcp"}, {"LiebDevMgmt_DM", {NULL}, 3028, "udp"}, {"LiebDevMgmt_A", {NULL}, 3029, "tcp"}, {"LiebDevMgmt_A", {NULL}, 3029, "udp"}, {"arepa-cas", {NULL}, 3030, "tcp"}, {"arepa-cas", {NULL}, 3030, "udp"}, {"eppc", {NULL}, 3031, "tcp"}, {"eppc", {NULL}, 3031, "udp"}, {"redwood-chat", {NULL}, 3032, "tcp"}, {"redwood-chat", {NULL}, 3032, "udp"}, {"pdb", {NULL}, 3033, "tcp"}, {"pdb", {NULL}, 3033, "udp"}, {"osmosis-aeea", {NULL}, 3034, "tcp"}, {"osmosis-aeea", {NULL}, 3034, "udp"}, {"fjsv-gssagt", {NULL}, 3035, "tcp"}, {"fjsv-gssagt", {NULL}, 3035, "udp"}, {"hagel-dump", {NULL}, 3036, "tcp"}, {"hagel-dump", {NULL}, 3036, "udp"}, {"hp-san-mgmt", {NULL}, 3037, "tcp"}, {"hp-san-mgmt", {NULL}, 3037, "udp"}, {"santak-ups", {NULL}, 3038, "tcp"}, {"santak-ups", {NULL}, 3038, "udp"}, {"cogitate", {NULL}, 3039, "tcp"}, {"cogitate", {NULL}, 3039, "udp"}, {"tomato-springs", {NULL}, 3040, "tcp"}, {"tomato-springs", {NULL}, 3040, "udp"}, {"di-traceware", {NULL}, 3041, "tcp"}, {"di-traceware", {NULL}, 3041, "udp"}, {"journee", {NULL}, 3042, "tcp"}, {"journee", {NULL}, 3042, "udp"}, {"brp", {NULL}, 3043, "tcp"}, {"brp", {NULL}, 3043, "udp"}, {"epp", {NULL}, 3044, "tcp"}, {"epp", {NULL}, 3044, "udp"}, {"responsenet", {NULL}, 3045, "tcp"}, {"responsenet", {NULL}, 3045, "udp"}, {"di-ase", {NULL}, 3046, "tcp"}, {"di-ase", {NULL}, 3046, "udp"}, {"hlserver", {NULL}, 3047, "tcp"}, {"hlserver", {NULL}, 3047, "udp"}, {"pctrader", {NULL}, 3048, "tcp"}, {"pctrader", {NULL}, 3048, "udp"}, {"nsws", {NULL}, 3049, "tcp"}, {"nsws", {NULL}, 3049, "udp"}, {"gds_db", {NULL}, 3050, "tcp"}, {"gds_db", {NULL}, 3050, "udp"}, {"galaxy-server", {NULL}, 3051, "tcp"}, {"galaxy-server", {NULL}, 3051, "udp"}, {"apc-3052", {NULL}, 3052, "tcp"}, {"apc-3052", {NULL}, 3052, "udp"}, {"dsom-server", {NULL}, 3053, "tcp"}, {"dsom-server", {NULL}, 3053, "udp"}, {"amt-cnf-prot", {NULL}, 3054, "tcp"}, {"amt-cnf-prot", {NULL}, 3054, "udp"}, {"policyserver", {NULL}, 3055, "tcp"}, {"policyserver", {NULL}, 3055, "udp"}, {"cdl-server", {NULL}, 3056, "tcp"}, {"cdl-server", {NULL}, 3056, "udp"}, {"goahead-fldup", {NULL}, 3057, "tcp"}, {"goahead-fldup", {NULL}, 3057, "udp"}, {"videobeans", {NULL}, 3058, "tcp"}, {"videobeans", {NULL}, 3058, "udp"}, {"qsoft", {NULL}, 3059, "tcp"}, {"qsoft", {NULL}, 3059, "udp"}, {"interserver", {NULL}, 3060, "tcp"}, {"interserver", {NULL}, 3060, "udp"}, {"cautcpd", {NULL}, 3061, "tcp"}, {"cautcpd", {NULL}, 3061, "udp"}, {"ncacn-ip-tcp", {NULL}, 3062, "tcp"}, {"ncacn-ip-tcp", {NULL}, 3062, "udp"}, {"ncadg-ip-udp", {NULL}, 3063, "tcp"}, {"ncadg-ip-udp", {NULL}, 3063, "udp"}, {"rprt", {NULL}, 3064, "tcp"}, {"rprt", {NULL}, 3064, "udp"}, {"slinterbase", {NULL}, 3065, "tcp"}, {"slinterbase", {NULL}, 3065, "udp"}, {"netattachsdmp", {NULL}, 3066, "tcp"}, {"netattachsdmp", {NULL}, 3066, "udp"}, {"fjhpjp", {NULL}, 3067, "tcp"}, {"fjhpjp", {NULL}, 3067, "udp"}, {"ls3bcast", {NULL}, 3068, "tcp"}, {"ls3bcast", {NULL}, 3068, "udp"}, {"ls3", {NULL}, 3069, "tcp"}, {"ls3", {NULL}, 3069, "udp"}, {"mgxswitch", {NULL}, 3070, "tcp"}, {"mgxswitch", {NULL}, 3070, "udp"}, {"csd-mgmt-port", {NULL}, 3071, "tcp"}, {"csd-mgmt-port", {NULL}, 3071, "udp"}, {"csd-monitor", {NULL}, 3072, "tcp"}, {"csd-monitor", {NULL}, 3072, "udp"}, {"vcrp", {NULL}, 3073, "tcp"}, {"vcrp", {NULL}, 3073, "udp"}, {"xbox", {NULL}, 3074, "tcp"}, {"xbox", {NULL}, 3074, "udp"}, {"orbix-locator", {NULL}, 3075, "tcp"}, {"orbix-locator", {NULL}, 3075, "udp"}, {"orbix-config", {NULL}, 3076, "tcp"}, {"orbix-config", {NULL}, 3076, "udp"}, {"orbix-loc-ssl", {NULL}, 3077, "tcp"}, {"orbix-loc-ssl", {NULL}, 3077, "udp"}, {"orbix-cfg-ssl", {NULL}, 3078, "tcp"}, {"orbix-cfg-ssl", {NULL}, 3078, "udp"}, {"lv-frontpanel", {NULL}, 3079, "tcp"}, {"lv-frontpanel", {NULL}, 3079, "udp"}, {"stm_pproc", {NULL}, 3080, "tcp"}, {"stm_pproc", {NULL}, 3080, "udp"}, {"tl1-lv", {NULL}, 3081, "tcp"}, {"tl1-lv", {NULL}, 3081, "udp"}, {"tl1-raw", {NULL}, 3082, "tcp"}, {"tl1-raw", {NULL}, 3082, "udp"}, {"tl1-telnet", {NULL}, 3083, "tcp"}, {"tl1-telnet", {NULL}, 3083, "udp"}, {"itm-mccs", {NULL}, 3084, "tcp"}, {"itm-mccs", {NULL}, 3084, "udp"}, {"pcihreq", {NULL}, 3085, "tcp"}, {"pcihreq", {NULL}, 3085, "udp"}, {"jdl-dbkitchen", {NULL}, 3086, "tcp"}, {"jdl-dbkitchen", {NULL}, 3086, "udp"}, {"asoki-sma", {NULL}, 3087, "tcp"}, {"asoki-sma", {NULL}, 3087, "udp"}, {"xdtp", {NULL}, 3088, "tcp"}, {"xdtp", {NULL}, 3088, "udp"}, {"ptk-alink", {NULL}, 3089, "tcp"}, {"ptk-alink", {NULL}, 3089, "udp"}, {"stss", {NULL}, 3090, "tcp"}, {"stss", {NULL}, 3090, "udp"}, {"1ci-smcs", {NULL}, 3091, "tcp"}, {"1ci-smcs", {NULL}, 3091, "udp"}, {"rapidmq-center", {NULL}, 3093, "tcp"}, {"rapidmq-center", {NULL}, 3093, "udp"}, {"rapidmq-reg", {NULL}, 3094, "tcp"}, {"rapidmq-reg", {NULL}, 3094, "udp"}, {"panasas", {NULL}, 3095, "tcp"}, {"panasas", {NULL}, 3095, "udp"}, {"ndl-aps", {NULL}, 3096, "tcp"}, {"ndl-aps", {NULL}, 3096, "udp"}, {"itu-bicc-stc", {NULL}, 3097, "sctp"}, {"umm-port", {NULL}, 3098, "tcp"}, {"umm-port", {NULL}, 3098, "udp"}, {"chmd", {NULL}, 3099, "tcp"}, {"chmd", {NULL}, 3099, "udp"}, {"opcon-xps", {NULL}, 3100, "tcp"}, {"opcon-xps", {NULL}, 3100, "udp"}, {"hp-pxpib", {NULL}, 3101, "tcp"}, {"hp-pxpib", {NULL}, 3101, "udp"}, {"slslavemon", {NULL}, 3102, "tcp"}, {"slslavemon", {NULL}, 3102, "udp"}, {"autocuesmi", {NULL}, 3103, "tcp"}, {"autocuesmi", {NULL}, 3103, "udp"}, {"autocuelog", {NULL}, 3104, "tcp"}, {"autocuetime", {NULL}, 3104, "udp"}, {"cardbox", {NULL}, 3105, "tcp"}, {"cardbox", {NULL}, 3105, "udp"}, {"cardbox-http", {NULL}, 3106, "tcp"}, {"cardbox-http", {NULL}, 3106, "udp"}, {"business", {NULL}, 3107, "tcp"}, {"business", {NULL}, 3107, "udp"}, {"geolocate", {NULL}, 3108, "tcp"}, {"geolocate", {NULL}, 3108, "udp"}, {"personnel", {NULL}, 3109, "tcp"}, {"personnel", {NULL}, 3109, "udp"}, {"sim-control", {NULL}, 3110, "tcp"}, {"sim-control", {NULL}, 3110, "udp"}, {"wsynch", {NULL}, 3111, "tcp"}, {"wsynch", {NULL}, 3111, "udp"}, {"ksysguard", {NULL}, 3112, "tcp"}, {"ksysguard", {NULL}, 3112, "udp"}, {"cs-auth-svr", {NULL}, 3113, "tcp"}, {"cs-auth-svr", {NULL}, 3113, "udp"}, {"ccmad", {NULL}, 3114, "tcp"}, {"ccmad", {NULL}, 3114, "udp"}, {"mctet-master", {NULL}, 3115, "tcp"}, {"mctet-master", {NULL}, 3115, "udp"}, {"mctet-gateway", {NULL}, 3116, "tcp"}, {"mctet-gateway", {NULL}, 3116, "udp"}, {"mctet-jserv", {NULL}, 3117, "tcp"}, {"mctet-jserv", {NULL}, 3117, "udp"}, {"pkagent", {NULL}, 3118, "tcp"}, {"pkagent", {NULL}, 3118, "udp"}, {"d2000kernel", {NULL}, 3119, "tcp"}, {"d2000kernel", {NULL}, 3119, "udp"}, {"d2000webserver", {NULL}, 3120, "tcp"}, {"d2000webserver", {NULL}, 3120, "udp"}, {"vtr-emulator", {NULL}, 3122, "tcp"}, {"vtr-emulator", {NULL}, 3122, "udp"}, {"edix", {NULL}, 3123, "tcp"}, {"edix", {NULL}, 3123, "udp"}, {"beacon-port", {NULL}, 3124, "tcp"}, {"beacon-port", {NULL}, 3124, "udp"}, {"a13-an", {NULL}, 3125, "tcp"}, {"a13-an", {NULL}, 3125, "udp"}, {"ctx-bridge", {NULL}, 3127, "tcp"}, {"ctx-bridge", {NULL}, 3127, "udp"}, {"ndl-aas", {NULL}, 3128, "tcp"}, {"ndl-aas", {NULL}, 3128, "udp"}, {"netport-id", {NULL}, 3129, "tcp"}, {"netport-id", {NULL}, 3129, "udp"}, {"icpv2", {NULL}, 3130, "tcp"}, {"icpv2", {NULL}, 3130, "udp"}, {"netbookmark", {NULL}, 3131, "tcp"}, {"netbookmark", {NULL}, 3131, "udp"}, {"ms-rule-engine", {NULL}, 3132, "tcp"}, {"ms-rule-engine", {NULL}, 3132, "udp"}, {"prism-deploy", {NULL}, 3133, "tcp"}, {"prism-deploy", {NULL}, 3133, "udp"}, {"ecp", {NULL}, 3134, "tcp"}, {"ecp", {NULL}, 3134, "udp"}, {"peerbook-port", {NULL}, 3135, "tcp"}, {"peerbook-port", {NULL}, 3135, "udp"}, {"grubd", {NULL}, 3136, "tcp"}, {"grubd", {NULL}, 3136, "udp"}, {"rtnt-1", {NULL}, 3137, "tcp"}, {"rtnt-1", {NULL}, 3137, "udp"}, {"rtnt-2", {NULL}, 3138, "tcp"}, {"rtnt-2", {NULL}, 3138, "udp"}, {"incognitorv", {NULL}, 3139, "tcp"}, {"incognitorv", {NULL}, 3139, "udp"}, {"ariliamulti", {NULL}, 3140, "tcp"}, {"ariliamulti", {NULL}, 3140, "udp"}, {"vmodem", {NULL}, 3141, "tcp"}, {"vmodem", {NULL}, 3141, "udp"}, {"rdc-wh-eos", {NULL}, 3142, "tcp"}, {"rdc-wh-eos", {NULL}, 3142, "udp"}, {"seaview", {NULL}, 3143, "tcp"}, {"seaview", {NULL}, 3143, "udp"}, {"tarantella", {NULL}, 3144, "tcp"}, {"tarantella", {NULL}, 3144, "udp"}, {"csi-lfap", {NULL}, 3145, "tcp"}, {"csi-lfap", {NULL}, 3145, "udp"}, {"bears-02", {NULL}, 3146, "tcp"}, {"bears-02", {NULL}, 3146, "udp"}, {"rfio", {NULL}, 3147, "tcp"}, {"rfio", {NULL}, 3147, "udp"}, {"nm-game-admin", {NULL}, 3148, "tcp"}, {"nm-game-admin", {NULL}, 3148, "udp"}, {"nm-game-server", {NULL}, 3149, "tcp"}, {"nm-game-server", {NULL}, 3149, "udp"}, {"nm-asses-admin", {NULL}, 3150, "tcp"}, {"nm-asses-admin", {NULL}, 3150, "udp"}, {"nm-assessor", {NULL}, 3151, "tcp"}, {"nm-assessor", {NULL}, 3151, "udp"}, {"feitianrockey", {NULL}, 3152, "tcp"}, {"feitianrockey", {NULL}, 3152, "udp"}, {"s8-client-port", {NULL}, 3153, "tcp"}, {"s8-client-port", {NULL}, 3153, "udp"}, {"ccmrmi", {NULL}, 3154, "tcp"}, {"ccmrmi", {NULL}, 3154, "udp"}, {"jpegmpeg", {NULL}, 3155, "tcp"}, {"jpegmpeg", {NULL}, 3155, "udp"}, {"indura", {NULL}, 3156, "tcp"}, {"indura", {NULL}, 3156, "udp"}, {"e3consultants", {NULL}, 3157, "tcp"}, {"e3consultants", {NULL}, 3157, "udp"}, {"stvp", {NULL}, 3158, "tcp"}, {"stvp", {NULL}, 3158, "udp"}, {"navegaweb-port", {NULL}, 3159, "tcp"}, {"navegaweb-port", {NULL}, 3159, "udp"}, {"tip-app-server", {NULL}, 3160, "tcp"}, {"tip-app-server", {NULL}, 3160, "udp"}, {"doc1lm", {NULL}, 3161, "tcp"}, {"doc1lm", {NULL}, 3161, "udp"}, {"sflm", {NULL}, 3162, "tcp"}, {"sflm", {NULL}, 3162, "udp"}, {"res-sap", {NULL}, 3163, "tcp"}, {"res-sap", {NULL}, 3163, "udp"}, {"imprs", {NULL}, 3164, "tcp"}, {"imprs", {NULL}, 3164, "udp"}, {"newgenpay", {NULL}, 3165, "tcp"}, {"newgenpay", {NULL}, 3165, "udp"}, {"sossecollector", {NULL}, 3166, "tcp"}, {"sossecollector", {NULL}, 3166, "udp"}, {"nowcontact", {NULL}, 3167, "tcp"}, {"nowcontact", {NULL}, 3167, "udp"}, {"poweronnud", {NULL}, 3168, "tcp"}, {"poweronnud", {NULL}, 3168, "udp"}, {"serverview-as", {NULL}, 3169, "tcp"}, {"serverview-as", {NULL}, 3169, "udp"}, {"serverview-asn", {NULL}, 3170, "tcp"}, {"serverview-asn", {NULL}, 3170, "udp"}, {"serverview-gf", {NULL}, 3171, "tcp"}, {"serverview-gf", {NULL}, 3171, "udp"}, {"serverview-rm", {NULL}, 3172, "tcp"}, {"serverview-rm", {NULL}, 3172, "udp"}, {"serverview-icc", {NULL}, 3173, "tcp"}, {"serverview-icc", {NULL}, 3173, "udp"}, {"armi-server", {NULL}, 3174, "tcp"}, {"armi-server", {NULL}, 3174, "udp"}, {"t1-e1-over-ip", {NULL}, 3175, "tcp"}, {"t1-e1-over-ip", {NULL}, 3175, "udp"}, {"ars-master", {NULL}, 3176, "tcp"}, {"ars-master", {NULL}, 3176, "udp"}, {"phonex-port", {NULL}, 3177, "tcp"}, {"phonex-port", {NULL}, 3177, "udp"}, {"radclientport", {NULL}, 3178, "tcp"}, {"radclientport", {NULL}, 3178, "udp"}, {"h2gf-w-2m", {NULL}, 3179, "tcp"}, {"h2gf-w-2m", {NULL}, 3179, "udp"}, {"mc-brk-srv", {NULL}, 3180, "tcp"}, {"mc-brk-srv", {NULL}, 3180, "udp"}, {"bmcpatrolagent", {NULL}, 3181, "tcp"}, {"bmcpatrolagent", {NULL}, 3181, "udp"}, {"bmcpatrolrnvu", {NULL}, 3182, "tcp"}, {"bmcpatrolrnvu", {NULL}, 3182, "udp"}, {"cops-tls", {NULL}, 3183, "tcp"}, {"cops-tls", {NULL}, 3183, "udp"}, {"apogeex-port", {NULL}, 3184, "tcp"}, {"apogeex-port", {NULL}, 3184, "udp"}, {"smpppd", {NULL}, 3185, "tcp"}, {"smpppd", {NULL}, 3185, "udp"}, {"iiw-port", {NULL}, 3186, "tcp"}, {"iiw-port", {NULL}, 3186, "udp"}, {"odi-port", {NULL}, 3187, "tcp"}, {"odi-port", {NULL}, 3187, "udp"}, {"brcm-comm-port", {NULL}, 3188, "tcp"}, {"brcm-comm-port", {NULL}, 3188, "udp"}, {"pcle-infex", {NULL}, 3189, "tcp"}, {"pcle-infex", {NULL}, 3189, "udp"}, {"csvr-proxy", {NULL}, 3190, "tcp"}, {"csvr-proxy", {NULL}, 3190, "udp"}, {"csvr-sslproxy", {NULL}, 3191, "tcp"}, {"csvr-sslproxy", {NULL}, 3191, "udp"}, {"firemonrcc", {NULL}, 3192, "tcp"}, {"firemonrcc", {NULL}, 3192, "udp"}, {"spandataport", {NULL}, 3193, "tcp"}, {"spandataport", {NULL}, 3193, "udp"}, {"magbind", {NULL}, 3194, "tcp"}, {"magbind", {NULL}, 3194, "udp"}, {"ncu-1", {NULL}, 3195, "tcp"}, {"ncu-1", {NULL}, 3195, "udp"}, {"ncu-2", {NULL}, 3196, "tcp"}, {"ncu-2", {NULL}, 3196, "udp"}, {"embrace-dp-s", {NULL}, 3197, "tcp"}, {"embrace-dp-s", {NULL}, 3197, "udp"}, {"embrace-dp-c", {NULL}, 3198, "tcp"}, {"embrace-dp-c", {NULL}, 3198, "udp"}, {"dmod-workspace", {NULL}, 3199, "tcp"}, {"dmod-workspace", {NULL}, 3199, "udp"}, {"tick-port", {NULL}, 3200, "tcp"}, {"tick-port", {NULL}, 3200, "udp"}, {"cpq-tasksmart", {NULL}, 3201, "tcp"}, {"cpq-tasksmart", {NULL}, 3201, "udp"}, {"intraintra", {NULL}, 3202, "tcp"}, {"intraintra", {NULL}, 3202, "udp"}, {"netwatcher-mon", {NULL}, 3203, "tcp"}, {"netwatcher-mon", {NULL}, 3203, "udp"}, {"netwatcher-db", {NULL}, 3204, "tcp"}, {"netwatcher-db", {NULL}, 3204, "udp"}, {"isns", {NULL}, 3205, "tcp"}, {"isns", {NULL}, 3205, "udp"}, {"ironmail", {NULL}, 3206, "tcp"}, {"ironmail", {NULL}, 3206, "udp"}, {"vx-auth-port", {NULL}, 3207, "tcp"}, {"vx-auth-port", {NULL}, 3207, "udp"}, {"pfu-prcallback", {NULL}, 3208, "tcp"}, {"pfu-prcallback", {NULL}, 3208, "udp"}, {"netwkpathengine", {NULL}, 3209, "tcp"}, {"netwkpathengine", {NULL}, 3209, "udp"}, {"flamenco-proxy", {NULL}, 3210, "tcp"}, {"flamenco-proxy", {NULL}, 3210, "udp"}, {"avsecuremgmt", {NULL}, 3211, "tcp"}, {"avsecuremgmt", {NULL}, 3211, "udp"}, {"surveyinst", {NULL}, 3212, "tcp"}, {"surveyinst", {NULL}, 3212, "udp"}, {"neon24x7", {NULL}, 3213, "tcp"}, {"neon24x7", {NULL}, 3213, "udp"}, {"jmq-daemon-1", {NULL}, 3214, "tcp"}, {"jmq-daemon-1", {NULL}, 3214, "udp"}, {"jmq-daemon-2", {NULL}, 3215, "tcp"}, {"jmq-daemon-2", {NULL}, 3215, "udp"}, {"ferrari-foam", {NULL}, 3216, "tcp"}, {"ferrari-foam", {NULL}, 3216, "udp"}, {"unite", {NULL}, 3217, "tcp"}, {"unite", {NULL}, 3217, "udp"}, {"smartpackets", {NULL}, 3218, "tcp"}, {"smartpackets", {NULL}, 3218, "udp"}, {"wms-messenger", {NULL}, 3219, "tcp"}, {"wms-messenger", {NULL}, 3219, "udp"}, {"xnm-ssl", {NULL}, 3220, "tcp"}, {"xnm-ssl", {NULL}, 3220, "udp"}, {"xnm-clear-text", {NULL}, 3221, "tcp"}, {"xnm-clear-text", {NULL}, 3221, "udp"}, {"glbp", {NULL}, 3222, "tcp"}, {"glbp", {NULL}, 3222, "udp"}, {"digivote", {NULL}, 3223, "tcp"}, {"digivote", {NULL}, 3223, "udp"}, {"aes-discovery", {NULL}, 3224, "tcp"}, {"aes-discovery", {NULL}, 3224, "udp"}, {"fcip-port", {NULL}, 3225, "tcp"}, {"fcip-port", {NULL}, 3225, "udp"}, {"isi-irp", {NULL}, 3226, "tcp"}, {"isi-irp", {NULL}, 3226, "udp"}, {"dwnmshttp", {NULL}, 3227, "tcp"}, {"dwnmshttp", {NULL}, 3227, "udp"}, {"dwmsgserver", {NULL}, 3228, "tcp"}, {"dwmsgserver", {NULL}, 3228, "udp"}, {"global-cd-port", {NULL}, 3229, "tcp"}, {"global-cd-port", {NULL}, 3229, "udp"}, {"sftdst-port", {NULL}, 3230, "tcp"}, {"sftdst-port", {NULL}, 3230, "udp"}, {"vidigo", {NULL}, 3231, "tcp"}, {"vidigo", {NULL}, 3231, "udp"}, {"mdtp", {NULL}, 3232, "tcp"}, {"mdtp", {NULL}, 3232, "udp"}, {"whisker", {NULL}, 3233, "tcp"}, {"whisker", {NULL}, 3233, "udp"}, {"alchemy", {NULL}, 3234, "tcp"}, {"alchemy", {NULL}, 3234, "udp"}, {"mdap-port", {NULL}, 3235, "tcp"}, {"mdap-port", {NULL}, 3235, "udp"}, {"apparenet-ts", {NULL}, 3236, "tcp"}, {"apparenet-ts", {NULL}, 3236, "udp"}, {"apparenet-tps", {NULL}, 3237, "tcp"}, {"apparenet-tps", {NULL}, 3237, "udp"}, {"apparenet-as", {NULL}, 3238, "tcp"}, {"apparenet-as", {NULL}, 3238, "udp"}, {"apparenet-ui", {NULL}, 3239, "tcp"}, {"apparenet-ui", {NULL}, 3239, "udp"}, {"triomotion", {NULL}, 3240, "tcp"}, {"triomotion", {NULL}, 3240, "udp"}, {"sysorb", {NULL}, 3241, "tcp"}, {"sysorb", {NULL}, 3241, "udp"}, {"sdp-id-port", {NULL}, 3242, "tcp"}, {"sdp-id-port", {NULL}, 3242, "udp"}, {"timelot", {NULL}, 3243, "tcp"}, {"timelot", {NULL}, 3243, "udp"}, {"onesaf", {NULL}, 3244, "tcp"}, {"onesaf", {NULL}, 3244, "udp"}, {"vieo-fe", {NULL}, 3245, "tcp"}, {"vieo-fe", {NULL}, 3245, "udp"}, {"dvt-system", {NULL}, 3246, "tcp"}, {"dvt-system", {NULL}, 3246, "udp"}, {"dvt-data", {NULL}, 3247, "tcp"}, {"dvt-data", {NULL}, 3247, "udp"}, {"procos-lm", {NULL}, 3248, "tcp"}, {"procos-lm", {NULL}, 3248, "udp"}, {"ssp", {NULL}, 3249, "tcp"}, {"ssp", {NULL}, 3249, "udp"}, {"hicp", {NULL}, 3250, "tcp"}, {"hicp", {NULL}, 3250, "udp"}, {"sysscanner", {NULL}, 3251, "tcp"}, {"sysscanner", {NULL}, 3251, "udp"}, {"dhe", {NULL}, 3252, "tcp"}, {"dhe", {NULL}, 3252, "udp"}, {"pda-data", {NULL}, 3253, "tcp"}, {"pda-data", {NULL}, 3253, "udp"}, {"pda-sys", {NULL}, 3254, "tcp"}, {"pda-sys", {NULL}, 3254, "udp"}, {"semaphore", {NULL}, 3255, "tcp"}, {"semaphore", {NULL}, 3255, "udp"}, {"cpqrpm-agent", {NULL}, 3256, "tcp"}, {"cpqrpm-agent", {NULL}, 3256, "udp"}, {"cpqrpm-server", {NULL}, 3257, "tcp"}, {"cpqrpm-server", {NULL}, 3257, "udp"}, {"ivecon-port", {NULL}, 3258, "tcp"}, {"ivecon-port", {NULL}, 3258, "udp"}, {"epncdp2", {NULL}, 3259, "tcp"}, {"epncdp2", {NULL}, 3259, "udp"}, {"iscsi-target", {NULL}, 3260, "tcp"}, {"iscsi-target", {NULL}, 3260, "udp"}, {"winshadow", {NULL}, 3261, "tcp"}, {"winshadow", {NULL}, 3261, "udp"}, {"necp", {NULL}, 3262, "tcp"}, {"necp", {NULL}, 3262, "udp"}, {"ecolor-imager", {NULL}, 3263, "tcp"}, {"ecolor-imager", {NULL}, 3263, "udp"}, {"ccmail", {NULL}, 3264, "tcp"}, {"ccmail", {NULL}, 3264, "udp"}, {"altav-tunnel", {NULL}, 3265, "tcp"}, {"altav-tunnel", {NULL}, 3265, "udp"}, {"ns-cfg-server", {NULL}, 3266, "tcp"}, {"ns-cfg-server", {NULL}, 3266, "udp"}, {"ibm-dial-out", {NULL}, 3267, "tcp"}, {"ibm-dial-out", {NULL}, 3267, "udp"}, {"msft-gc", {NULL}, 3268, "tcp"}, {"msft-gc", {NULL}, 3268, "udp"}, {"msft-gc-ssl", {NULL}, 3269, "tcp"}, {"msft-gc-ssl", {NULL}, 3269, "udp"}, {"verismart", {NULL}, 3270, "tcp"}, {"verismart", {NULL}, 3270, "udp"}, {"csoft-prev", {NULL}, 3271, "tcp"}, {"csoft-prev", {NULL}, 3271, "udp"}, {"user-manager", {NULL}, 3272, "tcp"}, {"user-manager", {NULL}, 3272, "udp"}, {"sxmp", {NULL}, 3273, "tcp"}, {"sxmp", {NULL}, 3273, "udp"}, {"ordinox-server", {NULL}, 3274, "tcp"}, {"ordinox-server", {NULL}, 3274, "udp"}, {"samd", {NULL}, 3275, "tcp"}, {"samd", {NULL}, 3275, "udp"}, {"maxim-asics", {NULL}, 3276, "tcp"}, {"maxim-asics", {NULL}, 3276, "udp"}, {"awg-proxy", {NULL}, 3277, "tcp"}, {"awg-proxy", {NULL}, 3277, "udp"}, {"lkcmserver", {NULL}, 3278, "tcp"}, {"lkcmserver", {NULL}, 3278, "udp"}, {"admind", {NULL}, 3279, "tcp"}, {"admind", {NULL}, 3279, "udp"}, {"vs-server", {NULL}, 3280, "tcp"}, {"vs-server", {NULL}, 3280, "udp"}, {"sysopt", {NULL}, 3281, "tcp"}, {"sysopt", {NULL}, 3281, "udp"}, {"datusorb", {NULL}, 3282, "tcp"}, {"datusorb", {NULL}, 3282, "udp"}, {"net-assistant", {NULL}, 3283, "tcp"}, {"net-assistant", {NULL}, 3283, "udp"}, {"4talk", {NULL}, 3284, "tcp"}, {"4talk", {NULL}, 3284, "udp"}, {"plato", {NULL}, 3285, "tcp"}, {"plato", {NULL}, 3285, "udp"}, {"e-net", {NULL}, 3286, "tcp"}, {"e-net", {NULL}, 3286, "udp"}, {"directvdata", {NULL}, 3287, "tcp"}, {"directvdata", {NULL}, 3287, "udp"}, {"cops", {NULL}, 3288, "tcp"}, {"cops", {NULL}, 3288, "udp"}, {"enpc", {NULL}, 3289, "tcp"}, {"enpc", {NULL}, 3289, "udp"}, {"caps-lm", {NULL}, 3290, "tcp"}, {"caps-lm", {NULL}, 3290, "udp"}, {"sah-lm", {NULL}, 3291, "tcp"}, {"sah-lm", {NULL}, 3291, "udp"}, {"cart-o-rama", {NULL}, 3292, "tcp"}, {"cart-o-rama", {NULL}, 3292, "udp"}, {"fg-fps", {NULL}, 3293, "tcp"}, {"fg-fps", {NULL}, 3293, "udp"}, {"fg-gip", {NULL}, 3294, "tcp"}, {"fg-gip", {NULL}, 3294, "udp"}, {"dyniplookup", {NULL}, 3295, "tcp"}, {"dyniplookup", {NULL}, 3295, "udp"}, {"rib-slm", {NULL}, 3296, "tcp"}, {"rib-slm", {NULL}, 3296, "udp"}, {"cytel-lm", {NULL}, 3297, "tcp"}, {"cytel-lm", {NULL}, 3297, "udp"}, {"deskview", {NULL}, 3298, "tcp"}, {"deskview", {NULL}, 3298, "udp"}, {"pdrncs", {NULL}, 3299, "tcp"}, {"pdrncs", {NULL}, 3299, "udp"}, {"mcs-fastmail", {NULL}, 3302, "tcp"}, {"mcs-fastmail", {NULL}, 3302, "udp"}, {"opsession-clnt", {NULL}, 3303, "tcp"}, {"opsession-clnt", {NULL}, 3303, "udp"}, {"opsession-srvr", {NULL}, 3304, "tcp"}, {"opsession-srvr", {NULL}, 3304, "udp"}, {"odette-ftp", {NULL}, 3305, "tcp"}, {"odette-ftp", {NULL}, 3305, "udp"}, {"mysql", {NULL}, 3306, "tcp"}, {"mysql", {NULL}, 3306, "udp"}, {"opsession-prxy", {NULL}, 3307, "tcp"}, {"opsession-prxy", {NULL}, 3307, "udp"}, {"tns-server", {NULL}, 3308, "tcp"}, {"tns-server", {NULL}, 3308, "udp"}, {"tns-adv", {NULL}, 3309, "tcp"}, {"tns-adv", {NULL}, 3309, "udp"}, {"dyna-access", {NULL}, 3310, "tcp"}, {"dyna-access", {NULL}, 3310, "udp"}, {"mcns-tel-ret", {NULL}, 3311, "tcp"}, {"mcns-tel-ret", {NULL}, 3311, "udp"}, {"appman-server", {NULL}, 3312, "tcp"}, {"appman-server", {NULL}, 3312, "udp"}, {"uorb", {NULL}, 3313, "tcp"}, {"uorb", {NULL}, 3313, "udp"}, {"uohost", {NULL}, 3314, "tcp"}, {"uohost", {NULL}, 3314, "udp"}, {"cdid", {NULL}, 3315, "tcp"}, {"cdid", {NULL}, 3315, "udp"}, {"aicc-cmi", {NULL}, 3316, "tcp"}, {"aicc-cmi", {NULL}, 3316, "udp"}, {"vsaiport", {NULL}, 3317, "tcp"}, {"vsaiport", {NULL}, 3317, "udp"}, {"ssrip", {NULL}, 3318, "tcp"}, {"ssrip", {NULL}, 3318, "udp"}, {"sdt-lmd", {NULL}, 3319, "tcp"}, {"sdt-lmd", {NULL}, 3319, "udp"}, {"officelink2000", {NULL}, 3320, "tcp"}, {"officelink2000", {NULL}, 3320, "udp"}, {"vnsstr", {NULL}, 3321, "tcp"}, {"vnsstr", {NULL}, 3321, "udp"}, {"sftu", {NULL}, 3326, "tcp"}, {"sftu", {NULL}, 3326, "udp"}, {"bbars", {NULL}, 3327, "tcp"}, {"bbars", {NULL}, 3327, "udp"}, {"egptlm", {NULL}, 3328, "tcp"}, {"egptlm", {NULL}, 3328, "udp"}, {"hp-device-disc", {NULL}, 3329, "tcp"}, {"hp-device-disc", {NULL}, 3329, "udp"}, {"mcs-calypsoicf", {NULL}, 3330, "tcp"}, {"mcs-calypsoicf", {NULL}, 3330, "udp"}, {"mcs-messaging", {NULL}, 3331, "tcp"}, {"mcs-messaging", {NULL}, 3331, "udp"}, {"mcs-mailsvr", {NULL}, 3332, "tcp"}, {"mcs-mailsvr", {NULL}, 3332, "udp"}, {"dec-notes", {NULL}, 3333, "tcp"}, {"dec-notes", {NULL}, 3333, "udp"}, {"directv-web", {NULL}, 3334, "tcp"}, {"directv-web", {NULL}, 3334, "udp"}, {"directv-soft", {NULL}, 3335, "tcp"}, {"directv-soft", {NULL}, 3335, "udp"}, {"directv-tick", {NULL}, 3336, "tcp"}, {"directv-tick", {NULL}, 3336, "udp"}, {"directv-catlg", {NULL}, 3337, "tcp"}, {"directv-catlg", {NULL}, 3337, "udp"}, {"anet-b", {NULL}, 3338, "tcp"}, {"anet-b", {NULL}, 3338, "udp"}, {"anet-l", {NULL}, 3339, "tcp"}, {"anet-l", {NULL}, 3339, "udp"}, {"anet-m", {NULL}, 3340, "tcp"}, {"anet-m", {NULL}, 3340, "udp"}, {"anet-h", {NULL}, 3341, "tcp"}, {"anet-h", {NULL}, 3341, "udp"}, {"webtie", {NULL}, 3342, "tcp"}, {"webtie", {NULL}, 3342, "udp"}, {"ms-cluster-net", {NULL}, 3343, "tcp"}, {"ms-cluster-net", {NULL}, 3343, "udp"}, {"bnt-manager", {NULL}, 3344, "tcp"}, {"bnt-manager", {NULL}, 3344, "udp"}, {"influence", {NULL}, 3345, "tcp"}, {"influence", {NULL}, 3345, "udp"}, {"trnsprntproxy", {NULL}, 3346, "tcp"}, {"trnsprntproxy", {NULL}, 3346, "udp"}, {"phoenix-rpc", {NULL}, 3347, "tcp"}, {"phoenix-rpc", {NULL}, 3347, "udp"}, {"pangolin-laser", {NULL}, 3348, "tcp"}, {"pangolin-laser", {NULL}, 3348, "udp"}, {"chevinservices", {NULL}, 3349, "tcp"}, {"chevinservices", {NULL}, 3349, "udp"}, {"findviatv", {NULL}, 3350, "tcp"}, {"findviatv", {NULL}, 3350, "udp"}, {"btrieve", {NULL}, 3351, "tcp"}, {"btrieve", {NULL}, 3351, "udp"}, {"ssql", {NULL}, 3352, "tcp"}, {"ssql", {NULL}, 3352, "udp"}, {"fatpipe", {NULL}, 3353, "tcp"}, {"fatpipe", {NULL}, 3353, "udp"}, {"suitjd", {NULL}, 3354, "tcp"}, {"suitjd", {NULL}, 3354, "udp"}, {"ordinox-dbase", {NULL}, 3355, "tcp"}, {"ordinox-dbase", {NULL}, 3355, "udp"}, {"upnotifyps", {NULL}, 3356, "tcp"}, {"upnotifyps", {NULL}, 3356, "udp"}, {"adtech-test", {NULL}, 3357, "tcp"}, {"adtech-test", {NULL}, 3357, "udp"}, {"mpsysrmsvr", {NULL}, 3358, "tcp"}, {"mpsysrmsvr", {NULL}, 3358, "udp"}, {"wg-netforce", {NULL}, 3359, "tcp"}, {"wg-netforce", {NULL}, 3359, "udp"}, {"kv-server", {NULL}, 3360, "tcp"}, {"kv-server", {NULL}, 3360, "udp"}, {"kv-agent", {NULL}, 3361, "tcp"}, {"kv-agent", {NULL}, 3361, "udp"}, {"dj-ilm", {NULL}, 3362, "tcp"}, {"dj-ilm", {NULL}, 3362, "udp"}, {"nati-vi-server", {NULL}, 3363, "tcp"}, {"nati-vi-server", {NULL}, 3363, "udp"}, {"creativeserver", {NULL}, 3364, "tcp"}, {"creativeserver", {NULL}, 3364, "udp"}, {"contentserver", {NULL}, 3365, "tcp"}, {"contentserver", {NULL}, 3365, "udp"}, {"creativepartnr", {NULL}, 3366, "tcp"}, {"creativepartnr", {NULL}, 3366, "udp"}, {"tip2", {NULL}, 3372, "tcp"}, {"tip2", {NULL}, 3372, "udp"}, {"lavenir-lm", {NULL}, 3373, "tcp"}, {"lavenir-lm", {NULL}, 3373, "udp"}, {"cluster-disc", {NULL}, 3374, "tcp"}, {"cluster-disc", {NULL}, 3374, "udp"}, {"vsnm-agent", {NULL}, 3375, "tcp"}, {"vsnm-agent", {NULL}, 3375, "udp"}, {"cdbroker", {NULL}, 3376, "tcp"}, {"cdbroker", {NULL}, 3376, "udp"}, {"cogsys-lm", {NULL}, 3377, "tcp"}, {"cogsys-lm", {NULL}, 3377, "udp"}, {"wsicopy", {NULL}, 3378, "tcp"}, {"wsicopy", {NULL}, 3378, "udp"}, {"socorfs", {NULL}, 3379, "tcp"}, {"socorfs", {NULL}, 3379, "udp"}, {"sns-channels", {NULL}, 3380, "tcp"}, {"sns-channels", {NULL}, 3380, "udp"}, {"geneous", {NULL}, 3381, "tcp"}, {"geneous", {NULL}, 3381, "udp"}, {"fujitsu-neat", {NULL}, 3382, "tcp"}, {"fujitsu-neat", {NULL}, 3382, "udp"}, {"esp-lm", {NULL}, 3383, "tcp"}, {"esp-lm", {NULL}, 3383, "udp"}, {"hp-clic", {NULL}, 3384, "tcp"}, {"hp-clic", {NULL}, 3384, "udp"}, {"qnxnetman", {NULL}, 3385, "tcp"}, {"qnxnetman", {NULL}, 3385, "udp"}, {"gprs-data", {NULL}, 3386, "tcp"}, {"gprs-sig", {NULL}, 3386, "udp"}, {"backroomnet", {NULL}, 3387, "tcp"}, {"backroomnet", {NULL}, 3387, "udp"}, {"cbserver", {NULL}, 3388, "tcp"}, {"cbserver", {NULL}, 3388, "udp"}, {"ms-wbt-server", {NULL}, 3389, "tcp"}, {"ms-wbt-server", {NULL}, 3389, "udp"}, {"dsc", {NULL}, 3390, "tcp"}, {"dsc", {NULL}, 3390, "udp"}, {"savant", {NULL}, 3391, "tcp"}, {"savant", {NULL}, 3391, "udp"}, {"efi-lm", {NULL}, 3392, "tcp"}, {"efi-lm", {NULL}, 3392, "udp"}, {"d2k-tapestry1", {NULL}, 3393, "tcp"}, {"d2k-tapestry1", {NULL}, 3393, "udp"}, {"d2k-tapestry2", {NULL}, 3394, "tcp"}, {"d2k-tapestry2", {NULL}, 3394, "udp"}, {"dyna-lm", {NULL}, 3395, "tcp"}, {"dyna-lm", {NULL}, 3395, "udp"}, {"printer_agent", {NULL}, 3396, "tcp"}, {"printer_agent", {NULL}, 3396, "udp"}, {"cloanto-lm", {NULL}, 3397, "tcp"}, {"cloanto-lm", {NULL}, 3397, "udp"}, {"mercantile", {NULL}, 3398, "tcp"}, {"mercantile", {NULL}, 3398, "udp"}, {"csms", {NULL}, 3399, "tcp"}, {"csms", {NULL}, 3399, "udp"}, {"csms2", {NULL}, 3400, "tcp"}, {"csms2", {NULL}, 3400, "udp"}, {"filecast", {NULL}, 3401, "tcp"}, {"filecast", {NULL}, 3401, "udp"}, {"fxaengine-net", {NULL}, 3402, "tcp"}, {"fxaengine-net", {NULL}, 3402, "udp"}, {"nokia-ann-ch1", {NULL}, 3405, "tcp"}, {"nokia-ann-ch1", {NULL}, 3405, "udp"}, {"nokia-ann-ch2", {NULL}, 3406, "tcp"}, {"nokia-ann-ch2", {NULL}, 3406, "udp"}, {"ldap-admin", {NULL}, 3407, "tcp"}, {"ldap-admin", {NULL}, 3407, "udp"}, {"BESApi", {NULL}, 3408, "tcp"}, {"BESApi", {NULL}, 3408, "udp"}, {"networklens", {NULL}, 3409, "tcp"}, {"networklens", {NULL}, 3409, "udp"}, {"networklenss", {NULL}, 3410, "tcp"}, {"networklenss", {NULL}, 3410, "udp"}, {"biolink-auth", {NULL}, 3411, "tcp"}, {"biolink-auth", {NULL}, 3411, "udp"}, {"xmlblaster", {NULL}, 3412, "tcp"}, {"xmlblaster", {NULL}, 3412, "udp"}, {"svnet", {NULL}, 3413, "tcp"}, {"svnet", {NULL}, 3413, "udp"}, {"wip-port", {NULL}, 3414, "tcp"}, {"wip-port", {NULL}, 3414, "udp"}, {"bcinameservice", {NULL}, 3415, "tcp"}, {"bcinameservice", {NULL}, 3415, "udp"}, {"commandport", {NULL}, 3416, "tcp"}, {"commandport", {NULL}, 3416, "udp"}, {"csvr", {NULL}, 3417, "tcp"}, {"csvr", {NULL}, 3417, "udp"}, {"rnmap", {NULL}, 3418, "tcp"}, {"rnmap", {NULL}, 3418, "udp"}, {"softaudit", {NULL}, 3419, "tcp"}, {"softaudit", {NULL}, 3419, "udp"}, {"ifcp-port", {NULL}, 3420, "tcp"}, {"ifcp-port", {NULL}, 3420, "udp"}, {"bmap", {NULL}, 3421, "tcp"}, {"bmap", {NULL}, 3421, "udp"}, {"rusb-sys-port", {NULL}, 3422, "tcp"}, {"rusb-sys-port", {NULL}, 3422, "udp"}, {"xtrm", {NULL}, 3423, "tcp"}, {"xtrm", {NULL}, 3423, "udp"}, {"xtrms", {NULL}, 3424, "tcp"}, {"xtrms", {NULL}, 3424, "udp"}, {"agps-port", {NULL}, 3425, "tcp"}, {"agps-port", {NULL}, 3425, "udp"}, {"arkivio", {NULL}, 3426, "tcp"}, {"arkivio", {NULL}, 3426, "udp"}, {"websphere-snmp", {NULL}, 3427, "tcp"}, {"websphere-snmp", {NULL}, 3427, "udp"}, {"twcss", {NULL}, 3428, "tcp"}, {"twcss", {NULL}, 3428, "udp"}, {"gcsp", {NULL}, 3429, "tcp"}, {"gcsp", {NULL}, 3429, "udp"}, {"ssdispatch", {NULL}, 3430, "tcp"}, {"ssdispatch", {NULL}, 3430, "udp"}, {"ndl-als", {NULL}, 3431, "tcp"}, {"ndl-als", {NULL}, 3431, "udp"}, {"osdcp", {NULL}, 3432, "tcp"}, {"osdcp", {NULL}, 3432, "udp"}, {"alta-smp", {NULL}, 3433, "tcp"}, {"alta-smp", {NULL}, 3433, "udp"}, {"opencm", {NULL}, 3434, "tcp"}, {"opencm", {NULL}, 3434, "udp"}, {"pacom", {NULL}, 3435, "tcp"}, {"pacom", {NULL}, 3435, "udp"}, {"gc-config", {NULL}, 3436, "tcp"}, {"gc-config", {NULL}, 3436, "udp"}, {"autocueds", {NULL}, 3437, "tcp"}, {"autocueds", {NULL}, 3437, "udp"}, {"spiral-admin", {NULL}, 3438, "tcp"}, {"spiral-admin", {NULL}, 3438, "udp"}, {"hri-port", {NULL}, 3439, "tcp"}, {"hri-port", {NULL}, 3439, "udp"}, {"ans-console", {NULL}, 3440, "tcp"}, {"ans-console", {NULL}, 3440, "udp"}, {"connect-client", {NULL}, 3441, "tcp"}, {"connect-client", {NULL}, 3441, "udp"}, {"connect-server", {NULL}, 3442, "tcp"}, {"connect-server", {NULL}, 3442, "udp"}, {"ov-nnm-websrv", {NULL}, 3443, "tcp"}, {"ov-nnm-websrv", {NULL}, 3443, "udp"}, {"denali-server", {NULL}, 3444, "tcp"}, {"denali-server", {NULL}, 3444, "udp"}, {"monp", {NULL}, 3445, "tcp"}, {"monp", {NULL}, 3445, "udp"}, {"3comfaxrpc", {NULL}, 3446, "tcp"}, {"3comfaxrpc", {NULL}, 3446, "udp"}, {"directnet", {NULL}, 3447, "tcp"}, {"directnet", {NULL}, 3447, "udp"}, {"dnc-port", {NULL}, 3448, "tcp"}, {"dnc-port", {NULL}, 3448, "udp"}, {"hotu-chat", {NULL}, 3449, "tcp"}, {"hotu-chat", {NULL}, 3449, "udp"}, {"castorproxy", {NULL}, 3450, "tcp"}, {"castorproxy", {NULL}, 3450, "udp"}, {"asam", {NULL}, 3451, "tcp"}, {"asam", {NULL}, 3451, "udp"}, {"sabp-signal", {NULL}, 3452, "tcp"}, {"sabp-signal", {NULL}, 3452, "udp"}, {"pscupd", {NULL}, 3453, "tcp"}, {"pscupd", {NULL}, 3453, "udp"}, {"mira", {NULL}, 3454, "tcp"}, {"prsvp", {NULL}, 3455, "tcp"}, {"prsvp", {NULL}, 3455, "udp"}, {"vat", {NULL}, 3456, "tcp"}, {"vat", {NULL}, 3456, "udp"}, {"vat-control", {NULL}, 3457, "tcp"}, {"vat-control", {NULL}, 3457, "udp"}, {"d3winosfi", {NULL}, 3458, "tcp"}, {"d3winosfi", {NULL}, 3458, "udp"}, {"integral", {NULL}, 3459, "tcp"}, {"integral", {NULL}, 3459, "udp"}, {"edm-manager", {NULL}, 3460, "tcp"}, {"edm-manager", {NULL}, 3460, "udp"}, {"edm-stager", {NULL}, 3461, "tcp"}, {"edm-stager", {NULL}, 3461, "udp"}, {"edm-std-notify", {NULL}, 3462, "tcp"}, {"edm-std-notify", {NULL}, 3462, "udp"}, {"edm-adm-notify", {NULL}, 3463, "tcp"}, {"edm-adm-notify", {NULL}, 3463, "udp"}, {"edm-mgr-sync", {NULL}, 3464, "tcp"}, {"edm-mgr-sync", {NULL}, 3464, "udp"}, {"edm-mgr-cntrl", {NULL}, 3465, "tcp"}, {"edm-mgr-cntrl", {NULL}, 3465, "udp"}, {"workflow", {NULL}, 3466, "tcp"}, {"workflow", {NULL}, 3466, "udp"}, {"rcst", {NULL}, 3467, "tcp"}, {"rcst", {NULL}, 3467, "udp"}, {"ttcmremotectrl", {NULL}, 3468, "tcp"}, {"ttcmremotectrl", {NULL}, 3468, "udp"}, {"pluribus", {NULL}, 3469, "tcp"}, {"pluribus", {NULL}, 3469, "udp"}, {"jt400", {NULL}, 3470, "tcp"}, {"jt400", {NULL}, 3470, "udp"}, {"jt400-ssl", {NULL}, 3471, "tcp"}, {"jt400-ssl", {NULL}, 3471, "udp"}, {"jaugsremotec-1", {NULL}, 3472, "tcp"}, {"jaugsremotec-1", {NULL}, 3472, "udp"}, {"jaugsremotec-2", {NULL}, 3473, "tcp"}, {"jaugsremotec-2", {NULL}, 3473, "udp"}, {"ttntspauto", {NULL}, 3474, "tcp"}, {"ttntspauto", {NULL}, 3474, "udp"}, {"genisar-port", {NULL}, 3475, "tcp"}, {"genisar-port", {NULL}, 3475, "udp"}, {"nppmp", {NULL}, 3476, "tcp"}, {"nppmp", {NULL}, 3476, "udp"}, {"ecomm", {NULL}, 3477, "tcp"}, {"ecomm", {NULL}, 3477, "udp"}, {"stun", {NULL}, 3478, "tcp"}, {"stun", {NULL}, 3478, "udp"}, {"turn", {NULL}, 3478, "tcp"}, {"turn", {NULL}, 3478, "udp"}, {"stun-behavior", {NULL}, 3478, "tcp"}, {"stun-behavior", {NULL}, 3478, "udp"}, {"twrpc", {NULL}, 3479, "tcp"}, {"twrpc", {NULL}, 3479, "udp"}, {"plethora", {NULL}, 3480, "tcp"}, {"plethora", {NULL}, 3480, "udp"}, {"cleanerliverc", {NULL}, 3481, "tcp"}, {"cleanerliverc", {NULL}, 3481, "udp"}, {"vulture", {NULL}, 3482, "tcp"}, {"vulture", {NULL}, 3482, "udp"}, {"slim-devices", {NULL}, 3483, "tcp"}, {"slim-devices", {NULL}, 3483, "udp"}, {"gbs-stp", {NULL}, 3484, "tcp"}, {"gbs-stp", {NULL}, 3484, "udp"}, {"celatalk", {NULL}, 3485, "tcp"}, {"celatalk", {NULL}, 3485, "udp"}, {"ifsf-hb-port", {NULL}, 3486, "tcp"}, {"ifsf-hb-port", {NULL}, 3486, "udp"}, {"ltctcp", {NULL}, 3487, "tcp"}, {"ltcudp", {NULL}, 3487, "udp"}, {"fs-rh-srv", {NULL}, 3488, "tcp"}, {"fs-rh-srv", {NULL}, 3488, "udp"}, {"dtp-dia", {NULL}, 3489, "tcp"}, {"dtp-dia", {NULL}, 3489, "udp"}, {"colubris", {NULL}, 3490, "tcp"}, {"colubris", {NULL}, 3490, "udp"}, {"swr-port", {NULL}, 3491, "tcp"}, {"swr-port", {NULL}, 3491, "udp"}, {"tvdumtray-port", {NULL}, 3492, "tcp"}, {"tvdumtray-port", {NULL}, 3492, "udp"}, {"nut", {NULL}, 3493, "tcp"}, {"nut", {NULL}, 3493, "udp"}, {"ibm3494", {NULL}, 3494, "tcp"}, {"ibm3494", {NULL}, 3494, "udp"}, {"seclayer-tcp", {NULL}, 3495, "tcp"}, {"seclayer-tcp", {NULL}, 3495, "udp"}, {"seclayer-tls", {NULL}, 3496, "tcp"}, {"seclayer-tls", {NULL}, 3496, "udp"}, {"ipether232port", {NULL}, 3497, "tcp"}, {"ipether232port", {NULL}, 3497, "udp"}, {"dashpas-port", {NULL}, 3498, "tcp"}, {"dashpas-port", {NULL}, 3498, "udp"}, {"sccip-media", {NULL}, 3499, "tcp"}, {"sccip-media", {NULL}, 3499, "udp"}, {"rtmp-port", {NULL}, 3500, "tcp"}, {"rtmp-port", {NULL}, 3500, "udp"}, {"isoft-p2p", {NULL}, 3501, "tcp"}, {"isoft-p2p", {NULL}, 3501, "udp"}, {"avinstalldisc", {NULL}, 3502, "tcp"}, {"avinstalldisc", {NULL}, 3502, "udp"}, {"lsp-ping", {NULL}, 3503, "tcp"}, {"lsp-ping", {NULL}, 3503, "udp"}, {"ironstorm", {NULL}, 3504, "tcp"}, {"ironstorm", {NULL}, 3504, "udp"}, {"ccmcomm", {NULL}, 3505, "tcp"}, {"ccmcomm", {NULL}, 3505, "udp"}, {"apc-3506", {NULL}, 3506, "tcp"}, {"apc-3506", {NULL}, 3506, "udp"}, {"nesh-broker", {NULL}, 3507, "tcp"}, {"nesh-broker", {NULL}, 3507, "udp"}, {"interactionweb", {NULL}, 3508, "tcp"}, {"interactionweb", {NULL}, 3508, "udp"}, {"vt-ssl", {NULL}, 3509, "tcp"}, {"vt-ssl", {NULL}, 3509, "udp"}, {"xss-port", {NULL}, 3510, "tcp"}, {"xss-port", {NULL}, 3510, "udp"}, {"webmail-2", {NULL}, 3511, "tcp"}, {"webmail-2", {NULL}, 3511, "udp"}, {"aztec", {NULL}, 3512, "tcp"}, {"aztec", {NULL}, 3512, "udp"}, {"arcpd", {NULL}, 3513, "tcp"}, {"arcpd", {NULL}, 3513, "udp"}, {"must-p2p", {NULL}, 3514, "tcp"}, {"must-p2p", {NULL}, 3514, "udp"}, {"must-backplane", {NULL}, 3515, "tcp"}, {"must-backplane", {NULL}, 3515, "udp"}, {"smartcard-port", {NULL}, 3516, "tcp"}, {"smartcard-port", {NULL}, 3516, "udp"}, {"802-11-iapp", {NULL}, 3517, "tcp"}, {"802-11-iapp", {NULL}, 3517, "udp"}, {"artifact-msg", {NULL}, 3518, "tcp"}, {"artifact-msg", {NULL}, 3518, "udp"}, {"nvmsgd", {NULL}, 3519, "tcp"}, {"galileo", {NULL}, 3519, "udp"}, {"galileolog", {NULL}, 3520, "tcp"}, {"galileolog", {NULL}, 3520, "udp"}, {"mc3ss", {NULL}, 3521, "tcp"}, {"mc3ss", {NULL}, 3521, "udp"}, {"nssocketport", {NULL}, 3522, "tcp"}, {"nssocketport", {NULL}, 3522, "udp"}, {"odeumservlink", {NULL}, 3523, "tcp"}, {"odeumservlink", {NULL}, 3523, "udp"}, {"ecmport", {NULL}, 3524, "tcp"}, {"ecmport", {NULL}, 3524, "udp"}, {"eisport", {NULL}, 3525, "tcp"}, {"eisport", {NULL}, 3525, "udp"}, {"starquiz-port", {NULL}, 3526, "tcp"}, {"starquiz-port", {NULL}, 3526, "udp"}, {"beserver-msg-q", {NULL}, 3527, "tcp"}, {"beserver-msg-q", {NULL}, 3527, "udp"}, {"jboss-iiop", {NULL}, 3528, "tcp"}, {"jboss-iiop", {NULL}, 3528, "udp"}, {"jboss-iiop-ssl", {NULL}, 3529, "tcp"}, {"jboss-iiop-ssl", {NULL}, 3529, "udp"}, {"gf", {NULL}, 3530, "tcp"}, {"gf", {NULL}, 3530, "udp"}, {"joltid", {NULL}, 3531, "tcp"}, {"joltid", {NULL}, 3531, "udp"}, {"raven-rmp", {NULL}, 3532, "tcp"}, {"raven-rmp", {NULL}, 3532, "udp"}, {"raven-rdp", {NULL}, 3533, "tcp"}, {"raven-rdp", {NULL}, 3533, "udp"}, {"urld-port", {NULL}, 3534, "tcp"}, {"urld-port", {NULL}, 3534, "udp"}, {"ms-la", {NULL}, 3535, "tcp"}, {"ms-la", {NULL}, 3535, "udp"}, {"snac", {NULL}, 3536, "tcp"}, {"snac", {NULL}, 3536, "udp"}, {"ni-visa-remote", {NULL}, 3537, "tcp"}, {"ni-visa-remote", {NULL}, 3537, "udp"}, {"ibm-diradm", {NULL}, 3538, "tcp"}, {"ibm-diradm", {NULL}, 3538, "udp"}, {"ibm-diradm-ssl", {NULL}, 3539, "tcp"}, {"ibm-diradm-ssl", {NULL}, 3539, "udp"}, {"pnrp-port", {NULL}, 3540, "tcp"}, {"pnrp-port", {NULL}, 3540, "udp"}, {"voispeed-port", {NULL}, 3541, "tcp"}, {"voispeed-port", {NULL}, 3541, "udp"}, {"hacl-monitor", {NULL}, 3542, "tcp"}, {"hacl-monitor", {NULL}, 3542, "udp"}, {"qftest-lookup", {NULL}, 3543, "tcp"}, {"qftest-lookup", {NULL}, 3543, "udp"}, {"teredo", {NULL}, 3544, "tcp"}, {"teredo", {NULL}, 3544, "udp"}, {"camac", {NULL}, 3545, "tcp"}, {"camac", {NULL}, 3545, "udp"}, {"symantec-sim", {NULL}, 3547, "tcp"}, {"symantec-sim", {NULL}, 3547, "udp"}, {"interworld", {NULL}, 3548, "tcp"}, {"interworld", {NULL}, 3548, "udp"}, {"tellumat-nms", {NULL}, 3549, "tcp"}, {"tellumat-nms", {NULL}, 3549, "udp"}, {"ssmpp", {NULL}, 3550, "tcp"}, {"ssmpp", {NULL}, 3550, "udp"}, {"apcupsd", {NULL}, 3551, "tcp"}, {"apcupsd", {NULL}, 3551, "udp"}, {"taserver", {NULL}, 3552, "tcp"}, {"taserver", {NULL}, 3552, "udp"}, {"rbr-discovery", {NULL}, 3553, "tcp"}, {"rbr-discovery", {NULL}, 3553, "udp"}, {"questnotify", {NULL}, 3554, "tcp"}, {"questnotify", {NULL}, 3554, "udp"}, {"razor", {NULL}, 3555, "tcp"}, {"razor", {NULL}, 3555, "udp"}, {"sky-transport", {NULL}, 3556, "tcp"}, {"sky-transport", {NULL}, 3556, "udp"}, {"personalos-001", {NULL}, 3557, "tcp"}, {"personalos-001", {NULL}, 3557, "udp"}, {"mcp-port", {NULL}, 3558, "tcp"}, {"mcp-port", {NULL}, 3558, "udp"}, {"cctv-port", {NULL}, 3559, "tcp"}, {"cctv-port", {NULL}, 3559, "udp"}, {"iniserve-port", {NULL}, 3560, "tcp"}, {"iniserve-port", {NULL}, 3560, "udp"}, {"bmc-onekey", {NULL}, 3561, "tcp"}, {"bmc-onekey", {NULL}, 3561, "udp"}, {"sdbproxy", {NULL}, 3562, "tcp"}, {"sdbproxy", {NULL}, 3562, "udp"}, {"watcomdebug", {NULL}, 3563, "tcp"}, {"watcomdebug", {NULL}, 3563, "udp"}, {"esimport", {NULL}, 3564, "tcp"}, {"esimport", {NULL}, 3564, "udp"}, {"m2pa", {NULL}, 3565, "tcp"}, {"m2pa", {NULL}, 3565, "sctp"}, {"quest-data-hub", {NULL}, 3566, "tcp"}, {"oap", {NULL}, 3567, "tcp"}, {"oap", {NULL}, 3567, "udp"}, {"oap-s", {NULL}, 3568, "tcp"}, {"oap-s", {NULL}, 3568, "udp"}, {"mbg-ctrl", {NULL}, 3569, "tcp"}, {"mbg-ctrl", {NULL}, 3569, "udp"}, {"mccwebsvr-port", {NULL}, 3570, "tcp"}, {"mccwebsvr-port", {NULL}, 3570, "udp"}, {"megardsvr-port", {NULL}, 3571, "tcp"}, {"megardsvr-port", {NULL}, 3571, "udp"}, {"megaregsvrport", {NULL}, 3572, "tcp"}, {"megaregsvrport", {NULL}, 3572, "udp"}, {"tag-ups-1", {NULL}, 3573, "tcp"}, {"tag-ups-1", {NULL}, 3573, "udp"}, {"dmaf-server", {NULL}, 3574, "tcp"}, {"dmaf-caster", {NULL}, 3574, "udp"}, {"ccm-port", {NULL}, 3575, "tcp"}, {"ccm-port", {NULL}, 3575, "udp"}, {"cmc-port", {NULL}, 3576, "tcp"}, {"cmc-port", {NULL}, 3576, "udp"}, {"config-port", {NULL}, 3577, "tcp"}, {"config-port", {NULL}, 3577, "udp"}, {"data-port", {NULL}, 3578, "tcp"}, {"data-port", {NULL}, 3578, "udp"}, {"ttat3lb", {NULL}, 3579, "tcp"}, {"ttat3lb", {NULL}, 3579, "udp"}, {"nati-svrloc", {NULL}, 3580, "tcp"}, {"nati-svrloc", {NULL}, 3580, "udp"}, {"kfxaclicensing", {NULL}, 3581, "tcp"}, {"kfxaclicensing", {NULL}, 3581, "udp"}, {"press", {NULL}, 3582, "tcp"}, {"press", {NULL}, 3582, "udp"}, {"canex-watch", {NULL}, 3583, "tcp"}, {"canex-watch", {NULL}, 3583, "udp"}, {"u-dbap", {NULL}, 3584, "tcp"}, {"u-dbap", {NULL}, 3584, "udp"}, {"emprise-lls", {NULL}, 3585, "tcp"}, {"emprise-lls", {NULL}, 3585, "udp"}, {"emprise-lsc", {NULL}, 3586, "tcp"}, {"emprise-lsc", {NULL}, 3586, "udp"}, {"p2pgroup", {NULL}, 3587, "tcp"}, {"p2pgroup", {NULL}, 3587, "udp"}, {"sentinel", {NULL}, 3588, "tcp"}, {"sentinel", {NULL}, 3588, "udp"}, {"isomair", {NULL}, 3589, "tcp"}, {"isomair", {NULL}, 3589, "udp"}, {"wv-csp-sms", {NULL}, 3590, "tcp"}, {"wv-csp-sms", {NULL}, 3590, "udp"}, {"gtrack-server", {NULL}, 3591, "tcp"}, {"gtrack-server", {NULL}, 3591, "udp"}, {"gtrack-ne", {NULL}, 3592, "tcp"}, {"gtrack-ne", {NULL}, 3592, "udp"}, {"bpmd", {NULL}, 3593, "tcp"}, {"bpmd", {NULL}, 3593, "udp"}, {"mediaspace", {NULL}, 3594, "tcp"}, {"mediaspace", {NULL}, 3594, "udp"}, {"shareapp", {NULL}, 3595, "tcp"}, {"shareapp", {NULL}, 3595, "udp"}, {"iw-mmogame", {NULL}, 3596, "tcp"}, {"iw-mmogame", {NULL}, 3596, "udp"}, {"a14", {NULL}, 3597, "tcp"}, {"a14", {NULL}, 3597, "udp"}, {"a15", {NULL}, 3598, "tcp"}, {"a15", {NULL}, 3598, "udp"}, {"quasar-server", {NULL}, 3599, "tcp"}, {"quasar-server", {NULL}, 3599, "udp"}, {"trap-daemon", {NULL}, 3600, "tcp"}, {"trap-daemon", {NULL}, 3600, "udp"}, {"visinet-gui", {NULL}, 3601, "tcp"}, {"visinet-gui", {NULL}, 3601, "udp"}, {"infiniswitchcl", {NULL}, 3602, "tcp"}, {"infiniswitchcl", {NULL}, 3602, "udp"}, {"int-rcv-cntrl", {NULL}, 3603, "tcp"}, {"int-rcv-cntrl", {NULL}, 3603, "udp"}, {"bmc-jmx-port", {NULL}, 3604, "tcp"}, {"bmc-jmx-port", {NULL}, 3604, "udp"}, {"comcam-io", {NULL}, 3605, "tcp"}, {"comcam-io", {NULL}, 3605, "udp"}, {"splitlock", {NULL}, 3606, "tcp"}, {"splitlock", {NULL}, 3606, "udp"}, {"precise-i3", {NULL}, 3607, "tcp"}, {"precise-i3", {NULL}, 3607, "udp"}, {"trendchip-dcp", {NULL}, 3608, "tcp"}, {"trendchip-dcp", {NULL}, 3608, "udp"}, {"cpdi-pidas-cm", {NULL}, 3609, "tcp"}, {"cpdi-pidas-cm", {NULL}, 3609, "udp"}, {"echonet", {NULL}, 3610, "tcp"}, {"echonet", {NULL}, 3610, "udp"}, {"six-degrees", {NULL}, 3611, "tcp"}, {"six-degrees", {NULL}, 3611, "udp"}, {"hp-dataprotect", {NULL}, 3612, "tcp"}, {"hp-dataprotect", {NULL}, 3612, "udp"}, {"alaris-disc", {NULL}, 3613, "tcp"}, {"alaris-disc", {NULL}, 3613, "udp"}, {"sigma-port", {NULL}, 3614, "tcp"}, {"sigma-port", {NULL}, 3614, "udp"}, {"start-network", {NULL}, 3615, "tcp"}, {"start-network", {NULL}, 3615, "udp"}, {"cd3o-protocol", {NULL}, 3616, "tcp"}, {"cd3o-protocol", {NULL}, 3616, "udp"}, {"sharp-server", {NULL}, 3617, "tcp"}, {"sharp-server", {NULL}, 3617, "udp"}, {"aairnet-1", {NULL}, 3618, "tcp"}, {"aairnet-1", {NULL}, 3618, "udp"}, {"aairnet-2", {NULL}, 3619, "tcp"}, {"aairnet-2", {NULL}, 3619, "udp"}, {"ep-pcp", {NULL}, 3620, "tcp"}, {"ep-pcp", {NULL}, 3620, "udp"}, {"ep-nsp", {NULL}, 3621, "tcp"}, {"ep-nsp", {NULL}, 3621, "udp"}, {"ff-lr-port", {NULL}, 3622, "tcp"}, {"ff-lr-port", {NULL}, 3622, "udp"}, {"haipe-discover", {NULL}, 3623, "tcp"}, {"haipe-discover", {NULL}, 3623, "udp"}, {"dist-upgrade", {NULL}, 3624, "tcp"}, {"dist-upgrade", {NULL}, 3624, "udp"}, {"volley", {NULL}, 3625, "tcp"}, {"volley", {NULL}, 3625, "udp"}, {"bvcdaemon-port", {NULL}, 3626, "tcp"}, {"bvcdaemon-port", {NULL}, 3626, "udp"}, {"jamserverport", {NULL}, 3627, "tcp"}, {"jamserverport", {NULL}, 3627, "udp"}, {"ept-machine", {NULL}, 3628, "tcp"}, {"ept-machine", {NULL}, 3628, "udp"}, {"escvpnet", {NULL}, 3629, "tcp"}, {"escvpnet", {NULL}, 3629, "udp"}, {"cs-remote-db", {NULL}, 3630, "tcp"}, {"cs-remote-db", {NULL}, 3630, "udp"}, {"cs-services", {NULL}, 3631, "tcp"}, {"cs-services", {NULL}, 3631, "udp"}, {"distcc", {NULL}, 3632, "tcp"}, {"distcc", {NULL}, 3632, "udp"}, {"wacp", {NULL}, 3633, "tcp"}, {"wacp", {NULL}, 3633, "udp"}, {"hlibmgr", {NULL}, 3634, "tcp"}, {"hlibmgr", {NULL}, 3634, "udp"}, {"sdo", {NULL}, 3635, "tcp"}, {"sdo", {NULL}, 3635, "udp"}, {"servistaitsm", {NULL}, 3636, "tcp"}, {"servistaitsm", {NULL}, 3636, "udp"}, {"scservp", {NULL}, 3637, "tcp"}, {"scservp", {NULL}, 3637, "udp"}, {"ehp-backup", {NULL}, 3638, "tcp"}, {"ehp-backup", {NULL}, 3638, "udp"}, {"xap-ha", {NULL}, 3639, "tcp"}, {"xap-ha", {NULL}, 3639, "udp"}, {"netplay-port1", {NULL}, 3640, "tcp"}, {"netplay-port1", {NULL}, 3640, "udp"}, {"netplay-port2", {NULL}, 3641, "tcp"}, {"netplay-port2", {NULL}, 3641, "udp"}, {"juxml-port", {NULL}, 3642, "tcp"}, {"juxml-port", {NULL}, 3642, "udp"}, {"audiojuggler", {NULL}, 3643, "tcp"}, {"audiojuggler", {NULL}, 3643, "udp"}, {"ssowatch", {NULL}, 3644, "tcp"}, {"ssowatch", {NULL}, 3644, "udp"}, {"cyc", {NULL}, 3645, "tcp"}, {"cyc", {NULL}, 3645, "udp"}, {"xss-srv-port", {NULL}, 3646, "tcp"}, {"xss-srv-port", {NULL}, 3646, "udp"}, {"splitlock-gw", {NULL}, 3647, "tcp"}, {"splitlock-gw", {NULL}, 3647, "udp"}, {"fjcp", {NULL}, 3648, "tcp"}, {"fjcp", {NULL}, 3648, "udp"}, {"nmmp", {NULL}, 3649, "tcp"}, {"nmmp", {NULL}, 3649, "udp"}, {"prismiq-plugin", {NULL}, 3650, "tcp"}, {"prismiq-plugin", {NULL}, 3650, "udp"}, {"xrpc-registry", {NULL}, 3651, "tcp"}, {"xrpc-registry", {NULL}, 3651, "udp"}, {"vxcrnbuport", {NULL}, 3652, "tcp"}, {"vxcrnbuport", {NULL}, 3652, "udp"}, {"tsp", {NULL}, 3653, "tcp"}, {"tsp", {NULL}, 3653, "udp"}, {"vaprtm", {NULL}, 3654, "tcp"}, {"vaprtm", {NULL}, 3654, "udp"}, {"abatemgr", {NULL}, 3655, "tcp"}, {"abatemgr", {NULL}, 3655, "udp"}, {"abatjss", {NULL}, 3656, "tcp"}, {"abatjss", {NULL}, 3656, "udp"}, {"immedianet-bcn", {NULL}, 3657, "tcp"}, {"immedianet-bcn", {NULL}, 3657, "udp"}, {"ps-ams", {NULL}, 3658, "tcp"}, {"ps-ams", {NULL}, 3658, "udp"}, {"apple-sasl", {NULL}, 3659, "tcp"}, {"apple-sasl", {NULL}, 3659, "udp"}, {"can-nds-ssl", {NULL}, 3660, "tcp"}, {"can-nds-ssl", {NULL}, 3660, "udp"}, {"can-ferret-ssl", {NULL}, 3661, "tcp"}, {"can-ferret-ssl", {NULL}, 3661, "udp"}, {"pserver", {NULL}, 3662, "tcp"}, {"pserver", {NULL}, 3662, "udp"}, {"dtp", {NULL}, 3663, "tcp"}, {"dtp", {NULL}, 3663, "udp"}, {"ups-engine", {NULL}, 3664, "tcp"}, {"ups-engine", {NULL}, 3664, "udp"}, {"ent-engine", {NULL}, 3665, "tcp"}, {"ent-engine", {NULL}, 3665, "udp"}, {"eserver-pap", {NULL}, 3666, "tcp"}, {"eserver-pap", {NULL}, 3666, "udp"}, {"infoexch", {NULL}, 3667, "tcp"}, {"infoexch", {NULL}, 3667, "udp"}, {"dell-rm-port", {NULL}, 3668, "tcp"}, {"dell-rm-port", {NULL}, 3668, "udp"}, {"casanswmgmt", {NULL}, 3669, "tcp"}, {"casanswmgmt", {NULL}, 3669, "udp"}, {"smile", {NULL}, 3670, "tcp"}, {"smile", {NULL}, 3670, "udp"}, {"efcp", {NULL}, 3671, "tcp"}, {"efcp", {NULL}, 3671, "udp"}, {"lispworks-orb", {NULL}, 3672, "tcp"}, {"lispworks-orb", {NULL}, 3672, "udp"}, {"mediavault-gui", {NULL}, 3673, "tcp"}, {"mediavault-gui", {NULL}, 3673, "udp"}, {"wininstall-ipc", {NULL}, 3674, "tcp"}, {"wininstall-ipc", {NULL}, 3674, "udp"}, {"calltrax", {NULL}, 3675, "tcp"}, {"calltrax", {NULL}, 3675, "udp"}, {"va-pacbase", {NULL}, 3676, "tcp"}, {"va-pacbase", {NULL}, 3676, "udp"}, {"roverlog", {NULL}, 3677, "tcp"}, {"roverlog", {NULL}, 3677, "udp"}, {"ipr-dglt", {NULL}, 3678, "tcp"}, {"ipr-dglt", {NULL}, 3678, "udp"}, {"newton-dock", {NULL}, 3679, "tcp"}, {"newton-dock", {NULL}, 3679, "udp"}, {"npds-tracker", {NULL}, 3680, "tcp"}, {"npds-tracker", {NULL}, 3680, "udp"}, {"bts-x73", {NULL}, 3681, "tcp"}, {"bts-x73", {NULL}, 3681, "udp"}, {"cas-mapi", {NULL}, 3682, "tcp"}, {"cas-mapi", {NULL}, 3682, "udp"}, {"bmc-ea", {NULL}, 3683, "tcp"}, {"bmc-ea", {NULL}, 3683, "udp"}, {"faxstfx-port", {NULL}, 3684, "tcp"}, {"faxstfx-port", {NULL}, 3684, "udp"}, {"dsx-agent", {NULL}, 3685, "tcp"}, {"dsx-agent", {NULL}, 3685, "udp"}, {"tnmpv2", {NULL}, 3686, "tcp"}, {"tnmpv2", {NULL}, 3686, "udp"}, {"simple-push", {NULL}, 3687, "tcp"}, {"simple-push", {NULL}, 3687, "udp"}, {"simple-push-s", {NULL}, 3688, "tcp"}, {"simple-push-s", {NULL}, 3688, "udp"}, {"daap", {NULL}, 3689, "tcp"}, {"daap", {NULL}, 3689, "udp"}, {"svn", {NULL}, 3690, "tcp"}, {"svn", {NULL}, 3690, "udp"}, {"magaya-network", {NULL}, 3691, "tcp"}, {"magaya-network", {NULL}, 3691, "udp"}, {"intelsync", {NULL}, 3692, "tcp"}, {"intelsync", {NULL}, 3692, "udp"}, {"bmc-data-coll", {NULL}, 3695, "tcp"}, {"bmc-data-coll", {NULL}, 3695, "udp"}, {"telnetcpcd", {NULL}, 3696, "tcp"}, {"telnetcpcd", {NULL}, 3696, "udp"}, {"nw-license", {NULL}, 3697, "tcp"}, {"nw-license", {NULL}, 3697, "udp"}, {"sagectlpanel", {NULL}, 3698, "tcp"}, {"sagectlpanel", {NULL}, 3698, "udp"}, {"kpn-icw", {NULL}, 3699, "tcp"}, {"kpn-icw", {NULL}, 3699, "udp"}, {"lrs-paging", {NULL}, 3700, "tcp"}, {"lrs-paging", {NULL}, 3700, "udp"}, {"netcelera", {NULL}, 3701, "tcp"}, {"netcelera", {NULL}, 3701, "udp"}, {"ws-discovery", {NULL}, 3702, "tcp"}, {"ws-discovery", {NULL}, 3702, "udp"}, {"adobeserver-3", {NULL}, 3703, "tcp"}, {"adobeserver-3", {NULL}, 3703, "udp"}, {"adobeserver-4", {NULL}, 3704, "tcp"}, {"adobeserver-4", {NULL}, 3704, "udp"}, {"adobeserver-5", {NULL}, 3705, "tcp"}, {"adobeserver-5", {NULL}, 3705, "udp"}, {"rt-event", {NULL}, 3706, "tcp"}, {"rt-event", {NULL}, 3706, "udp"}, {"rt-event-s", {NULL}, 3707, "tcp"}, {"rt-event-s", {NULL}, 3707, "udp"}, {"sun-as-iiops", {NULL}, 3708, "tcp"}, {"sun-as-iiops", {NULL}, 3708, "udp"}, {"ca-idms", {NULL}, 3709, "tcp"}, {"ca-idms", {NULL}, 3709, "udp"}, {"portgate-auth", {NULL}, 3710, "tcp"}, {"portgate-auth", {NULL}, 3710, "udp"}, {"edb-server2", {NULL}, 3711, "tcp"}, {"edb-server2", {NULL}, 3711, "udp"}, {"sentinel-ent", {NULL}, 3712, "tcp"}, {"sentinel-ent", {NULL}, 3712, "udp"}, {"tftps", {NULL}, 3713, "tcp"}, {"tftps", {NULL}, 3713, "udp"}, {"delos-dms", {NULL}, 3714, "tcp"}, {"delos-dms", {NULL}, 3714, "udp"}, {"anoto-rendezv", {NULL}, 3715, "tcp"}, {"anoto-rendezv", {NULL}, 3715, "udp"}, {"wv-csp-sms-cir", {NULL}, 3716, "tcp"}, {"wv-csp-sms-cir", {NULL}, 3716, "udp"}, {"wv-csp-udp-cir", {NULL}, 3717, "tcp"}, {"wv-csp-udp-cir", {NULL}, 3717, "udp"}, {"opus-services", {NULL}, 3718, "tcp"}, {"opus-services", {NULL}, 3718, "udp"}, {"itelserverport", {NULL}, 3719, "tcp"}, {"itelserverport", {NULL}, 3719, "udp"}, {"ufastro-instr", {NULL}, 3720, "tcp"}, {"ufastro-instr", {NULL}, 3720, "udp"}, {"xsync", {NULL}, 3721, "tcp"}, {"xsync", {NULL}, 3721, "udp"}, {"xserveraid", {NULL}, 3722, "tcp"}, {"xserveraid", {NULL}, 3722, "udp"}, {"sychrond", {NULL}, 3723, "tcp"}, {"sychrond", {NULL}, 3723, "udp"}, {"blizwow", {NULL}, 3724, "tcp"}, {"blizwow", {NULL}, 3724, "udp"}, {"na-er-tip", {NULL}, 3725, "tcp"}, {"na-er-tip", {NULL}, 3725, "udp"}, {"array-manager", {NULL}, 3726, "tcp"}, {"array-manager", {NULL}, 3726, "udp"}, {"e-mdu", {NULL}, 3727, "tcp"}, {"e-mdu", {NULL}, 3727, "udp"}, {"e-woa", {NULL}, 3728, "tcp"}, {"e-woa", {NULL}, 3728, "udp"}, {"fksp-audit", {NULL}, 3729, "tcp"}, {"fksp-audit", {NULL}, 3729, "udp"}, {"client-ctrl", {NULL}, 3730, "tcp"}, {"client-ctrl", {NULL}, 3730, "udp"}, {"smap", {NULL}, 3731, "tcp"}, {"smap", {NULL}, 3731, "udp"}, {"m-wnn", {NULL}, 3732, "tcp"}, {"m-wnn", {NULL}, 3732, "udp"}, {"multip-msg", {NULL}, 3733, "tcp"}, {"multip-msg", {NULL}, 3733, "udp"}, {"synel-data", {NULL}, 3734, "tcp"}, {"synel-data", {NULL}, 3734, "udp"}, {"pwdis", {NULL}, 3735, "tcp"}, {"pwdis", {NULL}, 3735, "udp"}, {"rs-rmi", {NULL}, 3736, "tcp"}, {"rs-rmi", {NULL}, 3736, "udp"}, {"xpanel", {NULL}, 3737, "tcp"}, {"versatalk", {NULL}, 3738, "tcp"}, {"versatalk", {NULL}, 3738, "udp"}, {"launchbird-lm", {NULL}, 3739, "tcp"}, {"launchbird-lm", {NULL}, 3739, "udp"}, {"heartbeat", {NULL}, 3740, "tcp"}, {"heartbeat", {NULL}, 3740, "udp"}, {"wysdma", {NULL}, 3741, "tcp"}, {"wysdma", {NULL}, 3741, "udp"}, {"cst-port", {NULL}, 3742, "tcp"}, {"cst-port", {NULL}, 3742, "udp"}, {"ipcs-command", {NULL}, 3743, "tcp"}, {"ipcs-command", {NULL}, 3743, "udp"}, {"sasg", {NULL}, 3744, "tcp"}, {"sasg", {NULL}, 3744, "udp"}, {"gw-call-port", {NULL}, 3745, "tcp"}, {"gw-call-port", {NULL}, 3745, "udp"}, {"linktest", {NULL}, 3746, "tcp"}, {"linktest", {NULL}, 3746, "udp"}, {"linktest-s", {NULL}, 3747, "tcp"}, {"linktest-s", {NULL}, 3747, "udp"}, {"webdata", {NULL}, 3748, "tcp"}, {"webdata", {NULL}, 3748, "udp"}, {"cimtrak", {NULL}, 3749, "tcp"}, {"cimtrak", {NULL}, 3749, "udp"}, {"cbos-ip-port", {NULL}, 3750, "tcp"}, {"cbos-ip-port", {NULL}, 3750, "udp"}, {"gprs-cube", {NULL}, 3751, "tcp"}, {"gprs-cube", {NULL}, 3751, "udp"}, {"vipremoteagent", {NULL}, 3752, "tcp"}, {"vipremoteagent", {NULL}, 3752, "udp"}, {"nattyserver", {NULL}, 3753, "tcp"}, {"nattyserver", {NULL}, 3753, "udp"}, {"timestenbroker", {NULL}, 3754, "tcp"}, {"timestenbroker", {NULL}, 3754, "udp"}, {"sas-remote-hlp", {NULL}, 3755, "tcp"}, {"sas-remote-hlp", {NULL}, 3755, "udp"}, {"canon-capt", {NULL}, 3756, "tcp"}, {"canon-capt", {NULL}, 3756, "udp"}, {"grf-port", {NULL}, 3757, "tcp"}, {"grf-port", {NULL}, 3757, "udp"}, {"apw-registry", {NULL}, 3758, "tcp"}, {"apw-registry", {NULL}, 3758, "udp"}, {"exapt-lmgr", {NULL}, 3759, "tcp"}, {"exapt-lmgr", {NULL}, 3759, "udp"}, {"adtempusclient", {NULL}, 3760, "tcp"}, {"adtempusclient", {NULL}, 3760, "udp"}, {"gsakmp", {NULL}, 3761, "tcp"}, {"gsakmp", {NULL}, 3761, "udp"}, {"gbs-smp", {NULL}, 3762, "tcp"}, {"gbs-smp", {NULL}, 3762, "udp"}, {"xo-wave", {NULL}, 3763, "tcp"}, {"xo-wave", {NULL}, 3763, "udp"}, {"mni-prot-rout", {NULL}, 3764, "tcp"}, {"mni-prot-rout", {NULL}, 3764, "udp"}, {"rtraceroute", {NULL}, 3765, "tcp"}, {"rtraceroute", {NULL}, 3765, "udp"}, {"listmgr-port", {NULL}, 3767, "tcp"}, {"listmgr-port", {NULL}, 3767, "udp"}, {"rblcheckd", {NULL}, 3768, "tcp"}, {"rblcheckd", {NULL}, 3768, "udp"}, {"haipe-otnk", {NULL}, 3769, "tcp"}, {"haipe-otnk", {NULL}, 3769, "udp"}, {"cindycollab", {NULL}, 3770, "tcp"}, {"cindycollab", {NULL}, 3770, "udp"}, {"paging-port", {NULL}, 3771, "tcp"}, {"paging-port", {NULL}, 3771, "udp"}, {"ctp", {NULL}, 3772, "tcp"}, {"ctp", {NULL}, 3772, "udp"}, {"ctdhercules", {NULL}, 3773, "tcp"}, {"ctdhercules", {NULL}, 3773, "udp"}, {"zicom", {NULL}, 3774, "tcp"}, {"zicom", {NULL}, 3774, "udp"}, {"ispmmgr", {NULL}, 3775, "tcp"}, {"ispmmgr", {NULL}, 3775, "udp"}, {"dvcprov-port", {NULL}, 3776, "tcp"}, {"dvcprov-port", {NULL}, 3776, "udp"}, {"jibe-eb", {NULL}, 3777, "tcp"}, {"jibe-eb", {NULL}, 3777, "udp"}, {"c-h-it-port", {NULL}, 3778, "tcp"}, {"c-h-it-port", {NULL}, 3778, "udp"}, {"cognima", {NULL}, 3779, "tcp"}, {"cognima", {NULL}, 3779, "udp"}, {"nnp", {NULL}, 3780, "tcp"}, {"nnp", {NULL}, 3780, "udp"}, {"abcvoice-port", {NULL}, 3781, "tcp"}, {"abcvoice-port", {NULL}, 3781, "udp"}, {"iso-tp0s", {NULL}, 3782, "tcp"}, {"iso-tp0s", {NULL}, 3782, "udp"}, {"bim-pem", {NULL}, 3783, "tcp"}, {"bim-pem", {NULL}, 3783, "udp"}, {"bfd-control", {NULL}, 3784, "tcp"}, {"bfd-control", {NULL}, 3784, "udp"}, {"bfd-echo", {NULL}, 3785, "tcp"}, {"bfd-echo", {NULL}, 3785, "udp"}, {"upstriggervsw", {NULL}, 3786, "tcp"}, {"upstriggervsw", {NULL}, 3786, "udp"}, {"fintrx", {NULL}, 3787, "tcp"}, {"fintrx", {NULL}, 3787, "udp"}, {"isrp-port", {NULL}, 3788, "tcp"}, {"isrp-port", {NULL}, 3788, "udp"}, {"remotedeploy", {NULL}, 3789, "tcp"}, {"remotedeploy", {NULL}, 3789, "udp"}, {"quickbooksrds", {NULL}, 3790, "tcp"}, {"quickbooksrds", {NULL}, 3790, "udp"}, {"tvnetworkvideo", {NULL}, 3791, "tcp"}, {"tvnetworkvideo", {NULL}, 3791, "udp"}, {"sitewatch", {NULL}, 3792, "tcp"}, {"sitewatch", {NULL}, 3792, "udp"}, {"dcsoftware", {NULL}, 3793, "tcp"}, {"dcsoftware", {NULL}, 3793, "udp"}, {"jaus", {NULL}, 3794, "tcp"}, {"jaus", {NULL}, 3794, "udp"}, {"myblast", {NULL}, 3795, "tcp"}, {"myblast", {NULL}, 3795, "udp"}, {"spw-dialer", {NULL}, 3796, "tcp"}, {"spw-dialer", {NULL}, 3796, "udp"}, {"idps", {NULL}, 3797, "tcp"}, {"idps", {NULL}, 3797, "udp"}, {"minilock", {NULL}, 3798, "tcp"}, {"minilock", {NULL}, 3798, "udp"}, {"radius-dynauth", {NULL}, 3799, "tcp"}, {"radius-dynauth", {NULL}, 3799, "udp"}, {"pwgpsi", {NULL}, 3800, "tcp"}, {"pwgpsi", {NULL}, 3800, "udp"}, {"ibm-mgr", {NULL}, 3801, "tcp"}, {"ibm-mgr", {NULL}, 3801, "udp"}, {"vhd", {NULL}, 3802, "tcp"}, {"vhd", {NULL}, 3802, "udp"}, {"soniqsync", {NULL}, 3803, "tcp"}, {"soniqsync", {NULL}, 3803, "udp"}, {"iqnet-port", {NULL}, 3804, "tcp"}, {"iqnet-port", {NULL}, 3804, "udp"}, {"tcpdataserver", {NULL}, 3805, "tcp"}, {"tcpdataserver", {NULL}, 3805, "udp"}, {"wsmlb", {NULL}, 3806, "tcp"}, {"wsmlb", {NULL}, 3806, "udp"}, {"spugna", {NULL}, 3807, "tcp"}, {"spugna", {NULL}, 3807, "udp"}, {"sun-as-iiops-ca", {NULL}, 3808, "tcp"}, {"sun-as-iiops-ca", {NULL}, 3808, "udp"}, {"apocd", {NULL}, 3809, "tcp"}, {"apocd", {NULL}, 3809, "udp"}, {"wlanauth", {NULL}, 3810, "tcp"}, {"wlanauth", {NULL}, 3810, "udp"}, {"amp", {NULL}, 3811, "tcp"}, {"amp", {NULL}, 3811, "udp"}, {"neto-wol-server", {NULL}, 3812, "tcp"}, {"neto-wol-server", {NULL}, 3812, "udp"}, {"rap-ip", {NULL}, 3813, "tcp"}, {"rap-ip", {NULL}, 3813, "udp"}, {"neto-dcs", {NULL}, 3814, "tcp"}, {"neto-dcs", {NULL}, 3814, "udp"}, {"lansurveyorxml", {NULL}, 3815, "tcp"}, {"lansurveyorxml", {NULL}, 3815, "udp"}, {"sunlps-http", {NULL}, 3816, "tcp"}, {"sunlps-http", {NULL}, 3816, "udp"}, {"tapeware", {NULL}, 3817, "tcp"}, {"tapeware", {NULL}, 3817, "udp"}, {"crinis-hb", {NULL}, 3818, "tcp"}, {"crinis-hb", {NULL}, 3818, "udp"}, {"epl-slp", {NULL}, 3819, "tcp"}, {"epl-slp", {NULL}, 3819, "udp"}, {"scp", {NULL}, 3820, "tcp"}, {"scp", {NULL}, 3820, "udp"}, {"pmcp", {NULL}, 3821, "tcp"}, {"pmcp", {NULL}, 3821, "udp"}, {"acp-discovery", {NULL}, 3822, "tcp"}, {"acp-discovery", {NULL}, 3822, "udp"}, {"acp-conduit", {NULL}, 3823, "tcp"}, {"acp-conduit", {NULL}, 3823, "udp"}, {"acp-policy", {NULL}, 3824, "tcp"}, {"acp-policy", {NULL}, 3824, "udp"}, {"ffserver", {NULL}, 3825, "tcp"}, {"ffserver", {NULL}, 3825, "udp"}, {"wormux", {NULL}, 3826, "tcp"}, {"wormux", {NULL}, 3826, "udp"}, {"netmpi", {NULL}, 3827, "tcp"}, {"netmpi", {NULL}, 3827, "udp"}, {"neteh", {NULL}, 3828, "tcp"}, {"neteh", {NULL}, 3828, "udp"}, {"neteh-ext", {NULL}, 3829, "tcp"}, {"neteh-ext", {NULL}, 3829, "udp"}, {"cernsysmgmtagt", {NULL}, 3830, "tcp"}, {"cernsysmgmtagt", {NULL}, 3830, "udp"}, {"dvapps", {NULL}, 3831, "tcp"}, {"dvapps", {NULL}, 3831, "udp"}, {"xxnetserver", {NULL}, 3832, "tcp"}, {"xxnetserver", {NULL}, 3832, "udp"}, {"aipn-auth", {NULL}, 3833, "tcp"}, {"aipn-auth", {NULL}, 3833, "udp"}, {"spectardata", {NULL}, 3834, "tcp"}, {"spectardata", {NULL}, 3834, "udp"}, {"spectardb", {NULL}, 3835, "tcp"}, {"spectardb", {NULL}, 3835, "udp"}, {"markem-dcp", {NULL}, 3836, "tcp"}, {"markem-dcp", {NULL}, 3836, "udp"}, {"mkm-discovery", {NULL}, 3837, "tcp"}, {"mkm-discovery", {NULL}, 3837, "udp"}, {"sos", {NULL}, 3838, "tcp"}, {"sos", {NULL}, 3838, "udp"}, {"amx-rms", {NULL}, 3839, "tcp"}, {"amx-rms", {NULL}, 3839, "udp"}, {"flirtmitmir", {NULL}, 3840, "tcp"}, {"flirtmitmir", {NULL}, 3840, "udp"}, {"zfirm-shiprush3", {NULL}, 3841, "tcp"}, {"zfirm-shiprush3", {NULL}, 3841, "udp"}, {"nhci", {NULL}, 3842, "tcp"}, {"nhci", {NULL}, 3842, "udp"}, {"quest-agent", {NULL}, 3843, "tcp"}, {"quest-agent", {NULL}, 3843, "udp"}, {"rnm", {NULL}, 3844, "tcp"}, {"rnm", {NULL}, 3844, "udp"}, {"v-one-spp", {NULL}, 3845, "tcp"}, {"v-one-spp", {NULL}, 3845, "udp"}, {"an-pcp", {NULL}, 3846, "tcp"}, {"an-pcp", {NULL}, 3846, "udp"}, {"msfw-control", {NULL}, 3847, "tcp"}, {"msfw-control", {NULL}, 3847, "udp"}, {"item", {NULL}, 3848, "tcp"}, {"item", {NULL}, 3848, "udp"}, {"spw-dnspreload", {NULL}, 3849, "tcp"}, {"spw-dnspreload", {NULL}, 3849, "udp"}, {"qtms-bootstrap", {NULL}, 3850, "tcp"}, {"qtms-bootstrap", {NULL}, 3850, "udp"}, {"spectraport", {NULL}, 3851, "tcp"}, {"spectraport", {NULL}, 3851, "udp"}, {"sse-app-config", {NULL}, 3852, "tcp"}, {"sse-app-config", {NULL}, 3852, "udp"}, {"sscan", {NULL}, 3853, "tcp"}, {"sscan", {NULL}, 3853, "udp"}, {"stryker-com", {NULL}, 3854, "tcp"}, {"stryker-com", {NULL}, 3854, "udp"}, {"opentrac", {NULL}, 3855, "tcp"}, {"opentrac", {NULL}, 3855, "udp"}, {"informer", {NULL}, 3856, "tcp"}, {"informer", {NULL}, 3856, "udp"}, {"trap-port", {NULL}, 3857, "tcp"}, {"trap-port", {NULL}, 3857, "udp"}, {"trap-port-mom", {NULL}, 3858, "tcp"}, {"trap-port-mom", {NULL}, 3858, "udp"}, {"nav-port", {NULL}, 3859, "tcp"}, {"nav-port", {NULL}, 3859, "udp"}, {"sasp", {NULL}, 3860, "tcp"}, {"sasp", {NULL}, 3860, "udp"}, {"winshadow-hd", {NULL}, 3861, "tcp"}, {"winshadow-hd", {NULL}, 3861, "udp"}, {"giga-pocket", {NULL}, 3862, "tcp"}, {"giga-pocket", {NULL}, 3862, "udp"}, {"asap-tcp", {NULL}, 3863, "tcp"}, {"asap-udp", {NULL}, 3863, "udp"}, {"asap-sctp", {NULL}, 3863, "sctp"}, {"asap-tcp-tls", {NULL}, 3864, "tcp"}, {"asap-sctp-tls", {NULL}, 3864, "sctp"}, {"xpl", {NULL}, 3865, "tcp"}, {"xpl", {NULL}, 3865, "udp"}, {"dzdaemon", {NULL}, 3866, "tcp"}, {"dzdaemon", {NULL}, 3866, "udp"}, {"dzoglserver", {NULL}, 3867, "tcp"}, {"dzoglserver", {NULL}, 3867, "udp"}, {"diameter", {NULL}, 3868, "tcp"}, {"diameter", {NULL}, 3868, "sctp"}, {"ovsam-mgmt", {NULL}, 3869, "tcp"}, {"ovsam-mgmt", {NULL}, 3869, "udp"}, {"ovsam-d-agent", {NULL}, 3870, "tcp"}, {"ovsam-d-agent", {NULL}, 3870, "udp"}, {"avocent-adsap", {NULL}, 3871, "tcp"}, {"avocent-adsap", {NULL}, 3871, "udp"}, {"oem-agent", {NULL}, 3872, "tcp"}, {"oem-agent", {NULL}, 3872, "udp"}, {"fagordnc", {NULL}, 3873, "tcp"}, {"fagordnc", {NULL}, 3873, "udp"}, {"sixxsconfig", {NULL}, 3874, "tcp"}, {"sixxsconfig", {NULL}, 3874, "udp"}, {"pnbscada", {NULL}, 3875, "tcp"}, {"pnbscada", {NULL}, 3875, "udp"}, {"dl_agent", {NULL}, 3876, "tcp"}, {"dl_agent", {NULL}, 3876, "udp"}, {"xmpcr-interface", {NULL}, 3877, "tcp"}, {"xmpcr-interface", {NULL}, 3877, "udp"}, {"fotogcad", {NULL}, 3878, "tcp"}, {"fotogcad", {NULL}, 3878, "udp"}, {"appss-lm", {NULL}, 3879, "tcp"}, {"appss-lm", {NULL}, 3879, "udp"}, {"igrs", {NULL}, 3880, "tcp"}, {"igrs", {NULL}, 3880, "udp"}, {"idac", {NULL}, 3881, "tcp"}, {"idac", {NULL}, 3881, "udp"}, {"msdts1", {NULL}, 3882, "tcp"}, {"msdts1", {NULL}, 3882, "udp"}, {"vrpn", {NULL}, 3883, "tcp"}, {"vrpn", {NULL}, 3883, "udp"}, {"softrack-meter", {NULL}, 3884, "tcp"}, {"softrack-meter", {NULL}, 3884, "udp"}, {"topflow-ssl", {NULL}, 3885, "tcp"}, {"topflow-ssl", {NULL}, 3885, "udp"}, {"nei-management", {NULL}, 3886, "tcp"}, {"nei-management", {NULL}, 3886, "udp"}, {"ciphire-data", {NULL}, 3887, "tcp"}, {"ciphire-data", {NULL}, 3887, "udp"}, {"ciphire-serv", {NULL}, 3888, "tcp"}, {"ciphire-serv", {NULL}, 3888, "udp"}, {"dandv-tester", {NULL}, 3889, "tcp"}, {"dandv-tester", {NULL}, 3889, "udp"}, {"ndsconnect", {NULL}, 3890, "tcp"}, {"ndsconnect", {NULL}, 3890, "udp"}, {"rtc-pm-port", {NULL}, 3891, "tcp"}, {"rtc-pm-port", {NULL}, 3891, "udp"}, {"pcc-image-port", {NULL}, 3892, "tcp"}, {"pcc-image-port", {NULL}, 3892, "udp"}, {"cgi-starapi", {NULL}, 3893, "tcp"}, {"cgi-starapi", {NULL}, 3893, "udp"}, {"syam-agent", {NULL}, 3894, "tcp"}, {"syam-agent", {NULL}, 3894, "udp"}, {"syam-smc", {NULL}, 3895, "tcp"}, {"syam-smc", {NULL}, 3895, "udp"}, {"sdo-tls", {NULL}, 3896, "tcp"}, {"sdo-tls", {NULL}, 3896, "udp"}, {"sdo-ssh", {NULL}, 3897, "tcp"}, {"sdo-ssh", {NULL}, 3897, "udp"}, {"senip", {NULL}, 3898, "tcp"}, {"senip", {NULL}, 3898, "udp"}, {"itv-control", {NULL}, 3899, "tcp"}, {"itv-control", {NULL}, 3899, "udp"}, {"udt_os", {NULL}, 3900, "tcp"}, {"udt_os", {NULL}, 3900, "udp"}, {"nimsh", {NULL}, 3901, "tcp"}, {"nimsh", {NULL}, 3901, "udp"}, {"nimaux", {NULL}, 3902, "tcp"}, {"nimaux", {NULL}, 3902, "udp"}, {"charsetmgr", {NULL}, 3903, "tcp"}, {"charsetmgr", {NULL}, 3903, "udp"}, {"omnilink-port", {NULL}, 3904, "tcp"}, {"omnilink-port", {NULL}, 3904, "udp"}, {"mupdate", {NULL}, 3905, "tcp"}, {"mupdate", {NULL}, 3905, "udp"}, {"topovista-data", {NULL}, 3906, "tcp"}, {"topovista-data", {NULL}, 3906, "udp"}, {"imoguia-port", {NULL}, 3907, "tcp"}, {"imoguia-port", {NULL}, 3907, "udp"}, {"hppronetman", {NULL}, 3908, "tcp"}, {"hppronetman", {NULL}, 3908, "udp"}, {"surfcontrolcpa", {NULL}, 3909, "tcp"}, {"surfcontrolcpa", {NULL}, 3909, "udp"}, {"prnrequest", {NULL}, 3910, "tcp"}, {"prnrequest", {NULL}, 3910, "udp"}, {"prnstatus", {NULL}, 3911, "tcp"}, {"prnstatus", {NULL}, 3911, "udp"}, {"gbmt-stars", {NULL}, 3912, "tcp"}, {"gbmt-stars", {NULL}, 3912, "udp"}, {"listcrt-port", {NULL}, 3913, "tcp"}, {"listcrt-port", {NULL}, 3913, "udp"}, {"listcrt-port-2", {NULL}, 3914, "tcp"}, {"listcrt-port-2", {NULL}, 3914, "udp"}, {"agcat", {NULL}, 3915, "tcp"}, {"agcat", {NULL}, 3915, "udp"}, {"wysdmc", {NULL}, 3916, "tcp"}, {"wysdmc", {NULL}, 3916, "udp"}, {"aftmux", {NULL}, 3917, "tcp"}, {"aftmux", {NULL}, 3917, "udp"}, {"pktcablemmcops", {NULL}, 3918, "tcp"}, {"pktcablemmcops", {NULL}, 3918, "udp"}, {"hyperip", {NULL}, 3919, "tcp"}, {"hyperip", {NULL}, 3919, "udp"}, {"exasoftport1", {NULL}, 3920, "tcp"}, {"exasoftport1", {NULL}, 3920, "udp"}, {"herodotus-net", {NULL}, 3921, "tcp"}, {"herodotus-net", {NULL}, 3921, "udp"}, {"sor-update", {NULL}, 3922, "tcp"}, {"sor-update", {NULL}, 3922, "udp"}, {"symb-sb-port", {NULL}, 3923, "tcp"}, {"symb-sb-port", {NULL}, 3923, "udp"}, {"mpl-gprs-port", {NULL}, 3924, "tcp"}, {"mpl-gprs-port", {NULL}, 3924, "udp"}, {"zmp", {NULL}, 3925, "tcp"}, {"zmp", {NULL}, 3925, "udp"}, {"winport", {NULL}, 3926, "tcp"}, {"winport", {NULL}, 3926, "udp"}, {"natdataservice", {NULL}, 3927, "tcp"}, {"natdataservice", {NULL}, 3927, "udp"}, {"netboot-pxe", {NULL}, 3928, "tcp"}, {"netboot-pxe", {NULL}, 3928, "udp"}, {"smauth-port", {NULL}, 3929, "tcp"}, {"smauth-port", {NULL}, 3929, "udp"}, {"syam-webserver", {NULL}, 3930, "tcp"}, {"syam-webserver", {NULL}, 3930, "udp"}, {"msr-plugin-port", {NULL}, 3931, "tcp"}, {"msr-plugin-port", {NULL}, 3931, "udp"}, {"dyn-site", {NULL}, 3932, "tcp"}, {"dyn-site", {NULL}, 3932, "udp"}, {"plbserve-port", {NULL}, 3933, "tcp"}, {"plbserve-port", {NULL}, 3933, "udp"}, {"sunfm-port", {NULL}, 3934, "tcp"}, {"sunfm-port", {NULL}, 3934, "udp"}, {"sdp-portmapper", {NULL}, 3935, "tcp"}, {"sdp-portmapper", {NULL}, 3935, "udp"}, {"mailprox", {NULL}, 3936, "tcp"}, {"mailprox", {NULL}, 3936, "udp"}, {"dvbservdsc", {NULL}, 3937, "tcp"}, {"dvbservdsc", {NULL}, 3937, "udp"}, {"dbcontrol_agent", {NULL}, 3938, "tcp"}, {"dbcontrol_agent", {NULL}, 3938, "udp"}, {"aamp", {NULL}, 3939, "tcp"}, {"aamp", {NULL}, 3939, "udp"}, {"xecp-node", {NULL}, 3940, "tcp"}, {"xecp-node", {NULL}, 3940, "udp"}, {"homeportal-web", {NULL}, 3941, "tcp"}, {"homeportal-web", {NULL}, 3941, "udp"}, {"srdp", {NULL}, 3942, "tcp"}, {"srdp", {NULL}, 3942, "udp"}, {"tig", {NULL}, 3943, "tcp"}, {"tig", {NULL}, 3943, "udp"}, {"sops", {NULL}, 3944, "tcp"}, {"sops", {NULL}, 3944, "udp"}, {"emcads", {NULL}, 3945, "tcp"}, {"emcads", {NULL}, 3945, "udp"}, {"backupedge", {NULL}, 3946, "tcp"}, {"backupedge", {NULL}, 3946, "udp"}, {"ccp", {NULL}, 3947, "tcp"}, {"ccp", {NULL}, 3947, "udp"}, {"apdap", {NULL}, 3948, "tcp"}, {"apdap", {NULL}, 3948, "udp"}, {"drip", {NULL}, 3949, "tcp"}, {"drip", {NULL}, 3949, "udp"}, {"namemunge", {NULL}, 3950, "tcp"}, {"namemunge", {NULL}, 3950, "udp"}, {"pwgippfax", {NULL}, 3951, "tcp"}, {"pwgippfax", {NULL}, 3951, "udp"}, {"i3-sessionmgr", {NULL}, 3952, "tcp"}, {"i3-sessionmgr", {NULL}, 3952, "udp"}, {"xmlink-connect", {NULL}, 3953, "tcp"}, {"xmlink-connect", {NULL}, 3953, "udp"}, {"adrep", {NULL}, 3954, "tcp"}, {"adrep", {NULL}, 3954, "udp"}, {"p2pcommunity", {NULL}, 3955, "tcp"}, {"p2pcommunity", {NULL}, 3955, "udp"}, {"gvcp", {NULL}, 3956, "tcp"}, {"gvcp", {NULL}, 3956, "udp"}, {"mqe-broker", {NULL}, 3957, "tcp"}, {"mqe-broker", {NULL}, 3957, "udp"}, {"mqe-agent", {NULL}, 3958, "tcp"}, {"mqe-agent", {NULL}, 3958, "udp"}, {"treehopper", {NULL}, 3959, "tcp"}, {"treehopper", {NULL}, 3959, "udp"}, {"bess", {NULL}, 3960, "tcp"}, {"bess", {NULL}, 3960, "udp"}, {"proaxess", {NULL}, 3961, "tcp"}, {"proaxess", {NULL}, 3961, "udp"}, {"sbi-agent", {NULL}, 3962, "tcp"}, {"sbi-agent", {NULL}, 3962, "udp"}, {"thrp", {NULL}, 3963, "tcp"}, {"thrp", {NULL}, 3963, "udp"}, {"sasggprs", {NULL}, 3964, "tcp"}, {"sasggprs", {NULL}, 3964, "udp"}, {"ati-ip-to-ncpe", {NULL}, 3965, "tcp"}, {"ati-ip-to-ncpe", {NULL}, 3965, "udp"}, {"bflckmgr", {NULL}, 3966, "tcp"}, {"bflckmgr", {NULL}, 3966, "udp"}, {"ppsms", {NULL}, 3967, "tcp"}, {"ppsms", {NULL}, 3967, "udp"}, {"ianywhere-dbns", {NULL}, 3968, "tcp"}, {"ianywhere-dbns", {NULL}, 3968, "udp"}, {"landmarks", {NULL}, 3969, "tcp"}, {"landmarks", {NULL}, 3969, "udp"}, {"lanrevagent", {NULL}, 3970, "tcp"}, {"lanrevagent", {NULL}, 3970, "udp"}, {"lanrevserver", {NULL}, 3971, "tcp"}, {"lanrevserver", {NULL}, 3971, "udp"}, {"iconp", {NULL}, 3972, "tcp"}, {"iconp", {NULL}, 3972, "udp"}, {"progistics", {NULL}, 3973, "tcp"}, {"progistics", {NULL}, 3973, "udp"}, {"citysearch", {NULL}, 3974, "tcp"}, {"citysearch", {NULL}, 3974, "udp"}, {"airshot", {NULL}, 3975, "tcp"}, {"airshot", {NULL}, 3975, "udp"}, {"opswagent", {NULL}, 3976, "tcp"}, {"opswagent", {NULL}, 3976, "udp"}, {"opswmanager", {NULL}, 3977, "tcp"}, {"opswmanager", {NULL}, 3977, "udp"}, {"secure-cfg-svr", {NULL}, 3978, "tcp"}, {"secure-cfg-svr", {NULL}, 3978, "udp"}, {"smwan", {NULL}, 3979, "tcp"}, {"smwan", {NULL}, 3979, "udp"}, {"acms", {NULL}, 3980, "tcp"}, {"acms", {NULL}, 3980, "udp"}, {"starfish", {NULL}, 3981, "tcp"}, {"starfish", {NULL}, 3981, "udp"}, {"eis", {NULL}, 3982, "tcp"}, {"eis", {NULL}, 3982, "udp"}, {"eisp", {NULL}, 3983, "tcp"}, {"eisp", {NULL}, 3983, "udp"}, {"mapper-nodemgr", {NULL}, 3984, "tcp"}, {"mapper-nodemgr", {NULL}, 3984, "udp"}, {"mapper-mapethd", {NULL}, 3985, "tcp"}, {"mapper-mapethd", {NULL}, 3985, "udp"}, {"mapper-ws_ethd", {NULL}, 3986, "tcp"}, {"mapper-ws_ethd", {NULL}, 3986, "udp"}, {"centerline", {NULL}, 3987, "tcp"}, {"centerline", {NULL}, 3987, "udp"}, {"dcs-config", {NULL}, 3988, "tcp"}, {"dcs-config", {NULL}, 3988, "udp"}, {"bv-queryengine", {NULL}, 3989, "tcp"}, {"bv-queryengine", {NULL}, 3989, "udp"}, {"bv-is", {NULL}, 3990, "tcp"}, {"bv-is", {NULL}, 3990, "udp"}, {"bv-smcsrv", {NULL}, 3991, "tcp"}, {"bv-smcsrv", {NULL}, 3991, "udp"}, {"bv-ds", {NULL}, 3992, "tcp"}, {"bv-ds", {NULL}, 3992, "udp"}, {"bv-agent", {NULL}, 3993, "tcp"}, {"bv-agent", {NULL}, 3993, "udp"}, {"iss-mgmt-ssl", {NULL}, 3995, "tcp"}, {"iss-mgmt-ssl", {NULL}, 3995, "udp"}, {"abcsoftware", {NULL}, 3996, "tcp"}, {"abcsoftware", {NULL}, 3996, "udp"}, {"agentsease-db", {NULL}, 3997, "tcp"}, {"agentsease-db", {NULL}, 3997, "udp"}, {"dnx", {NULL}, 3998, "tcp"}, {"dnx", {NULL}, 3998, "udp"}, {"nvcnet", {NULL}, 3999, "tcp"}, {"nvcnet", {NULL}, 3999, "udp"}, {"terabase", {NULL}, 4000, "tcp"}, {"terabase", {NULL}, 4000, "udp"}, {"newoak", {NULL}, 4001, "tcp"}, {"newoak", {NULL}, 4001, "udp"}, {"pxc-spvr-ft", {NULL}, 4002, "tcp"}, {"pxc-spvr-ft", {NULL}, 4002, "udp"}, {"pxc-splr-ft", {NULL}, 4003, "tcp"}, {"pxc-splr-ft", {NULL}, 4003, "udp"}, {"pxc-roid", {NULL}, 4004, "tcp"}, {"pxc-roid", {NULL}, 4004, "udp"}, {"pxc-pin", {NULL}, 4005, "tcp"}, {"pxc-pin", {NULL}, 4005, "udp"}, {"pxc-spvr", {NULL}, 4006, "tcp"}, {"pxc-spvr", {NULL}, 4006, "udp"}, {"pxc-splr", {NULL}, 4007, "tcp"}, {"pxc-splr", {NULL}, 4007, "udp"}, {"netcheque", {NULL}, 4008, "tcp"}, {"netcheque", {NULL}, 4008, "udp"}, {"chimera-hwm", {NULL}, 4009, "tcp"}, {"chimera-hwm", {NULL}, 4009, "udp"}, {"samsung-unidex", {NULL}, 4010, "tcp"}, {"samsung-unidex", {NULL}, 4010, "udp"}, {"altserviceboot", {NULL}, 4011, "tcp"}, {"altserviceboot", {NULL}, 4011, "udp"}, {"pda-gate", {NULL}, 4012, "tcp"}, {"pda-gate", {NULL}, 4012, "udp"}, {"acl-manager", {NULL}, 4013, "tcp"}, {"acl-manager", {NULL}, 4013, "udp"}, {"taiclock", {NULL}, 4014, "tcp"}, {"taiclock", {NULL}, 4014, "udp"}, {"talarian-mcast1", {NULL}, 4015, "tcp"}, {"talarian-mcast1", {NULL}, 4015, "udp"}, {"talarian-mcast2", {NULL}, 4016, "tcp"}, {"talarian-mcast2", {NULL}, 4016, "udp"}, {"talarian-mcast3", {NULL}, 4017, "tcp"}, {"talarian-mcast3", {NULL}, 4017, "udp"}, {"talarian-mcast4", {NULL}, 4018, "tcp"}, {"talarian-mcast4", {NULL}, 4018, "udp"}, {"talarian-mcast5", {NULL}, 4019, "tcp"}, {"talarian-mcast5", {NULL}, 4019, "udp"}, {"trap", {NULL}, 4020, "tcp"}, {"trap", {NULL}, 4020, "udp"}, {"nexus-portal", {NULL}, 4021, "tcp"}, {"nexus-portal", {NULL}, 4021, "udp"}, {"dnox", {NULL}, 4022, "tcp"}, {"dnox", {NULL}, 4022, "udp"}, {"esnm-zoning", {NULL}, 4023, "tcp"}, {"esnm-zoning", {NULL}, 4023, "udp"}, {"tnp1-port", {NULL}, 4024, "tcp"}, {"tnp1-port", {NULL}, 4024, "udp"}, {"partimage", {NULL}, 4025, "tcp"}, {"partimage", {NULL}, 4025, "udp"}, {"as-debug", {NULL}, 4026, "tcp"}, {"as-debug", {NULL}, 4026, "udp"}, {"bxp", {NULL}, 4027, "tcp"}, {"bxp", {NULL}, 4027, "udp"}, {"dtserver-port", {NULL}, 4028, "tcp"}, {"dtserver-port", {NULL}, 4028, "udp"}, {"ip-qsig", {NULL}, 4029, "tcp"}, {"ip-qsig", {NULL}, 4029, "udp"}, {"jdmn-port", {NULL}, 4030, "tcp"}, {"jdmn-port", {NULL}, 4030, "udp"}, {"suucp", {NULL}, 4031, "tcp"}, {"suucp", {NULL}, 4031, "udp"}, {"vrts-auth-port", {NULL}, 4032, "tcp"}, {"vrts-auth-port", {NULL}, 4032, "udp"}, {"sanavigator", {NULL}, 4033, "tcp"}, {"sanavigator", {NULL}, 4033, "udp"}, {"ubxd", {NULL}, 4034, "tcp"}, {"ubxd", {NULL}, 4034, "udp"}, {"wap-push-http", {NULL}, 4035, "tcp"}, {"wap-push-http", {NULL}, 4035, "udp"}, {"wap-push-https", {NULL}, 4036, "tcp"}, {"wap-push-https", {NULL}, 4036, "udp"}, {"ravehd", {NULL}, 4037, "tcp"}, {"ravehd", {NULL}, 4037, "udp"}, {"fazzt-ptp", {NULL}, 4038, "tcp"}, {"fazzt-ptp", {NULL}, 4038, "udp"}, {"fazzt-admin", {NULL}, 4039, "tcp"}, {"fazzt-admin", {NULL}, 4039, "udp"}, {"yo-main", {NULL}, 4040, "tcp"}, {"yo-main", {NULL}, 4040, "udp"}, {"houston", {NULL}, 4041, "tcp"}, {"houston", {NULL}, 4041, "udp"}, {"ldxp", {NULL}, 4042, "tcp"}, {"ldxp", {NULL}, 4042, "udp"}, {"nirp", {NULL}, 4043, "tcp"}, {"nirp", {NULL}, 4043, "udp"}, {"ltp", {NULL}, 4044, "tcp"}, {"ltp", {NULL}, 4044, "udp"}, {"npp", {NULL}, 4045, "tcp"}, {"npp", {NULL}, 4045, "udp"}, {"acp-proto", {NULL}, 4046, "tcp"}, {"acp-proto", {NULL}, 4046, "udp"}, {"ctp-state", {NULL}, 4047, "tcp"}, {"ctp-state", {NULL}, 4047, "udp"}, {"wafs", {NULL}, 4049, "tcp"}, {"wafs", {NULL}, 4049, "udp"}, {"cisco-wafs", {NULL}, 4050, "tcp"}, {"cisco-wafs", {NULL}, 4050, "udp"}, {"cppdp", {NULL}, 4051, "tcp"}, {"cppdp", {NULL}, 4051, "udp"}, {"interact", {NULL}, 4052, "tcp"}, {"interact", {NULL}, 4052, "udp"}, {"ccu-comm-1", {NULL}, 4053, "tcp"}, {"ccu-comm-1", {NULL}, 4053, "udp"}, {"ccu-comm-2", {NULL}, 4054, "tcp"}, {"ccu-comm-2", {NULL}, 4054, "udp"}, {"ccu-comm-3", {NULL}, 4055, "tcp"}, {"ccu-comm-3", {NULL}, 4055, "udp"}, {"lms", {NULL}, 4056, "tcp"}, {"lms", {NULL}, 4056, "udp"}, {"wfm", {NULL}, 4057, "tcp"}, {"wfm", {NULL}, 4057, "udp"}, {"kingfisher", {NULL}, 4058, "tcp"}, {"kingfisher", {NULL}, 4058, "udp"}, {"dlms-cosem", {NULL}, 4059, "tcp"}, {"dlms-cosem", {NULL}, 4059, "udp"}, {"dsmeter_iatc", {NULL}, 4060, "tcp"}, {"dsmeter_iatc", {NULL}, 4060, "udp"}, {"ice-location", {NULL}, 4061, "tcp"}, {"ice-location", {NULL}, 4061, "udp"}, {"ice-slocation", {NULL}, 4062, "tcp"}, {"ice-slocation", {NULL}, 4062, "udp"}, {"ice-router", {NULL}, 4063, "tcp"}, {"ice-router", {NULL}, 4063, "udp"}, {"ice-srouter", {NULL}, 4064, "tcp"}, {"ice-srouter", {NULL}, 4064, "udp"}, {"avanti_cdp", {NULL}, 4065, "tcp"}, {"avanti_cdp", {NULL}, 4065, "udp"}, {"pmas", {NULL}, 4066, "tcp"}, {"pmas", {NULL}, 4066, "udp"}, {"idp", {NULL}, 4067, "tcp"}, {"idp", {NULL}, 4067, "udp"}, {"ipfltbcst", {NULL}, 4068, "tcp"}, {"ipfltbcst", {NULL}, 4068, "udp"}, {"minger", {NULL}, 4069, "tcp"}, {"minger", {NULL}, 4069, "udp"}, {"tripe", {NULL}, 4070, "tcp"}, {"tripe", {NULL}, 4070, "udp"}, {"aibkup", {NULL}, 4071, "tcp"}, {"aibkup", {NULL}, 4071, "udp"}, {"zieto-sock", {NULL}, 4072, "tcp"}, {"zieto-sock", {NULL}, 4072, "udp"}, {"iRAPP", {NULL}, 4073, "tcp"}, {"iRAPP", {NULL}, 4073, "udp"}, {"cequint-cityid", {NULL}, 4074, "tcp"}, {"cequint-cityid", {NULL}, 4074, "udp"}, {"perimlan", {NULL}, 4075, "tcp"}, {"perimlan", {NULL}, 4075, "udp"}, {"seraph", {NULL}, 4076, "tcp"}, {"seraph", {NULL}, 4076, "udp"}, {"ascomalarm", {NULL}, 4077, "udp"}, {"cssp", {NULL}, 4078, "tcp"}, {"santools", {NULL}, 4079, "tcp"}, {"santools", {NULL}, 4079, "udp"}, {"lorica-in", {NULL}, 4080, "tcp"}, {"lorica-in", {NULL}, 4080, "udp"}, {"lorica-in-sec", {NULL}, 4081, "tcp"}, {"lorica-in-sec", {NULL}, 4081, "udp"}, {"lorica-out", {NULL}, 4082, "tcp"}, {"lorica-out", {NULL}, 4082, "udp"}, {"lorica-out-sec", {NULL}, 4083, "tcp"}, {"lorica-out-sec", {NULL}, 4083, "udp"}, {"fortisphere-vm", {NULL}, 4084, "udp"}, {"ezmessagesrv", {NULL}, 4085, "tcp"}, {"ftsync", {NULL}, 4086, "udp"}, {"applusservice", {NULL}, 4087, "tcp"}, {"npsp", {NULL}, 4088, "tcp"}, {"opencore", {NULL}, 4089, "tcp"}, {"opencore", {NULL}, 4089, "udp"}, {"omasgport", {NULL}, 4090, "tcp"}, {"omasgport", {NULL}, 4090, "udp"}, {"ewinstaller", {NULL}, 4091, "tcp"}, {"ewinstaller", {NULL}, 4091, "udp"}, {"ewdgs", {NULL}, 4092, "tcp"}, {"ewdgs", {NULL}, 4092, "udp"}, {"pvxpluscs", {NULL}, 4093, "tcp"}, {"pvxpluscs", {NULL}, 4093, "udp"}, {"sysrqd", {NULL}, 4094, "tcp"}, {"sysrqd", {NULL}, 4094, "udp"}, {"xtgui", {NULL}, 4095, "tcp"}, {"xtgui", {NULL}, 4095, "udp"}, {"bre", {NULL}, 4096, "tcp"}, {"bre", {NULL}, 4096, "udp"}, {"patrolview", {NULL}, 4097, "tcp"}, {"patrolview", {NULL}, 4097, "udp"}, {"drmsfsd", {NULL}, 4098, "tcp"}, {"drmsfsd", {NULL}, 4098, "udp"}, {"dpcp", {NULL}, 4099, "tcp"}, {"dpcp", {NULL}, 4099, "udp"}, {"igo-incognito", {NULL}, 4100, "tcp"}, {"igo-incognito", {NULL}, 4100, "udp"}, {"brlp-0", {NULL}, 4101, "tcp"}, {"brlp-0", {NULL}, 4101, "udp"}, {"brlp-1", {NULL}, 4102, "tcp"}, {"brlp-1", {NULL}, 4102, "udp"}, {"brlp-2", {NULL}, 4103, "tcp"}, {"brlp-2", {NULL}, 4103, "udp"}, {"brlp-3", {NULL}, 4104, "tcp"}, {"brlp-3", {NULL}, 4104, "udp"}, {"shofarplayer", {NULL}, 4105, "tcp"}, {"shofarplayer", {NULL}, 4105, "udp"}, {"synchronite", {NULL}, 4106, "tcp"}, {"synchronite", {NULL}, 4106, "udp"}, {"j-ac", {NULL}, 4107, "tcp"}, {"j-ac", {NULL}, 4107, "udp"}, {"accel", {NULL}, 4108, "tcp"}, {"accel", {NULL}, 4108, "udp"}, {"izm", {NULL}, 4109, "tcp"}, {"izm", {NULL}, 4109, "udp"}, {"g2tag", {NULL}, 4110, "tcp"}, {"g2tag", {NULL}, 4110, "udp"}, {"xgrid", {NULL}, 4111, "tcp"}, {"xgrid", {NULL}, 4111, "udp"}, {"apple-vpns-rp", {NULL}, 4112, "tcp"}, {"apple-vpns-rp", {NULL}, 4112, "udp"}, {"aipn-reg", {NULL}, 4113, "tcp"}, {"aipn-reg", {NULL}, 4113, "udp"}, {"jomamqmonitor", {NULL}, 4114, "tcp"}, {"jomamqmonitor", {NULL}, 4114, "udp"}, {"cds", {NULL}, 4115, "tcp"}, {"cds", {NULL}, 4115, "udp"}, {"smartcard-tls", {NULL}, 4116, "tcp"}, {"smartcard-tls", {NULL}, 4116, "udp"}, {"hillrserv", {NULL}, 4117, "tcp"}, {"hillrserv", {NULL}, 4117, "udp"}, {"netscript", {NULL}, 4118, "tcp"}, {"netscript", {NULL}, 4118, "udp"}, {"assuria-slm", {NULL}, 4119, "tcp"}, {"assuria-slm", {NULL}, 4119, "udp"}, {"e-builder", {NULL}, 4121, "tcp"}, {"e-builder", {NULL}, 4121, "udp"}, {"fprams", {NULL}, 4122, "tcp"}, {"fprams", {NULL}, 4122, "udp"}, {"z-wave", {NULL}, 4123, "tcp"}, {"z-wave", {NULL}, 4123, "udp"}, {"tigv2", {NULL}, 4124, "tcp"}, {"tigv2", {NULL}, 4124, "udp"}, {"opsview-envoy", {NULL}, 4125, "tcp"}, {"opsview-envoy", {NULL}, 4125, "udp"}, {"ddrepl", {NULL}, 4126, "tcp"}, {"ddrepl", {NULL}, 4126, "udp"}, {"unikeypro", {NULL}, 4127, "tcp"}, {"unikeypro", {NULL}, 4127, "udp"}, {"nufw", {NULL}, 4128, "tcp"}, {"nufw", {NULL}, 4128, "udp"}, {"nuauth", {NULL}, 4129, "tcp"}, {"nuauth", {NULL}, 4129, "udp"}, {"fronet", {NULL}, 4130, "tcp"}, {"fronet", {NULL}, 4130, "udp"}, {"stars", {NULL}, 4131, "tcp"}, {"stars", {NULL}, 4131, "udp"}, {"nuts_dem", {NULL}, 4132, "tcp"}, {"nuts_dem", {NULL}, 4132, "udp"}, {"nuts_bootp", {NULL}, 4133, "tcp"}, {"nuts_bootp", {NULL}, 4133, "udp"}, {"nifty-hmi", {NULL}, 4134, "tcp"}, {"nifty-hmi", {NULL}, 4134, "udp"}, {"cl-db-attach", {NULL}, 4135, "tcp"}, {"cl-db-attach", {NULL}, 4135, "udp"}, {"cl-db-request", {NULL}, 4136, "tcp"}, {"cl-db-request", {NULL}, 4136, "udp"}, {"cl-db-remote", {NULL}, 4137, "tcp"}, {"cl-db-remote", {NULL}, 4137, "udp"}, {"nettest", {NULL}, 4138, "tcp"}, {"nettest", {NULL}, 4138, "udp"}, {"thrtx", {NULL}, 4139, "tcp"}, {"thrtx", {NULL}, 4139, "udp"}, {"cedros_fds", {NULL}, 4140, "tcp"}, {"cedros_fds", {NULL}, 4140, "udp"}, {"oirtgsvc", {NULL}, 4141, "tcp"}, {"oirtgsvc", {NULL}, 4141, "udp"}, {"oidocsvc", {NULL}, 4142, "tcp"}, {"oidocsvc", {NULL}, 4142, "udp"}, {"oidsr", {NULL}, 4143, "tcp"}, {"oidsr", {NULL}, 4143, "udp"}, {"vvr-control", {NULL}, 4145, "tcp"}, {"vvr-control", {NULL}, 4145, "udp"}, {"tgcconnect", {NULL}, 4146, "tcp"}, {"tgcconnect", {NULL}, 4146, "udp"}, {"vrxpservman", {NULL}, 4147, "tcp"}, {"vrxpservman", {NULL}, 4147, "udp"}, {"hhb-handheld", {NULL}, 4148, "tcp"}, {"hhb-handheld", {NULL}, 4148, "udp"}, {"agslb", {NULL}, 4149, "tcp"}, {"agslb", {NULL}, 4149, "udp"}, {"PowerAlert-nsa", {NULL}, 4150, "tcp"}, {"PowerAlert-nsa", {NULL}, 4150, "udp"}, {"menandmice_noh", {NULL}, 4151, "tcp"}, {"menandmice_noh", {NULL}, 4151, "udp"}, {"idig_mux", {NULL}, 4152, "tcp"}, {"idig_mux", {NULL}, 4152, "udp"}, {"mbl-battd", {NULL}, 4153, "tcp"}, {"mbl-battd", {NULL}, 4153, "udp"}, {"atlinks", {NULL}, 4154, "tcp"}, {"atlinks", {NULL}, 4154, "udp"}, {"bzr", {NULL}, 4155, "tcp"}, {"bzr", {NULL}, 4155, "udp"}, {"stat-results", {NULL}, 4156, "tcp"}, {"stat-results", {NULL}, 4156, "udp"}, {"stat-scanner", {NULL}, 4157, "tcp"}, {"stat-scanner", {NULL}, 4157, "udp"}, {"stat-cc", {NULL}, 4158, "tcp"}, {"stat-cc", {NULL}, 4158, "udp"}, {"nss", {NULL}, 4159, "tcp"}, {"nss", {NULL}, 4159, "udp"}, {"jini-discovery", {NULL}, 4160, "tcp"}, {"jini-discovery", {NULL}, 4160, "udp"}, {"omscontact", {NULL}, 4161, "tcp"}, {"omscontact", {NULL}, 4161, "udp"}, {"omstopology", {NULL}, 4162, "tcp"}, {"omstopology", {NULL}, 4162, "udp"}, {"silverpeakpeer", {NULL}, 4163, "tcp"}, {"silverpeakpeer", {NULL}, 4163, "udp"}, {"silverpeakcomm", {NULL}, 4164, "tcp"}, {"silverpeakcomm", {NULL}, 4164, "udp"}, {"altcp", {NULL}, 4165, "tcp"}, {"altcp", {NULL}, 4165, "udp"}, {"joost", {NULL}, 4166, "tcp"}, {"joost", {NULL}, 4166, "udp"}, {"ddgn", {NULL}, 4167, "tcp"}, {"ddgn", {NULL}, 4167, "udp"}, {"pslicser", {NULL}, 4168, "tcp"}, {"pslicser", {NULL}, 4168, "udp"}, {"iadt", {NULL}, 4169, "tcp"}, {"iadt-disc", {NULL}, 4169, "udp"}, {"d-cinema-csp", {NULL}, 4170, "tcp"}, {"ml-svnet", {NULL}, 4171, "tcp"}, {"pcoip", {NULL}, 4172, "tcp"}, {"pcoip", {NULL}, 4172, "udp"}, {"smcluster", {NULL}, 4174, "tcp"}, {"bccp", {NULL}, 4175, "tcp"}, {"tl-ipcproxy", {NULL}, 4176, "tcp"}, {"wello", {NULL}, 4177, "tcp"}, {"wello", {NULL}, 4177, "udp"}, {"storman", {NULL}, 4178, "tcp"}, {"storman", {NULL}, 4178, "udp"}, {"MaxumSP", {NULL}, 4179, "tcp"}, {"MaxumSP", {NULL}, 4179, "udp"}, {"httpx", {NULL}, 4180, "tcp"}, {"httpx", {NULL}, 4180, "udp"}, {"macbak", {NULL}, 4181, "tcp"}, {"macbak", {NULL}, 4181, "udp"}, {"pcptcpservice", {NULL}, 4182, "tcp"}, {"pcptcpservice", {NULL}, 4182, "udp"}, {"gmmp", {NULL}, 4183, "tcp"}, {"gmmp", {NULL}, 4183, "udp"}, {"universe_suite", {NULL}, 4184, "tcp"}, {"universe_suite", {NULL}, 4184, "udp"}, {"wcpp", {NULL}, 4185, "tcp"}, {"wcpp", {NULL}, 4185, "udp"}, {"boxbackupstore", {NULL}, 4186, "tcp"}, {"csc_proxy", {NULL}, 4187, "tcp"}, {"vatata", {NULL}, 4188, "tcp"}, {"vatata", {NULL}, 4188, "udp"}, {"pcep", {NULL}, 4189, "tcp"}, {"sieve", {NULL}, 4190, "tcp"}, {"dsmipv6", {NULL}, 4191, "udp"}, {"azeti", {NULL}, 4192, "tcp"}, {"azeti-bd", {NULL}, 4192, "udp"}, {"pvxplusio", {NULL}, 4193, "tcp"}, {"eims-admin", {NULL}, 4199, "tcp"}, {"eims-admin", {NULL}, 4199, "udp"}, {"corelccam", {NULL}, 4300, "tcp"}, {"corelccam", {NULL}, 4300, "udp"}, {"d-data", {NULL}, 4301, "tcp"}, {"d-data", {NULL}, 4301, "udp"}, {"d-data-control", {NULL}, 4302, "tcp"}, {"d-data-control", {NULL}, 4302, "udp"}, {"srcp", {NULL}, 4303, "tcp"}, {"srcp", {NULL}, 4303, "udp"}, {"owserver", {NULL}, 4304, "tcp"}, {"owserver", {NULL}, 4304, "udp"}, {"batman", {NULL}, 4305, "tcp"}, {"batman", {NULL}, 4305, "udp"}, {"pinghgl", {NULL}, 4306, "tcp"}, {"pinghgl", {NULL}, 4306, "udp"}, {"visicron-vs", {NULL}, 4307, "tcp"}, {"visicron-vs", {NULL}, 4307, "udp"}, {"compx-lockview", {NULL}, 4308, "tcp"}, {"compx-lockview", {NULL}, 4308, "udp"}, {"dserver", {NULL}, 4309, "tcp"}, {"dserver", {NULL}, 4309, "udp"}, {"mirrtex", {NULL}, 4310, "tcp"}, {"mirrtex", {NULL}, 4310, "udp"}, {"p6ssmc", {NULL}, 4311, "tcp"}, {"pscl-mgt", {NULL}, 4312, "tcp"}, {"perrla", {NULL}, 4313, "tcp"}, {"fdt-rcatp", {NULL}, 4320, "tcp"}, {"fdt-rcatp", {NULL}, 4320, "udp"}, {"rwhois", {NULL}, 4321, "tcp"}, {"rwhois", {NULL}, 4321, "udp"}, {"trim-event", {NULL}, 4322, "tcp"}, {"trim-event", {NULL}, 4322, "udp"}, {"trim-ice", {NULL}, 4323, "tcp"}, {"trim-ice", {NULL}, 4323, "udp"}, {"balour", {NULL}, 4324, "tcp"}, {"balour", {NULL}, 4324, "udp"}, {"geognosisman", {NULL}, 4325, "tcp"}, {"geognosisman", {NULL}, 4325, "udp"}, {"geognosis", {NULL}, 4326, "tcp"}, {"geognosis", {NULL}, 4326, "udp"}, {"jaxer-web", {NULL}, 4327, "tcp"}, {"jaxer-web", {NULL}, 4327, "udp"}, {"jaxer-manager", {NULL}, 4328, "tcp"}, {"jaxer-manager", {NULL}, 4328, "udp"}, {"publiqare-sync", {NULL}, 4329, "tcp"}, {"gaia", {NULL}, 4340, "tcp"}, {"gaia", {NULL}, 4340, "udp"}, {"lisp-data", {NULL}, 4341, "tcp"}, {"lisp-data", {NULL}, 4341, "udp"}, {"lisp-cons", {NULL}, 4342, "tcp"}, {"lisp-control", {NULL}, 4342, "udp"}, {"unicall", {NULL}, 4343, "tcp"}, {"unicall", {NULL}, 4343, "udp"}, {"vinainstall", {NULL}, 4344, "tcp"}, {"vinainstall", {NULL}, 4344, "udp"}, {"m4-network-as", {NULL}, 4345, "tcp"}, {"m4-network-as", {NULL}, 4345, "udp"}, {"elanlm", {NULL}, 4346, "tcp"}, {"elanlm", {NULL}, 4346, "udp"}, {"lansurveyor", {NULL}, 4347, "tcp"}, {"lansurveyor", {NULL}, 4347, "udp"}, {"itose", {NULL}, 4348, "tcp"}, {"itose", {NULL}, 4348, "udp"}, {"fsportmap", {NULL}, 4349, "tcp"}, {"fsportmap", {NULL}, 4349, "udp"}, {"net-device", {NULL}, 4350, "tcp"}, {"net-device", {NULL}, 4350, "udp"}, {"plcy-net-svcs", {NULL}, 4351, "tcp"}, {"plcy-net-svcs", {NULL}, 4351, "udp"}, {"pjlink", {NULL}, 4352, "tcp"}, {"pjlink", {NULL}, 4352, "udp"}, {"f5-iquery", {NULL}, 4353, "tcp"}, {"f5-iquery", {NULL}, 4353, "udp"}, {"qsnet-trans", {NULL}, 4354, "tcp"}, {"qsnet-trans", {NULL}, 4354, "udp"}, {"qsnet-workst", {NULL}, 4355, "tcp"}, {"qsnet-workst", {NULL}, 4355, "udp"}, {"qsnet-assist", {NULL}, 4356, "tcp"}, {"qsnet-assist", {NULL}, 4356, "udp"}, {"qsnet-cond", {NULL}, 4357, "tcp"}, {"qsnet-cond", {NULL}, 4357, "udp"}, {"qsnet-nucl", {NULL}, 4358, "tcp"}, {"qsnet-nucl", {NULL}, 4358, "udp"}, {"omabcastltkm", {NULL}, 4359, "tcp"}, {"omabcastltkm", {NULL}, 4359, "udp"}, {"matrix_vnet", {NULL}, 4360, "tcp"}, {"nacnl", {NULL}, 4361, "udp"}, {"afore-vdp-disc", {NULL}, 4362, "udp"}, {"wxbrief", {NULL}, 4368, "tcp"}, {"wxbrief", {NULL}, 4368, "udp"}, {"epmd", {NULL}, 4369, "tcp"}, {"epmd", {NULL}, 4369, "udp"}, {"elpro_tunnel", {NULL}, 4370, "tcp"}, {"elpro_tunnel", {NULL}, 4370, "udp"}, {"l2c-control", {NULL}, 4371, "tcp"}, {"l2c-disc", {NULL}, 4371, "udp"}, {"l2c-data", {NULL}, 4372, "tcp"}, {"l2c-data", {NULL}, 4372, "udp"}, {"remctl", {NULL}, 4373, "tcp"}, {"remctl", {NULL}, 4373, "udp"}, {"psi-ptt", {NULL}, 4374, "tcp"}, {"tolteces", {NULL}, 4375, "tcp"}, {"tolteces", {NULL}, 4375, "udp"}, {"bip", {NULL}, 4376, "tcp"}, {"bip", {NULL}, 4376, "udp"}, {"cp-spxsvr", {NULL}, 4377, "tcp"}, {"cp-spxsvr", {NULL}, 4377, "udp"}, {"cp-spxdpy", {NULL}, 4378, "tcp"}, {"cp-spxdpy", {NULL}, 4378, "udp"}, {"ctdb", {NULL}, 4379, "tcp"}, {"ctdb", {NULL}, 4379, "udp"}, {"xandros-cms", {NULL}, 4389, "tcp"}, {"xandros-cms", {NULL}, 4389, "udp"}, {"wiegand", {NULL}, 4390, "tcp"}, {"wiegand", {NULL}, 4390, "udp"}, {"apwi-imserver", {NULL}, 4391, "tcp"}, {"apwi-rxserver", {NULL}, 4392, "tcp"}, {"apwi-rxspooler", {NULL}, 4393, "tcp"}, {"apwi-disc", {NULL}, 4394, "udp"}, {"omnivisionesx", {NULL}, 4395, "tcp"}, {"omnivisionesx", {NULL}, 4395, "udp"}, {"fly", {NULL}, 4396, "tcp"}, {"ds-srv", {NULL}, 4400, "tcp"}, {"ds-srv", {NULL}, 4400, "udp"}, {"ds-srvr", {NULL}, 4401, "tcp"}, {"ds-srvr", {NULL}, 4401, "udp"}, {"ds-clnt", {NULL}, 4402, "tcp"}, {"ds-clnt", {NULL}, 4402, "udp"}, {"ds-user", {NULL}, 4403, "tcp"}, {"ds-user", {NULL}, 4403, "udp"}, {"ds-admin", {NULL}, 4404, "tcp"}, {"ds-admin", {NULL}, 4404, "udp"}, {"ds-mail", {NULL}, 4405, "tcp"}, {"ds-mail", {NULL}, 4405, "udp"}, {"ds-slp", {NULL}, 4406, "tcp"}, {"ds-slp", {NULL}, 4406, "udp"}, {"nacagent", {NULL}, 4407, "tcp"}, {"slscc", {NULL}, 4408, "tcp"}, {"netcabinet-com", {NULL}, 4409, "tcp"}, {"itwo-server", {NULL}, 4410, "tcp"}, {"netrockey6", {NULL}, 4425, "tcp"}, {"netrockey6", {NULL}, 4425, "udp"}, {"beacon-port-2", {NULL}, 4426, "tcp"}, {"beacon-port-2", {NULL}, 4426, "udp"}, {"drizzle", {NULL}, 4427, "tcp"}, {"omviserver", {NULL}, 4428, "tcp"}, {"omviagent", {NULL}, 4429, "tcp"}, {"rsqlserver", {NULL}, 4430, "tcp"}, {"rsqlserver", {NULL}, 4430, "udp"}, {"wspipe", {NULL}, 4431, "tcp"}, {"netblox", {NULL}, 4441, "udp"}, {"saris", {NULL}, 4442, "tcp"}, {"saris", {NULL}, 4442, "udp"}, {"pharos", {NULL}, 4443, "tcp"}, {"pharos", {NULL}, 4443, "udp"}, {"krb524", {NULL}, 4444, "tcp"}, {"krb524", {NULL}, 4444, "udp"}, {"nv-video", {NULL}, 4444, "tcp"}, {"nv-video", {NULL}, 4444, "udp"}, {"upnotifyp", {NULL}, 4445, "tcp"}, {"upnotifyp", {NULL}, 4445, "udp"}, {"n1-fwp", {NULL}, 4446, "tcp"}, {"n1-fwp", {NULL}, 4446, "udp"}, {"n1-rmgmt", {NULL}, 4447, "tcp"}, {"n1-rmgmt", {NULL}, 4447, "udp"}, {"asc-slmd", {NULL}, 4448, "tcp"}, {"asc-slmd", {NULL}, 4448, "udp"}, {"privatewire", {NULL}, 4449, "tcp"}, {"privatewire", {NULL}, 4449, "udp"}, {"camp", {NULL}, 4450, "tcp"}, {"camp", {NULL}, 4450, "udp"}, {"ctisystemmsg", {NULL}, 4451, "tcp"}, {"ctisystemmsg", {NULL}, 4451, "udp"}, {"ctiprogramload", {NULL}, 4452, "tcp"}, {"ctiprogramload", {NULL}, 4452, "udp"}, {"nssalertmgr", {NULL}, 4453, "tcp"}, {"nssalertmgr", {NULL}, 4453, "udp"}, {"nssagentmgr", {NULL}, 4454, "tcp"}, {"nssagentmgr", {NULL}, 4454, "udp"}, {"prchat-user", {NULL}, 4455, "tcp"}, {"prchat-user", {NULL}, 4455, "udp"}, {"prchat-server", {NULL}, 4456, "tcp"}, {"prchat-server", {NULL}, 4456, "udp"}, {"prRegister", {NULL}, 4457, "tcp"}, {"prRegister", {NULL}, 4457, "udp"}, {"mcp", {NULL}, 4458, "tcp"}, {"mcp", {NULL}, 4458, "udp"}, {"hpssmgmt", {NULL}, 4484, "tcp"}, {"hpssmgmt", {NULL}, 4484, "udp"}, {"assyst-dr", {NULL}, 4485, "tcp"}, {"icms", {NULL}, 4486, "tcp"}, {"icms", {NULL}, 4486, "udp"}, {"prex-tcp", {NULL}, 4487, "tcp"}, {"awacs-ice", {NULL}, 4488, "tcp"}, {"awacs-ice", {NULL}, 4488, "udp"}, {"ipsec-nat-t", {NULL}, 4500, "tcp"}, {"ipsec-nat-t", {NULL}, 4500, "udp"}, {"ehs", {NULL}, 4535, "tcp"}, {"ehs", {NULL}, 4535, "udp"}, {"ehs-ssl", {NULL}, 4536, "tcp"}, {"ehs-ssl", {NULL}, 4536, "udp"}, {"wssauthsvc", {NULL}, 4537, "tcp"}, {"wssauthsvc", {NULL}, 4537, "udp"}, {"swx-gate", {NULL}, 4538, "tcp"}, {"swx-gate", {NULL}, 4538, "udp"}, {"worldscores", {NULL}, 4545, "tcp"}, {"worldscores", {NULL}, 4545, "udp"}, {"sf-lm", {NULL}, 4546, "tcp"}, {"sf-lm", {NULL}, 4546, "udp"}, {"lanner-lm", {NULL}, 4547, "tcp"}, {"lanner-lm", {NULL}, 4547, "udp"}, {"synchromesh", {NULL}, 4548, "tcp"}, {"synchromesh", {NULL}, 4548, "udp"}, {"aegate", {NULL}, 4549, "tcp"}, {"aegate", {NULL}, 4549, "udp"}, {"gds-adppiw-db", {NULL}, 4550, "tcp"}, {"gds-adppiw-db", {NULL}, 4550, "udp"}, {"ieee-mih", {NULL}, 4551, "tcp"}, {"ieee-mih", {NULL}, 4551, "udp"}, {"menandmice-mon", {NULL}, 4552, "tcp"}, {"menandmice-mon", {NULL}, 4552, "udp"}, {"icshostsvc", {NULL}, 4553, "tcp"}, {"msfrs", {NULL}, 4554, "tcp"}, {"msfrs", {NULL}, 4554, "udp"}, {"rsip", {NULL}, 4555, "tcp"}, {"rsip", {NULL}, 4555, "udp"}, {"dtn-bundle-tcp", {NULL}, 4556, "tcp"}, {"dtn-bundle-udp", {NULL}, 4556, "udp"}, {"mtcevrunqss", {NULL}, 4557, "udp"}, {"mtcevrunqman", {NULL}, 4558, "udp"}, {"hylafax", {NULL}, 4559, "tcp"}, {"hylafax", {NULL}, 4559, "udp"}, {"kwtc", {NULL}, 4566, "tcp"}, {"kwtc", {NULL}, 4566, "udp"}, {"tram", {NULL}, 4567, "tcp"}, {"tram", {NULL}, 4567, "udp"}, {"bmc-reporting", {NULL}, 4568, "tcp"}, {"bmc-reporting", {NULL}, 4568, "udp"}, {"iax", {NULL}, 4569, "tcp"}, {"iax", {NULL}, 4569, "udp"}, {"rid", {NULL}, 4590, "tcp"}, {"l3t-at-an", {NULL}, 4591, "tcp"}, {"l3t-at-an", {NULL}, 4591, "udp"}, {"hrpd-ith-at-an", {NULL}, 4592, "udp"}, {"ipt-anri-anri", {NULL}, 4593, "tcp"}, {"ipt-anri-anri", {NULL}, 4593, "udp"}, {"ias-session", {NULL}, 4594, "tcp"}, {"ias-session", {NULL}, 4594, "udp"}, {"ias-paging", {NULL}, 4595, "tcp"}, {"ias-paging", {NULL}, 4595, "udp"}, {"ias-neighbor", {NULL}, 4596, "tcp"}, {"ias-neighbor", {NULL}, 4596, "udp"}, {"a21-an-1xbs", {NULL}, 4597, "tcp"}, {"a21-an-1xbs", {NULL}, 4597, "udp"}, {"a16-an-an", {NULL}, 4598, "tcp"}, {"a16-an-an", {NULL}, 4598, "udp"}, {"a17-an-an", {NULL}, 4599, "tcp"}, {"a17-an-an", {NULL}, 4599, "udp"}, {"piranha1", {NULL}, 4600, "tcp"}, {"piranha1", {NULL}, 4600, "udp"}, {"piranha2", {NULL}, 4601, "tcp"}, {"piranha2", {NULL}, 4601, "udp"}, {"mtsserver", {NULL}, 4602, "tcp"}, {"menandmice-upg", {NULL}, 4603, "tcp"}, {"playsta2-app", {NULL}, 4658, "tcp"}, {"playsta2-app", {NULL}, 4658, "udp"}, {"playsta2-lob", {NULL}, 4659, "tcp"}, {"playsta2-lob", {NULL}, 4659, "udp"}, {"smaclmgr", {NULL}, 4660, "tcp"}, {"smaclmgr", {NULL}, 4660, "udp"}, {"kar2ouche", {NULL}, 4661, "tcp"}, {"kar2ouche", {NULL}, 4661, "udp"}, {"oms", {NULL}, 4662, "tcp"}, {"oms", {NULL}, 4662, "udp"}, {"noteit", {NULL}, 4663, "tcp"}, {"noteit", {NULL}, 4663, "udp"}, {"ems", {NULL}, 4664, "tcp"}, {"ems", {NULL}, 4664, "udp"}, {"contclientms", {NULL}, 4665, "tcp"}, {"contclientms", {NULL}, 4665, "udp"}, {"eportcomm", {NULL}, 4666, "tcp"}, {"eportcomm", {NULL}, 4666, "udp"}, {"mmacomm", {NULL}, 4667, "tcp"}, {"mmacomm", {NULL}, 4667, "udp"}, {"mmaeds", {NULL}, 4668, "tcp"}, {"mmaeds", {NULL}, 4668, "udp"}, {"eportcommdata", {NULL}, 4669, "tcp"}, {"eportcommdata", {NULL}, 4669, "udp"}, {"light", {NULL}, 4670, "tcp"}, {"light", {NULL}, 4670, "udp"}, {"acter", {NULL}, 4671, "tcp"}, {"acter", {NULL}, 4671, "udp"}, {"rfa", {NULL}, 4672, "tcp"}, {"rfa", {NULL}, 4672, "udp"}, {"cxws", {NULL}, 4673, "tcp"}, {"cxws", {NULL}, 4673, "udp"}, {"appiq-mgmt", {NULL}, 4674, "tcp"}, {"appiq-mgmt", {NULL}, 4674, "udp"}, {"dhct-status", {NULL}, 4675, "tcp"}, {"dhct-status", {NULL}, 4675, "udp"}, {"dhct-alerts", {NULL}, 4676, "tcp"}, {"dhct-alerts", {NULL}, 4676, "udp"}, {"bcs", {NULL}, 4677, "tcp"}, {"bcs", {NULL}, 4677, "udp"}, {"traversal", {NULL}, 4678, "tcp"}, {"traversal", {NULL}, 4678, "udp"}, {"mgesupervision", {NULL}, 4679, "tcp"}, {"mgesupervision", {NULL}, 4679, "udp"}, {"mgemanagement", {NULL}, 4680, "tcp"}, {"mgemanagement", {NULL}, 4680, "udp"}, {"parliant", {NULL}, 4681, "tcp"}, {"parliant", {NULL}, 4681, "udp"}, {"finisar", {NULL}, 4682, "tcp"}, {"finisar", {NULL}, 4682, "udp"}, {"spike", {NULL}, 4683, "tcp"}, {"spike", {NULL}, 4683, "udp"}, {"rfid-rp1", {NULL}, 4684, "tcp"}, {"rfid-rp1", {NULL}, 4684, "udp"}, {"autopac", {NULL}, 4685, "tcp"}, {"autopac", {NULL}, 4685, "udp"}, {"msp-os", {NULL}, 4686, "tcp"}, {"msp-os", {NULL}, 4686, "udp"}, {"nst", {NULL}, 4687, "tcp"}, {"nst", {NULL}, 4687, "udp"}, {"mobile-p2p", {NULL}, 4688, "tcp"}, {"mobile-p2p", {NULL}, 4688, "udp"}, {"altovacentral", {NULL}, 4689, "tcp"}, {"altovacentral", {NULL}, 4689, "udp"}, {"prelude", {NULL}, 4690, "tcp"}, {"prelude", {NULL}, 4690, "udp"}, {"mtn", {NULL}, 4691, "tcp"}, {"mtn", {NULL}, 4691, "udp"}, {"conspiracy", {NULL}, 4692, "tcp"}, {"conspiracy", {NULL}, 4692, "udp"}, {"netxms-agent", {NULL}, 4700, "tcp"}, {"netxms-agent", {NULL}, 4700, "udp"}, {"netxms-mgmt", {NULL}, 4701, "tcp"}, {"netxms-mgmt", {NULL}, 4701, "udp"}, {"netxms-sync", {NULL}, 4702, "tcp"}, {"netxms-sync", {NULL}, 4702, "udp"}, {"npqes-test", {NULL}, 4703, "tcp"}, {"assuria-ins", {NULL}, 4704, "tcp"}, {"truckstar", {NULL}, 4725, "tcp"}, {"truckstar", {NULL}, 4725, "udp"}, {"a26-fap-fgw", {NULL}, 4726, "udp"}, {"fcis", {NULL}, 4727, "tcp"}, {"fcis-disc", {NULL}, 4727, "udp"}, {"capmux", {NULL}, 4728, "tcp"}, {"capmux", {NULL}, 4728, "udp"}, {"gsmtap", {NULL}, 4729, "udp"}, {"gearman", {NULL}, 4730, "tcp"}, {"gearman", {NULL}, 4730, "udp"}, {"remcap", {NULL}, 4731, "tcp"}, {"ohmtrigger", {NULL}, 4732, "udp"}, {"resorcs", {NULL}, 4733, "tcp"}, {"ipdr-sp", {NULL}, 4737, "tcp"}, {"ipdr-sp", {NULL}, 4737, "udp"}, {"solera-lpn", {NULL}, 4738, "tcp"}, {"solera-lpn", {NULL}, 4738, "udp"}, {"ipfix", {NULL}, 4739, "tcp"}, {"ipfix", {NULL}, 4739, "udp"}, {"ipfix", {NULL}, 4739, "sctp"}, {"ipfixs", {NULL}, 4740, "tcp"}, {"ipfixs", {NULL}, 4740, "sctp"}, {"ipfixs", {NULL}, 4740, "udp"}, {"lumimgrd", {NULL}, 4741, "tcp"}, {"lumimgrd", {NULL}, 4741, "udp"}, {"sicct", {NULL}, 4742, "tcp"}, {"sicct-sdp", {NULL}, 4742, "udp"}, {"openhpid", {NULL}, 4743, "tcp"}, {"openhpid", {NULL}, 4743, "udp"}, {"ifsp", {NULL}, 4744, "tcp"}, {"ifsp", {NULL}, 4744, "udp"}, {"fmp", {NULL}, 4745, "tcp"}, {"fmp", {NULL}, 4745, "udp"}, {"profilemac", {NULL}, 4749, "tcp"}, {"profilemac", {NULL}, 4749, "udp"}, {"ssad", {NULL}, 4750, "tcp"}, {"ssad", {NULL}, 4750, "udp"}, {"spocp", {NULL}, 4751, "tcp"}, {"spocp", {NULL}, 4751, "udp"}, {"snap", {NULL}, 4752, "tcp"}, {"snap", {NULL}, 4752, "udp"}, {"bfd-multi-ctl", {NULL}, 4784, "tcp"}, {"bfd-multi-ctl", {NULL}, 4784, "udp"}, {"cncp", {NULL}, 4785, "udp"}, {"smart-install", {NULL}, 4786, "tcp"}, {"sia-ctrl-plane", {NULL}, 4787, "tcp"}, {"iims", {NULL}, 4800, "tcp"}, {"iims", {NULL}, 4800, "udp"}, {"iwec", {NULL}, 4801, "tcp"}, {"iwec", {NULL}, 4801, "udp"}, {"ilss", {NULL}, 4802, "tcp"}, {"ilss", {NULL}, 4802, "udp"}, {"notateit", {NULL}, 4803, "tcp"}, {"notateit-disc", {NULL}, 4803, "udp"}, {"aja-ntv4-disc", {NULL}, 4804, "udp"}, {"htcp", {NULL}, 4827, "tcp"}, {"htcp", {NULL}, 4827, "udp"}, {"varadero-0", {NULL}, 4837, "tcp"}, {"varadero-0", {NULL}, 4837, "udp"}, {"varadero-1", {NULL}, 4838, "tcp"}, {"varadero-1", {NULL}, 4838, "udp"}, {"varadero-2", {NULL}, 4839, "tcp"}, {"varadero-2", {NULL}, 4839, "udp"}, {"opcua-tcp", {NULL}, 4840, "tcp"}, {"opcua-udp", {NULL}, 4840, "udp"}, {"quosa", {NULL}, 4841, "tcp"}, {"quosa", {NULL}, 4841, "udp"}, {"gw-asv", {NULL}, 4842, "tcp"}, {"gw-asv", {NULL}, 4842, "udp"}, {"opcua-tls", {NULL}, 4843, "tcp"}, {"opcua-tls", {NULL}, 4843, "udp"}, {"gw-log", {NULL}, 4844, "tcp"}, {"gw-log", {NULL}, 4844, "udp"}, {"wcr-remlib", {NULL}, 4845, "tcp"}, {"wcr-remlib", {NULL}, 4845, "udp"}, {"contamac_icm", {NULL}, 4846, "tcp"}, {"contamac_icm", {NULL}, 4846, "udp"}, {"wfc", {NULL}, 4847, "tcp"}, {"wfc", {NULL}, 4847, "udp"}, {"appserv-http", {NULL}, 4848, "tcp"}, {"appserv-http", {NULL}, 4848, "udp"}, {"appserv-https", {NULL}, 4849, "tcp"}, {"appserv-https", {NULL}, 4849, "udp"}, {"sun-as-nodeagt", {NULL}, 4850, "tcp"}, {"sun-as-nodeagt", {NULL}, 4850, "udp"}, {"derby-repli", {NULL}, 4851, "tcp"}, {"derby-repli", {NULL}, 4851, "udp"}, {"unify-debug", {NULL}, 4867, "tcp"}, {"unify-debug", {NULL}, 4867, "udp"}, {"phrelay", {NULL}, 4868, "tcp"}, {"phrelay", {NULL}, 4868, "udp"}, {"phrelaydbg", {NULL}, 4869, "tcp"}, {"phrelaydbg", {NULL}, 4869, "udp"}, {"cc-tracking", {NULL}, 4870, "tcp"}, {"cc-tracking", {NULL}, 4870, "udp"}, {"wired", {NULL}, 4871, "tcp"}, {"wired", {NULL}, 4871, "udp"}, {"tritium-can", {NULL}, 4876, "tcp"}, {"tritium-can", {NULL}, 4876, "udp"}, {"lmcs", {NULL}, 4877, "tcp"}, {"lmcs", {NULL}, 4877, "udp"}, {"inst-discovery", {NULL}, 4878, "udp"}, {"wsdl-event", {NULL}, 4879, "tcp"}, {"hislip", {NULL}, 4880, "tcp"}, {"socp-t", {NULL}, 4881, "udp"}, {"socp-c", {NULL}, 4882, "udp"}, {"wmlserver", {NULL}, 4883, "tcp"}, {"hivestor", {NULL}, 4884, "tcp"}, {"hivestor", {NULL}, 4884, "udp"}, {"abbs", {NULL}, 4885, "tcp"}, {"abbs", {NULL}, 4885, "udp"}, {"lyskom", {NULL}, 4894, "tcp"}, {"lyskom", {NULL}, 4894, "udp"}, {"radmin-port", {NULL}, 4899, "tcp"}, {"radmin-port", {NULL}, 4899, "udp"}, {"hfcs", {NULL}, 4900, "tcp"}, {"hfcs", {NULL}, 4900, "udp"}, {"flr_agent", {NULL}, 4901, "tcp"}, {"magiccontrol", {NULL}, 4902, "tcp"}, {"lutap", {NULL}, 4912, "tcp"}, {"lutcp", {NULL}, 4913, "tcp"}, {"bones", {NULL}, 4914, "tcp"}, {"bones", {NULL}, 4914, "udp"}, {"frcs", {NULL}, 4915, "tcp"}, {"atsc-mh-ssc", {NULL}, 4937, "udp"}, {"eq-office-4940", {NULL}, 4940, "tcp"}, {"eq-office-4940", {NULL}, 4940, "udp"}, {"eq-office-4941", {NULL}, 4941, "tcp"}, {"eq-office-4941", {NULL}, 4941, "udp"}, {"eq-office-4942", {NULL}, 4942, "tcp"}, {"eq-office-4942", {NULL}, 4942, "udp"}, {"munin", {NULL}, 4949, "tcp"}, {"munin", {NULL}, 4949, "udp"}, {"sybasesrvmon", {NULL}, 4950, "tcp"}, {"sybasesrvmon", {NULL}, 4950, "udp"}, {"pwgwims", {NULL}, 4951, "tcp"}, {"pwgwims", {NULL}, 4951, "udp"}, {"sagxtsds", {NULL}, 4952, "tcp"}, {"sagxtsds", {NULL}, 4952, "udp"}, {"dbsyncarbiter", {NULL}, 4953, "tcp"}, {"ccss-qmm", {NULL}, 4969, "tcp"}, {"ccss-qmm", {NULL}, 4969, "udp"}, {"ccss-qsm", {NULL}, 4970, "tcp"}, {"ccss-qsm", {NULL}, 4970, "udp"}, {"webyast", {NULL}, 4984, "tcp"}, {"gerhcs", {NULL}, 4985, "tcp"}, {"mrip", {NULL}, 4986, "tcp"}, {"mrip", {NULL}, 4986, "udp"}, {"smar-se-port1", {NULL}, 4987, "tcp"}, {"smar-se-port1", {NULL}, 4987, "udp"}, {"smar-se-port2", {NULL}, 4988, "tcp"}, {"smar-se-port2", {NULL}, 4988, "udp"}, {"parallel", {NULL}, 4989, "tcp"}, {"parallel", {NULL}, 4989, "udp"}, {"busycal", {NULL}, 4990, "tcp"}, {"busycal", {NULL}, 4990, "udp"}, {"vrt", {NULL}, 4991, "tcp"}, {"vrt", {NULL}, 4991, "udp"}, {"hfcs-manager", {NULL}, 4999, "tcp"}, {"hfcs-manager", {NULL}, 4999, "udp"}, {"commplex-main", {NULL}, 5000, "tcp"}, {"commplex-main", {NULL}, 5000, "udp"}, {"commplex-link", {NULL}, 5001, "tcp"}, {"commplex-link", {NULL}, 5001, "udp"}, {"rfe", {NULL}, 5002, "tcp"}, {"rfe", {NULL}, 5002, "udp"}, {"fmpro-internal", {NULL}, 5003, "tcp"}, {"fmpro-internal", {NULL}, 5003, "udp"}, {"avt-profile-1", {NULL}, 5004, "tcp"}, {"avt-profile-1", {NULL}, 5004, "udp"}, {"avt-profile-1", {NULL}, 5004, "dccp"}, {"avt-profile-2", {NULL}, 5005, "tcp"}, {"avt-profile-2", {NULL}, 5005, "udp"}, {"avt-profile-2", {NULL}, 5005, "dccp"}, {"wsm-server", {NULL}, 5006, "tcp"}, {"wsm-server", {NULL}, 5006, "udp"}, {"wsm-server-ssl", {NULL}, 5007, "tcp"}, {"wsm-server-ssl", {NULL}, 5007, "udp"}, {"synapsis-edge", {NULL}, 5008, "tcp"}, {"synapsis-edge", {NULL}, 5008, "udp"}, {"winfs", {NULL}, 5009, "tcp"}, {"winfs", {NULL}, 5009, "udp"}, {"telelpathstart", {NULL}, 5010, "tcp"}, {"telelpathstart", {NULL}, 5010, "udp"}, {"telelpathattack", {NULL}, 5011, "tcp"}, {"telelpathattack", {NULL}, 5011, "udp"}, {"nsp", {NULL}, 5012, "tcp"}, {"nsp", {NULL}, 5012, "udp"}, {"fmpro-v6", {NULL}, 5013, "tcp"}, {"fmpro-v6", {NULL}, 5013, "udp"}, {"onpsocket", {NULL}, 5014, "udp"}, {"fmwp", {NULL}, 5015, "tcp"}, {"zenginkyo-1", {NULL}, 5020, "tcp"}, {"zenginkyo-1", {NULL}, 5020, "udp"}, {"zenginkyo-2", {NULL}, 5021, "tcp"}, {"zenginkyo-2", {NULL}, 5021, "udp"}, {"mice", {NULL}, 5022, "tcp"}, {"mice", {NULL}, 5022, "udp"}, {"htuilsrv", {NULL}, 5023, "tcp"}, {"htuilsrv", {NULL}, 5023, "udp"}, {"scpi-telnet", {NULL}, 5024, "tcp"}, {"scpi-telnet", {NULL}, 5024, "udp"}, {"scpi-raw", {NULL}, 5025, "tcp"}, {"scpi-raw", {NULL}, 5025, "udp"}, {"strexec-d", {NULL}, 5026, "tcp"}, {"strexec-d", {NULL}, 5026, "udp"}, {"strexec-s", {NULL}, 5027, "tcp"}, {"strexec-s", {NULL}, 5027, "udp"}, {"qvr", {NULL}, 5028, "tcp"}, {"infobright", {NULL}, 5029, "tcp"}, {"infobright", {NULL}, 5029, "udp"}, {"surfpass", {NULL}, 5030, "tcp"}, {"surfpass", {NULL}, 5030, "udp"}, {"dmp", {NULL}, 5031, "udp"}, {"asnaacceler8db", {NULL}, 5042, "tcp"}, {"asnaacceler8db", {NULL}, 5042, "udp"}, {"swxadmin", {NULL}, 5043, "tcp"}, {"swxadmin", {NULL}, 5043, "udp"}, {"lxi-evntsvc", {NULL}, 5044, "tcp"}, {"lxi-evntsvc", {NULL}, 5044, "udp"}, {"osp", {NULL}, 5045, "tcp"}, {"vpm-udp", {NULL}, 5046, "udp"}, {"iscape", {NULL}, 5047, "udp"}, {"texai", {NULL}, 5048, "tcp"}, {"ivocalize", {NULL}, 5049, "tcp"}, {"ivocalize", {NULL}, 5049, "udp"}, {"mmcc", {NULL}, 5050, "tcp"}, {"mmcc", {NULL}, 5050, "udp"}, {"ita-agent", {NULL}, 5051, "tcp"}, {"ita-agent", {NULL}, 5051, "udp"}, {"ita-manager", {NULL}, 5052, "tcp"}, {"ita-manager", {NULL}, 5052, "udp"}, {"rlm", {NULL}, 5053, "tcp"}, {"rlm-admin", {NULL}, 5054, "tcp"}, {"unot", {NULL}, 5055, "tcp"}, {"unot", {NULL}, 5055, "udp"}, {"intecom-ps1", {NULL}, 5056, "tcp"}, {"intecom-ps1", {NULL}, 5056, "udp"}, {"intecom-ps2", {NULL}, 5057, "tcp"}, {"intecom-ps2", {NULL}, 5057, "udp"}, {"locus-disc", {NULL}, 5058, "udp"}, {"sds", {NULL}, 5059, "tcp"}, {"sds", {NULL}, 5059, "udp"}, {"sip", {NULL}, 5060, "tcp"}, {"sip", {NULL}, 5060, "udp"}, {"sip-tls", {NULL}, 5061, "tcp"}, {"sip-tls", {NULL}, 5061, "udp"}, {"na-localise", {NULL}, 5062, "tcp"}, {"na-localise", {NULL}, 5062, "udp"}, {"csrpc", {NULL}, 5063, "tcp"}, {"ca-1", {NULL}, 5064, "tcp"}, {"ca-1", {NULL}, 5064, "udp"}, {"ca-2", {NULL}, 5065, "tcp"}, {"ca-2", {NULL}, 5065, "udp"}, {"stanag-5066", {NULL}, 5066, "tcp"}, {"stanag-5066", {NULL}, 5066, "udp"}, {"authentx", {NULL}, 5067, "tcp"}, {"authentx", {NULL}, 5067, "udp"}, {"bitforestsrv", {NULL}, 5068, "tcp"}, {"i-net-2000-npr", {NULL}, 5069, "tcp"}, {"i-net-2000-npr", {NULL}, 5069, "udp"}, {"vtsas", {NULL}, 5070, "tcp"}, {"vtsas", {NULL}, 5070, "udp"}, {"powerschool", {NULL}, 5071, "tcp"}, {"powerschool", {NULL}, 5071, "udp"}, {"ayiya", {NULL}, 5072, "tcp"}, {"ayiya", {NULL}, 5072, "udp"}, {"tag-pm", {NULL}, 5073, "tcp"}, {"tag-pm", {NULL}, 5073, "udp"}, {"alesquery", {NULL}, 5074, "tcp"}, {"alesquery", {NULL}, 5074, "udp"}, {"cp-spxrpts", {NULL}, 5079, "udp"}, {"onscreen", {NULL}, 5080, "tcp"}, {"onscreen", {NULL}, 5080, "udp"}, {"sdl-ets", {NULL}, 5081, "tcp"}, {"sdl-ets", {NULL}, 5081, "udp"}, {"qcp", {NULL}, 5082, "tcp"}, {"qcp", {NULL}, 5082, "udp"}, {"qfp", {NULL}, 5083, "tcp"}, {"qfp", {NULL}, 5083, "udp"}, {"llrp", {NULL}, 5084, "tcp"}, {"llrp", {NULL}, 5084, "udp"}, {"encrypted-llrp", {NULL}, 5085, "tcp"}, {"encrypted-llrp", {NULL}, 5085, "udp"}, {"aprigo-cs", {NULL}, 5086, "tcp"}, {"car", {NULL}, 5090, "sctp"}, {"cxtp", {NULL}, 5091, "sctp"}, {"magpie", {NULL}, 5092, "udp"}, {"sentinel-lm", {NULL}, 5093, "tcp"}, {"sentinel-lm", {NULL}, 5093, "udp"}, {"hart-ip", {NULL}, 5094, "tcp"}, {"hart-ip", {NULL}, 5094, "udp"}, {"sentlm-srv2srv", {NULL}, 5099, "tcp"}, {"sentlm-srv2srv", {NULL}, 5099, "udp"}, {"socalia", {NULL}, 5100, "tcp"}, {"socalia", {NULL}, 5100, "udp"}, {"talarian-tcp", {NULL}, 5101, "tcp"}, {"talarian-udp", {NULL}, 5101, "udp"}, {"oms-nonsecure", {NULL}, 5102, "tcp"}, {"oms-nonsecure", {NULL}, 5102, "udp"}, {"actifio-c2c", {NULL}, 5103, "tcp"}, {"tinymessage", {NULL}, 5104, "udp"}, {"hughes-ap", {NULL}, 5105, "udp"}, {"taep-as-svc", {NULL}, 5111, "tcp"}, {"taep-as-svc", {NULL}, 5111, "udp"}, {"pm-cmdsvr", {NULL}, 5112, "tcp"}, {"pm-cmdsvr", {NULL}, 5112, "udp"}, {"ev-services", {NULL}, 5114, "tcp"}, {"autobuild", {NULL}, 5115, "tcp"}, {"emb-proj-cmd", {NULL}, 5116, "udp"}, {"gradecam", {NULL}, 5117, "tcp"}, {"nbt-pc", {NULL}, 5133, "tcp"}, {"nbt-pc", {NULL}, 5133, "udp"}, {"ppactivation", {NULL}, 5134, "tcp"}, {"erp-scale", {NULL}, 5135, "tcp"}, {"minotaur-sa", {NULL}, 5136, "udp"}, {"ctsd", {NULL}, 5137, "tcp"}, {"ctsd", {NULL}, 5137, "udp"}, {"rmonitor_secure", {NULL}, 5145, "tcp"}, {"rmonitor_secure", {NULL}, 5145, "udp"}, {"social-alarm", {NULL}, 5146, "tcp"}, {"atmp", {NULL}, 5150, "tcp"}, {"atmp", {NULL}, 5150, "udp"}, {"esri_sde", {NULL}, 5151, "tcp"}, {"esri_sde", {NULL}, 5151, "udp"}, {"sde-discovery", {NULL}, 5152, "tcp"}, {"sde-discovery", {NULL}, 5152, "udp"}, {"toruxserver", {NULL}, 5153, "tcp"}, {"bzflag", {NULL}, 5154, "tcp"}, {"bzflag", {NULL}, 5154, "udp"}, {"asctrl-agent", {NULL}, 5155, "tcp"}, {"asctrl-agent", {NULL}, 5155, "udp"}, {"rugameonline", {NULL}, 5156, "tcp"}, {"mediat", {NULL}, 5157, "tcp"}, {"snmpssh", {NULL}, 5161, "tcp"}, {"snmpssh-trap", {NULL}, 5162, "tcp"}, {"sbackup", {NULL}, 5163, "tcp"}, {"vpa", {NULL}, 5164, "tcp"}, {"vpa-disc", {NULL}, 5164, "udp"}, {"ife_icorp", {NULL}, 5165, "tcp"}, {"ife_icorp", {NULL}, 5165, "udp"}, {"winpcs", {NULL}, 5166, "tcp"}, {"winpcs", {NULL}, 5166, "udp"}, {"scte104", {NULL}, 5167, "tcp"}, {"scte104", {NULL}, 5167, "udp"}, {"scte30", {NULL}, 5168, "tcp"}, {"scte30", {NULL}, 5168, "udp"}, {"aol", {NULL}, 5190, "tcp"}, {"aol", {NULL}, 5190, "udp"}, {"aol-1", {NULL}, 5191, "tcp"}, {"aol-1", {NULL}, 5191, "udp"}, {"aol-2", {NULL}, 5192, "tcp"}, {"aol-2", {NULL}, 5192, "udp"}, {"aol-3", {NULL}, 5193, "tcp"}, {"aol-3", {NULL}, 5193, "udp"}, {"cpscomm", {NULL}, 5194, "tcp"}, {"targus-getdata", {NULL}, 5200, "tcp"}, {"targus-getdata", {NULL}, 5200, "udp"}, {"targus-getdata1", {NULL}, 5201, "tcp"}, {"targus-getdata1", {NULL}, 5201, "udp"}, {"targus-getdata2", {NULL}, 5202, "tcp"}, {"targus-getdata2", {NULL}, 5202, "udp"}, {"targus-getdata3", {NULL}, 5203, "tcp"}, {"targus-getdata3", {NULL}, 5203, "udp"}, {"3exmp", {NULL}, 5221, "tcp"}, {"xmpp-client", {NULL}, 5222, "tcp"}, {"hpvirtgrp", {NULL}, 5223, "tcp"}, {"hpvirtgrp", {NULL}, 5223, "udp"}, {"hpvirtctrl", {NULL}, 5224, "tcp"}, {"hpvirtctrl", {NULL}, 5224, "udp"}, {"hp-server", {NULL}, 5225, "tcp"}, {"hp-server", {NULL}, 5225, "udp"}, {"hp-status", {NULL}, 5226, "tcp"}, {"hp-status", {NULL}, 5226, "udp"}, {"perfd", {NULL}, 5227, "tcp"}, {"perfd", {NULL}, 5227, "udp"}, {"hpvroom", {NULL}, 5228, "tcp"}, {"csedaemon", {NULL}, 5232, "tcp"}, {"enfs", {NULL}, 5233, "tcp"}, {"eenet", {NULL}, 5234, "tcp"}, {"eenet", {NULL}, 5234, "udp"}, {"galaxy-network", {NULL}, 5235, "tcp"}, {"galaxy-network", {NULL}, 5235, "udp"}, {"padl2sim", {NULL}, 5236, "tcp"}, {"padl2sim", {NULL}, 5236, "udp"}, {"mnet-discovery", {NULL}, 5237, "tcp"}, {"mnet-discovery", {NULL}, 5237, "udp"}, {"downtools", {NULL}, 5245, "tcp"}, {"downtools-disc", {NULL}, 5245, "udp"}, {"capwap-control", {NULL}, 5246, "udp"}, {"capwap-data", {NULL}, 5247, "udp"}, {"caacws", {NULL}, 5248, "tcp"}, {"caacws", {NULL}, 5248, "udp"}, {"caaclang2", {NULL}, 5249, "tcp"}, {"caaclang2", {NULL}, 5249, "udp"}, {"soagateway", {NULL}, 5250, "tcp"}, {"soagateway", {NULL}, 5250, "udp"}, {"caevms", {NULL}, 5251, "tcp"}, {"caevms", {NULL}, 5251, "udp"}, {"movaz-ssc", {NULL}, 5252, "tcp"}, {"movaz-ssc", {NULL}, 5252, "udp"}, {"kpdp", {NULL}, 5253, "tcp"}, {"3com-njack-1", {NULL}, 5264, "tcp"}, {"3com-njack-1", {NULL}, 5264, "udp"}, {"3com-njack-2", {NULL}, 5265, "tcp"}, {"3com-njack-2", {NULL}, 5265, "udp"}, {"xmpp-server", {NULL}, 5269, "tcp"}, {"xmp", {NULL}, 5270, "tcp"}, {"xmp", {NULL}, 5270, "udp"}, {"cuelink", {NULL}, 5271, "tcp"}, {"cuelink-disc", {NULL}, 5271, "udp"}, {"pk", {NULL}, 5272, "tcp"}, {"pk", {NULL}, 5272, "udp"}, {"xmpp-bosh", {NULL}, 5280, "tcp"}, {"undo-lm", {NULL}, 5281, "tcp"}, {"transmit-port", {NULL}, 5282, "tcp"}, {"transmit-port", {NULL}, 5282, "udp"}, {"presence", {NULL}, 5298, "tcp"}, {"presence", {NULL}, 5298, "udp"}, {"nlg-data", {NULL}, 5299, "tcp"}, {"nlg-data", {NULL}, 5299, "udp"}, {"hacl-hb", {NULL}, 5300, "tcp"}, {"hacl-hb", {NULL}, 5300, "udp"}, {"hacl-gs", {NULL}, 5301, "tcp"}, {"hacl-gs", {NULL}, 5301, "udp"}, {"hacl-cfg", {NULL}, 5302, "tcp"}, {"hacl-cfg", {NULL}, 5302, "udp"}, {"hacl-probe", {NULL}, 5303, "tcp"}, {"hacl-probe", {NULL}, 5303, "udp"}, {"hacl-local", {NULL}, 5304, "tcp"}, {"hacl-local", {NULL}, 5304, "udp"}, {"hacl-test", {NULL}, 5305, "tcp"}, {"hacl-test", {NULL}, 5305, "udp"}, {"sun-mc-grp", {NULL}, 5306, "tcp"}, {"sun-mc-grp", {NULL}, 5306, "udp"}, {"sco-aip", {NULL}, 5307, "tcp"}, {"sco-aip", {NULL}, 5307, "udp"}, {"cfengine", {NULL}, 5308, "tcp"}, {"cfengine", {NULL}, 5308, "udp"}, {"jprinter", {NULL}, 5309, "tcp"}, {"jprinter", {NULL}, 5309, "udp"}, {"outlaws", {NULL}, 5310, "tcp"}, {"outlaws", {NULL}, 5310, "udp"}, {"permabit-cs", {NULL}, 5312, "tcp"}, {"permabit-cs", {NULL}, 5312, "udp"}, {"rrdp", {NULL}, 5313, "tcp"}, {"rrdp", {NULL}, 5313, "udp"}, {"opalis-rbt-ipc", {NULL}, 5314, "tcp"}, {"opalis-rbt-ipc", {NULL}, 5314, "udp"}, {"hacl-poll", {NULL}, 5315, "tcp"}, {"hacl-poll", {NULL}, 5315, "udp"}, {"hpdevms", {NULL}, 5316, "tcp"}, {"hpdevms", {NULL}, 5316, "udp"}, {"bsfserver-zn", {NULL}, 5320, "tcp"}, {"bsfsvr-zn-ssl", {NULL}, 5321, "tcp"}, {"kfserver", {NULL}, 5343, "tcp"}, {"kfserver", {NULL}, 5343, "udp"}, {"xkotodrcp", {NULL}, 5344, "tcp"}, {"xkotodrcp", {NULL}, 5344, "udp"}, {"stuns", {NULL}, 5349, "tcp"}, {"stuns", {NULL}, 5349, "udp"}, {"turns", {NULL}, 5349, "tcp"}, {"turns", {NULL}, 5349, "udp"}, {"stun-behaviors", {NULL}, 5349, "tcp"}, {"stun-behaviors", {NULL}, 5349, "udp"}, {"nat-pmp-status", {NULL}, 5350, "tcp"}, {"nat-pmp-status", {NULL}, 5350, "udp"}, {"nat-pmp", {NULL}, 5351, "tcp"}, {"nat-pmp", {NULL}, 5351, "udp"}, {"dns-llq", {NULL}, 5352, "tcp"}, {"dns-llq", {NULL}, 5352, "udp"}, {"mdns", {NULL}, 5353, "tcp"}, {"mdns", {NULL}, 5353, "udp"}, {"mdnsresponder", {NULL}, 5354, "tcp"}, {"mdnsresponder", {NULL}, 5354, "udp"}, {"llmnr", {NULL}, 5355, "tcp"}, {"llmnr", {NULL}, 5355, "udp"}, {"ms-smlbiz", {NULL}, 5356, "tcp"}, {"ms-smlbiz", {NULL}, 5356, "udp"}, {"wsdapi", {NULL}, 5357, "tcp"}, {"wsdapi", {NULL}, 5357, "udp"}, {"wsdapi-s", {NULL}, 5358, "tcp"}, {"wsdapi-s", {NULL}, 5358, "udp"}, {"ms-alerter", {NULL}, 5359, "tcp"}, {"ms-alerter", {NULL}, 5359, "udp"}, {"ms-sideshow", {NULL}, 5360, "tcp"}, {"ms-sideshow", {NULL}, 5360, "udp"}, {"ms-s-sideshow", {NULL}, 5361, "tcp"}, {"ms-s-sideshow", {NULL}, 5361, "udp"}, {"serverwsd2", {NULL}, 5362, "tcp"}, {"serverwsd2", {NULL}, 5362, "udp"}, {"net-projection", {NULL}, 5363, "tcp"}, {"net-projection", {NULL}, 5363, "udp"}, {"stresstester", {NULL}, 5397, "tcp"}, {"stresstester", {NULL}, 5397, "udp"}, {"elektron-admin", {NULL}, 5398, "tcp"}, {"elektron-admin", {NULL}, 5398, "udp"}, {"securitychase", {NULL}, 5399, "tcp"}, {"securitychase", {NULL}, 5399, "udp"}, {"excerpt", {NULL}, 5400, "tcp"}, {"excerpt", {NULL}, 5400, "udp"}, {"excerpts", {NULL}, 5401, "tcp"}, {"excerpts", {NULL}, 5401, "udp"}, {"mftp", {NULL}, 5402, "tcp"}, {"mftp", {NULL}, 5402, "udp"}, {"hpoms-ci-lstn", {NULL}, 5403, "tcp"}, {"hpoms-ci-lstn", {NULL}, 5403, "udp"}, {"hpoms-dps-lstn", {NULL}, 5404, "tcp"}, {"hpoms-dps-lstn", {NULL}, 5404, "udp"}, {"netsupport", {NULL}, 5405, "tcp"}, {"netsupport", {NULL}, 5405, "udp"}, {"systemics-sox", {NULL}, 5406, "tcp"}, {"systemics-sox", {NULL}, 5406, "udp"}, {"foresyte-clear", {NULL}, 5407, "tcp"}, {"foresyte-clear", {NULL}, 5407, "udp"}, {"foresyte-sec", {NULL}, 5408, "tcp"}, {"foresyte-sec", {NULL}, 5408, "udp"}, {"salient-dtasrv", {NULL}, 5409, "tcp"}, {"salient-dtasrv", {NULL}, 5409, "udp"}, {"salient-usrmgr", {NULL}, 5410, "tcp"}, {"salient-usrmgr", {NULL}, 5410, "udp"}, {"actnet", {NULL}, 5411, "tcp"}, {"actnet", {NULL}, 5411, "udp"}, {"continuus", {NULL}, 5412, "tcp"}, {"continuus", {NULL}, 5412, "udp"}, {"wwiotalk", {NULL}, 5413, "tcp"}, {"wwiotalk", {NULL}, 5413, "udp"}, {"statusd", {NULL}, 5414, "tcp"}, {"statusd", {NULL}, 5414, "udp"}, {"ns-server", {NULL}, 5415, "tcp"}, {"ns-server", {NULL}, 5415, "udp"}, {"sns-gateway", {NULL}, 5416, "tcp"}, {"sns-gateway", {NULL}, 5416, "udp"}, {"sns-agent", {NULL}, 5417, "tcp"}, {"sns-agent", {NULL}, 5417, "udp"}, {"mcntp", {NULL}, 5418, "tcp"}, {"mcntp", {NULL}, 5418, "udp"}, {"dj-ice", {NULL}, 5419, "tcp"}, {"dj-ice", {NULL}, 5419, "udp"}, {"cylink-c", {NULL}, 5420, "tcp"}, {"cylink-c", {NULL}, 5420, "udp"}, {"netsupport2", {NULL}, 5421, "tcp"}, {"netsupport2", {NULL}, 5421, "udp"}, {"salient-mux", {NULL}, 5422, "tcp"}, {"salient-mux", {NULL}, 5422, "udp"}, {"virtualuser", {NULL}, 5423, "tcp"}, {"virtualuser", {NULL}, 5423, "udp"}, {"beyond-remote", {NULL}, 5424, "tcp"}, {"beyond-remote", {NULL}, 5424, "udp"}, {"br-channel", {NULL}, 5425, "tcp"}, {"br-channel", {NULL}, 5425, "udp"}, {"devbasic", {NULL}, 5426, "tcp"}, {"devbasic", {NULL}, 5426, "udp"}, {"sco-peer-tta", {NULL}, 5427, "tcp"}, {"sco-peer-tta", {NULL}, 5427, "udp"}, {"telaconsole", {NULL}, 5428, "tcp"}, {"telaconsole", {NULL}, 5428, "udp"}, {"base", {NULL}, 5429, "tcp"}, {"base", {NULL}, 5429, "udp"}, {"radec-corp", {NULL}, 5430, "tcp"}, {"radec-corp", {NULL}, 5430, "udp"}, {"park-agent", {NULL}, 5431, "tcp"}, {"park-agent", {NULL}, 5431, "udp"}, {"postgresql", {NULL}, 5432, "tcp"}, {"postgresql", {NULL}, 5432, "udp"}, {"pyrrho", {NULL}, 5433, "tcp"}, {"pyrrho", {NULL}, 5433, "udp"}, {"sgi-arrayd", {NULL}, 5434, "tcp"}, {"sgi-arrayd", {NULL}, 5434, "udp"}, {"sceanics", {NULL}, 5435, "tcp"}, {"sceanics", {NULL}, 5435, "udp"}, {"pmip6-cntl", {NULL}, 5436, "udp"}, {"pmip6-data", {NULL}, 5437, "udp"}, {"spss", {NULL}, 5443, "tcp"}, {"spss", {NULL}, 5443, "udp"}, {"surebox", {NULL}, 5453, "tcp"}, {"surebox", {NULL}, 5453, "udp"}, {"apc-5454", {NULL}, 5454, "tcp"}, {"apc-5454", {NULL}, 5454, "udp"}, {"apc-5455", {NULL}, 5455, "tcp"}, {"apc-5455", {NULL}, 5455, "udp"}, {"apc-5456", {NULL}, 5456, "tcp"}, {"apc-5456", {NULL}, 5456, "udp"}, {"silkmeter", {NULL}, 5461, "tcp"}, {"silkmeter", {NULL}, 5461, "udp"}, {"ttl-publisher", {NULL}, 5462, "tcp"}, {"ttl-publisher", {NULL}, 5462, "udp"}, {"ttlpriceproxy", {NULL}, 5463, "tcp"}, {"ttlpriceproxy", {NULL}, 5463, "udp"}, {"quailnet", {NULL}, 5464, "tcp"}, {"quailnet", {NULL}, 5464, "udp"}, {"netops-broker", {NULL}, 5465, "tcp"}, {"netops-broker", {NULL}, 5465, "udp"}, {"fcp-addr-srvr1", {NULL}, 5500, "tcp"}, {"fcp-addr-srvr1", {NULL}, 5500, "udp"}, {"fcp-addr-srvr2", {NULL}, 5501, "tcp"}, {"fcp-addr-srvr2", {NULL}, 5501, "udp"}, {"fcp-srvr-inst1", {NULL}, 5502, "tcp"}, {"fcp-srvr-inst1", {NULL}, 5502, "udp"}, {"fcp-srvr-inst2", {NULL}, 5503, "tcp"}, {"fcp-srvr-inst2", {NULL}, 5503, "udp"}, {"fcp-cics-gw1", {NULL}, 5504, "tcp"}, {"fcp-cics-gw1", {NULL}, 5504, "udp"}, {"checkoutdb", {NULL}, 5505, "tcp"}, {"checkoutdb", {NULL}, 5505, "udp"}, {"amc", {NULL}, 5506, "tcp"}, {"amc", {NULL}, 5506, "udp"}, {"sgi-eventmond", {NULL}, 5553, "tcp"}, {"sgi-eventmond", {NULL}, 5553, "udp"}, {"sgi-esphttp", {NULL}, 5554, "tcp"}, {"sgi-esphttp", {NULL}, 5554, "udp"}, {"personal-agent", {NULL}, 5555, "tcp"}, {"personal-agent", {NULL}, 5555, "udp"}, {"freeciv", {NULL}, 5556, "tcp"}, {"freeciv", {NULL}, 5556, "udp"}, {"farenet", {NULL}, 5557, "tcp"}, {"westec-connect", {NULL}, 5566, "tcp"}, {"m-oap", {NULL}, 5567, "tcp"}, {"m-oap", {NULL}, 5567, "udp"}, {"sdt", {NULL}, 5568, "tcp"}, {"sdt", {NULL}, 5568, "udp"}, {"sdmmp", {NULL}, 5573, "tcp"}, {"sdmmp", {NULL}, 5573, "udp"}, {"lsi-bobcat", {NULL}, 5574, "tcp"}, {"ora-oap", {NULL}, 5575, "tcp"}, {"fdtracks", {NULL}, 5579, "tcp"}, {"tmosms0", {NULL}, 5580, "tcp"}, {"tmosms0", {NULL}, 5580, "udp"}, {"tmosms1", {NULL}, 5581, "tcp"}, {"tmosms1", {NULL}, 5581, "udp"}, {"fac-restore", {NULL}, 5582, "tcp"}, {"fac-restore", {NULL}, 5582, "udp"}, {"tmo-icon-sync", {NULL}, 5583, "tcp"}, {"tmo-icon-sync", {NULL}, 5583, "udp"}, {"bis-web", {NULL}, 5584, "tcp"}, {"bis-web", {NULL}, 5584, "udp"}, {"bis-sync", {NULL}, 5585, "tcp"}, {"bis-sync", {NULL}, 5585, "udp"}, {"ininmessaging", {NULL}, 5597, "tcp"}, {"ininmessaging", {NULL}, 5597, "udp"}, {"mctfeed", {NULL}, 5598, "tcp"}, {"mctfeed", {NULL}, 5598, "udp"}, {"esinstall", {NULL}, 5599, "tcp"}, {"esinstall", {NULL}, 5599, "udp"}, {"esmmanager", {NULL}, 5600, "tcp"}, {"esmmanager", {NULL}, 5600, "udp"}, {"esmagent", {NULL}, 5601, "tcp"}, {"esmagent", {NULL}, 5601, "udp"}, {"a1-msc", {NULL}, 5602, "tcp"}, {"a1-msc", {NULL}, 5602, "udp"}, {"a1-bs", {NULL}, 5603, "tcp"}, {"a1-bs", {NULL}, 5603, "udp"}, {"a3-sdunode", {NULL}, 5604, "tcp"}, {"a3-sdunode", {NULL}, 5604, "udp"}, {"a4-sdunode", {NULL}, 5605, "tcp"}, {"a4-sdunode", {NULL}, 5605, "udp"}, {"ninaf", {NULL}, 5627, "tcp"}, {"ninaf", {NULL}, 5627, "udp"}, {"htrust", {NULL}, 5628, "tcp"}, {"htrust", {NULL}, 5628, "udp"}, {"symantec-sfdb", {NULL}, 5629, "tcp"}, {"symantec-sfdb", {NULL}, 5629, "udp"}, {"precise-comm", {NULL}, 5630, "tcp"}, {"precise-comm", {NULL}, 5630, "udp"}, {"pcanywheredata", {NULL}, 5631, "tcp"}, {"pcanywheredata", {NULL}, 5631, "udp"}, {"pcanywherestat", {NULL}, 5632, "tcp"}, {"pcanywherestat", {NULL}, 5632, "udp"}, {"beorl", {NULL}, 5633, "tcp"}, {"beorl", {NULL}, 5633, "udp"}, {"xprtld", {NULL}, 5634, "tcp"}, {"xprtld", {NULL}, 5634, "udp"}, {"sfmsso", {NULL}, 5635, "tcp"}, {"sfm-db-server", {NULL}, 5636, "tcp"}, {"cssc", {NULL}, 5637, "tcp"}, {"amqps", {NULL}, 5671, "tcp"}, {"amqps", {NULL}, 5671, "udp"}, {"amqp", {NULL}, 5672, "tcp"}, {"amqp", {NULL}, 5672, "udp"}, {"amqp", {NULL}, 5672, "sctp"}, {"jms", {NULL}, 5673, "tcp"}, {"jms", {NULL}, 5673, "udp"}, {"hyperscsi-port", {NULL}, 5674, "tcp"}, {"hyperscsi-port", {NULL}, 5674, "udp"}, {"v5ua", {NULL}, 5675, "tcp"}, {"v5ua", {NULL}, 5675, "udp"}, {"v5ua", {NULL}, 5675, "sctp"}, {"raadmin", {NULL}, 5676, "tcp"}, {"raadmin", {NULL}, 5676, "udp"}, {"questdb2-lnchr", {NULL}, 5677, "tcp"}, {"questdb2-lnchr", {NULL}, 5677, "udp"}, {"rrac", {NULL}, 5678, "tcp"}, {"rrac", {NULL}, 5678, "udp"}, {"dccm", {NULL}, 5679, "tcp"}, {"dccm", {NULL}, 5679, "udp"}, {"auriga-router", {NULL}, 5680, "tcp"}, {"auriga-router", {NULL}, 5680, "udp"}, {"ncxcp", {NULL}, 5681, "tcp"}, {"ncxcp", {NULL}, 5681, "udp"}, {"brightcore", {NULL}, 5682, "udp"}, {"ggz", {NULL}, 5688, "tcp"}, {"ggz", {NULL}, 5688, "udp"}, {"qmvideo", {NULL}, 5689, "tcp"}, {"qmvideo", {NULL}, 5689, "udp"}, {"proshareaudio", {NULL}, 5713, "tcp"}, {"proshareaudio", {NULL}, 5713, "udp"}, {"prosharevideo", {NULL}, 5714, "tcp"}, {"prosharevideo", {NULL}, 5714, "udp"}, {"prosharedata", {NULL}, 5715, "tcp"}, {"prosharedata", {NULL}, 5715, "udp"}, {"prosharerequest", {NULL}, 5716, "tcp"}, {"prosharerequest", {NULL}, 5716, "udp"}, {"prosharenotify", {NULL}, 5717, "tcp"}, {"prosharenotify", {NULL}, 5717, "udp"}, {"dpm", {NULL}, 5718, "tcp"}, {"dpm", {NULL}, 5718, "udp"}, {"dpm-agent", {NULL}, 5719, "tcp"}, {"dpm-agent", {NULL}, 5719, "udp"}, {"ms-licensing", {NULL}, 5720, "tcp"}, {"ms-licensing", {NULL}, 5720, "udp"}, {"dtpt", {NULL}, 5721, "tcp"}, {"dtpt", {NULL}, 5721, "udp"}, {"msdfsr", {NULL}, 5722, "tcp"}, {"msdfsr", {NULL}, 5722, "udp"}, {"omhs", {NULL}, 5723, "tcp"}, {"omhs", {NULL}, 5723, "udp"}, {"omsdk", {NULL}, 5724, "tcp"}, {"omsdk", {NULL}, 5724, "udp"}, {"ms-ilm", {NULL}, 5725, "tcp"}, {"ms-ilm-sts", {NULL}, 5726, "tcp"}, {"asgenf", {NULL}, 5727, "tcp"}, {"io-dist-data", {NULL}, 5728, "tcp"}, {"io-dist-group", {NULL}, 5728, "udp"}, {"openmail", {NULL}, 5729, "tcp"}, {"openmail", {NULL}, 5729, "udp"}, {"unieng", {NULL}, 5730, "tcp"}, {"unieng", {NULL}, 5730, "udp"}, {"ida-discover1", {NULL}, 5741, "tcp"}, {"ida-discover1", {NULL}, 5741, "udp"}, {"ida-discover2", {NULL}, 5742, "tcp"}, {"ida-discover2", {NULL}, 5742, "udp"}, {"watchdoc-pod", {NULL}, 5743, "tcp"}, {"watchdoc-pod", {NULL}, 5743, "udp"}, {"watchdoc", {NULL}, 5744, "tcp"}, {"watchdoc", {NULL}, 5744, "udp"}, {"fcopy-server", {NULL}, 5745, "tcp"}, {"fcopy-server", {NULL}, 5745, "udp"}, {"fcopys-server", {NULL}, 5746, "tcp"}, {"fcopys-server", {NULL}, 5746, "udp"}, {"tunatic", {NULL}, 5747, "tcp"}, {"tunatic", {NULL}, 5747, "udp"}, {"tunalyzer", {NULL}, 5748, "tcp"}, {"tunalyzer", {NULL}, 5748, "udp"}, {"rscd", {NULL}, 5750, "tcp"}, {"rscd", {NULL}, 5750, "udp"}, {"openmailg", {NULL}, 5755, "tcp"}, {"openmailg", {NULL}, 5755, "udp"}, {"x500ms", {NULL}, 5757, "tcp"}, {"x500ms", {NULL}, 5757, "udp"}, {"openmailns", {NULL}, 5766, "tcp"}, {"openmailns", {NULL}, 5766, "udp"}, {"s-openmail", {NULL}, 5767, "tcp"}, {"s-openmail", {NULL}, 5767, "udp"}, {"openmailpxy", {NULL}, 5768, "tcp"}, {"openmailpxy", {NULL}, 5768, "udp"}, {"spramsca", {NULL}, 5769, "tcp"}, {"spramsca", {NULL}, 5769, "udp"}, {"spramsd", {NULL}, 5770, "tcp"}, {"spramsd", {NULL}, 5770, "udp"}, {"netagent", {NULL}, 5771, "tcp"}, {"netagent", {NULL}, 5771, "udp"}, {"dali-port", {NULL}, 5777, "tcp"}, {"dali-port", {NULL}, 5777, "udp"}, {"vts-rpc", {NULL}, 5780, "tcp"}, {"3par-evts", {NULL}, 5781, "tcp"}, {"3par-evts", {NULL}, 5781, "udp"}, {"3par-mgmt", {NULL}, 5782, "tcp"}, {"3par-mgmt", {NULL}, 5782, "udp"}, {"3par-mgmt-ssl", {NULL}, 5783, "tcp"}, {"3par-mgmt-ssl", {NULL}, 5783, "udp"}, {"ibar", {NULL}, 5784, "udp"}, {"3par-rcopy", {NULL}, 5785, "tcp"}, {"3par-rcopy", {NULL}, 5785, "udp"}, {"cisco-redu", {NULL}, 5786, "udp"}, {"waascluster", {NULL}, 5787, "udp"}, {"xtreamx", {NULL}, 5793, "tcp"}, {"xtreamx", {NULL}, 5793, "udp"}, {"spdp", {NULL}, 5794, "udp"}, {"icmpd", {NULL}, 5813, "tcp"}, {"icmpd", {NULL}, 5813, "udp"}, {"spt-automation", {NULL}, 5814, "tcp"}, {"spt-automation", {NULL}, 5814, "udp"}, {"wherehoo", {NULL}, 5859, "tcp"}, {"wherehoo", {NULL}, 5859, "udp"}, {"ppsuitemsg", {NULL}, 5863, "tcp"}, {"ppsuitemsg", {NULL}, 5863, "udp"}, {"rfb", {NULL}, 5900, "tcp"}, {"rfb", {NULL}, 5900, "udp"}, {"cm", {NULL}, 5910, "tcp"}, {"cm", {NULL}, 5910, "udp"}, {"cpdlc", {NULL}, 5911, "tcp"}, {"cpdlc", {NULL}, 5911, "udp"}, {"fis", {NULL}, 5912, "tcp"}, {"fis", {NULL}, 5912, "udp"}, {"ads-c", {NULL}, 5913, "tcp"}, {"ads-c", {NULL}, 5913, "udp"}, {"indy", {NULL}, 5963, "tcp"}, {"indy", {NULL}, 5963, "udp"}, {"mppolicy-v5", {NULL}, 5968, "tcp"}, {"mppolicy-v5", {NULL}, 5968, "udp"}, {"mppolicy-mgr", {NULL}, 5969, "tcp"}, {"mppolicy-mgr", {NULL}, 5969, "udp"}, {"couchdb", {NULL}, 5984, "tcp"}, {"couchdb", {NULL}, 5984, "udp"}, {"wsman", {NULL}, 5985, "tcp"}, {"wsman", {NULL}, 5985, "udp"}, {"wsmans", {NULL}, 5986, "tcp"}, {"wsmans", {NULL}, 5986, "udp"}, {"wbem-rmi", {NULL}, 5987, "tcp"}, {"wbem-rmi", {NULL}, 5987, "udp"}, {"wbem-http", {NULL}, 5988, "tcp"}, {"wbem-http", {NULL}, 5988, "udp"}, {"wbem-https", {NULL}, 5989, "tcp"}, {"wbem-https", {NULL}, 5989, "udp"}, {"wbem-exp-https", {NULL}, 5990, "tcp"}, {"wbem-exp-https", {NULL}, 5990, "udp"}, {"nuxsl", {NULL}, 5991, "tcp"}, {"nuxsl", {NULL}, 5991, "udp"}, {"consul-insight", {NULL}, 5992, "tcp"}, {"consul-insight", {NULL}, 5992, "udp"}, {"cvsup", {NULL}, 5999, "tcp"}, {"cvsup", {NULL}, 5999, "udp"}, {"ndl-ahp-svc", {NULL}, 6064, "tcp"}, {"ndl-ahp-svc", {NULL}, 6064, "udp"}, {"winpharaoh", {NULL}, 6065, "tcp"}, {"winpharaoh", {NULL}, 6065, "udp"}, {"ewctsp", {NULL}, 6066, "tcp"}, {"ewctsp", {NULL}, 6066, "udp"}, {"gsmp", {NULL}, 6068, "tcp"}, {"gsmp", {NULL}, 6068, "udp"}, {"trip", {NULL}, 6069, "tcp"}, {"trip", {NULL}, 6069, "udp"}, {"messageasap", {NULL}, 6070, "tcp"}, {"messageasap", {NULL}, 6070, "udp"}, {"ssdtp", {NULL}, 6071, "tcp"}, {"ssdtp", {NULL}, 6071, "udp"}, {"diagnose-proc", {NULL}, 6072, "tcp"}, {"diagnose-proc", {NULL}, 6072, "udp"}, {"directplay8", {NULL}, 6073, "tcp"}, {"directplay8", {NULL}, 6073, "udp"}, {"max", {NULL}, 6074, "tcp"}, {"max", {NULL}, 6074, "udp"}, {"dpm-acm", {NULL}, 6075, "tcp"}, {"miami-bcast", {NULL}, 6083, "udp"}, {"p2p-sip", {NULL}, 6084, "tcp"}, {"konspire2b", {NULL}, 6085, "tcp"}, {"konspire2b", {NULL}, 6085, "udp"}, {"pdtp", {NULL}, 6086, "tcp"}, {"pdtp", {NULL}, 6086, "udp"}, {"ldss", {NULL}, 6087, "tcp"}, {"ldss", {NULL}, 6087, "udp"}, {"raxa-mgmt", {NULL}, 6099, "tcp"}, {"synchronet-db", {NULL}, 6100, "tcp"}, {"synchronet-db", {NULL}, 6100, "udp"}, {"synchronet-rtc", {NULL}, 6101, "tcp"}, {"synchronet-rtc", {NULL}, 6101, "udp"}, {"synchronet-upd", {NULL}, 6102, "tcp"}, {"synchronet-upd", {NULL}, 6102, "udp"}, {"rets", {NULL}, 6103, "tcp"}, {"rets", {NULL}, 6103, "udp"}, {"dbdb", {NULL}, 6104, "tcp"}, {"dbdb", {NULL}, 6104, "udp"}, {"primaserver", {NULL}, 6105, "tcp"}, {"primaserver", {NULL}, 6105, "udp"}, {"mpsserver", {NULL}, 6106, "tcp"}, {"mpsserver", {NULL}, 6106, "udp"}, {"etc-control", {NULL}, 6107, "tcp"}, {"etc-control", {NULL}, 6107, "udp"}, {"sercomm-scadmin", {NULL}, 6108, "tcp"}, {"sercomm-scadmin", {NULL}, 6108, "udp"}, {"globecast-id", {NULL}, 6109, "tcp"}, {"globecast-id", {NULL}, 6109, "udp"}, {"softcm", {NULL}, 6110, "tcp"}, {"softcm", {NULL}, 6110, "udp"}, {"spc", {NULL}, 6111, "tcp"}, {"spc", {NULL}, 6111, "udp"}, {"dtspcd", {NULL}, 6112, "tcp"}, {"dtspcd", {NULL}, 6112, "udp"}, {"dayliteserver", {NULL}, 6113, "tcp"}, {"wrspice", {NULL}, 6114, "tcp"}, {"xic", {NULL}, 6115, "tcp"}, {"xtlserv", {NULL}, 6116, "tcp"}, {"daylitetouch", {NULL}, 6117, "tcp"}, {"spdy", {NULL}, 6121, "tcp"}, {"bex-webadmin", {NULL}, 6122, "tcp"}, {"bex-webadmin", {NULL}, 6122, "udp"}, {"backup-express", {NULL}, 6123, "tcp"}, {"backup-express", {NULL}, 6123, "udp"}, {"pnbs", {NULL}, 6124, "tcp"}, {"pnbs", {NULL}, 6124, "udp"}, {"nbt-wol", {NULL}, 6133, "tcp"}, {"nbt-wol", {NULL}, 6133, "udp"}, {"pulsonixnls", {NULL}, 6140, "tcp"}, {"pulsonixnls", {NULL}, 6140, "udp"}, {"meta-corp", {NULL}, 6141, "tcp"}, {"meta-corp", {NULL}, 6141, "udp"}, {"aspentec-lm", {NULL}, 6142, "tcp"}, {"aspentec-lm", {NULL}, 6142, "udp"}, {"watershed-lm", {NULL}, 6143, "tcp"}, {"watershed-lm", {NULL}, 6143, "udp"}, {"statsci1-lm", {NULL}, 6144, "tcp"}, {"statsci1-lm", {NULL}, 6144, "udp"}, {"statsci2-lm", {NULL}, 6145, "tcp"}, {"statsci2-lm", {NULL}, 6145, "udp"}, {"lonewolf-lm", {NULL}, 6146, "tcp"}, {"lonewolf-lm", {NULL}, 6146, "udp"}, {"montage-lm", {NULL}, 6147, "tcp"}, {"montage-lm", {NULL}, 6147, "udp"}, {"ricardo-lm", {NULL}, 6148, "tcp"}, {"ricardo-lm", {NULL}, 6148, "udp"}, {"tal-pod", {NULL}, 6149, "tcp"}, {"tal-pod", {NULL}, 6149, "udp"}, {"efb-aci", {NULL}, 6159, "tcp"}, {"patrol-ism", {NULL}, 6161, "tcp"}, {"patrol-ism", {NULL}, 6161, "udp"}, {"patrol-coll", {NULL}, 6162, "tcp"}, {"patrol-coll", {NULL}, 6162, "udp"}, {"pscribe", {NULL}, 6163, "tcp"}, {"pscribe", {NULL}, 6163, "udp"}, {"lm-x", {NULL}, 6200, "tcp"}, {"lm-x", {NULL}, 6200, "udp"}, {"radmind", {NULL}, 6222, "tcp"}, {"radmind", {NULL}, 6222, "udp"}, {"jeol-nsdtp-1", {NULL}, 6241, "tcp"}, {"jeol-nsddp-1", {NULL}, 6241, "udp"}, {"jeol-nsdtp-2", {NULL}, 6242, "tcp"}, {"jeol-nsddp-2", {NULL}, 6242, "udp"}, {"jeol-nsdtp-3", {NULL}, 6243, "tcp"}, {"jeol-nsddp-3", {NULL}, 6243, "udp"}, {"jeol-nsdtp-4", {NULL}, 6244, "tcp"}, {"jeol-nsddp-4", {NULL}, 6244, "udp"}, {"tl1-raw-ssl", {NULL}, 6251, "tcp"}, {"tl1-raw-ssl", {NULL}, 6251, "udp"}, {"tl1-ssh", {NULL}, 6252, "tcp"}, {"tl1-ssh", {NULL}, 6252, "udp"}, {"crip", {NULL}, 6253, "tcp"}, {"crip", {NULL}, 6253, "udp"}, {"gld", {NULL}, 6267, "tcp"}, {"grid", {NULL}, 6268, "tcp"}, {"grid", {NULL}, 6268, "udp"}, {"grid-alt", {NULL}, 6269, "tcp"}, {"grid-alt", {NULL}, 6269, "udp"}, {"bmc-grx", {NULL}, 6300, "tcp"}, {"bmc-grx", {NULL}, 6300, "udp"}, {"bmc_ctd_ldap", {NULL}, 6301, "tcp"}, {"bmc_ctd_ldap", {NULL}, 6301, "udp"}, {"ufmp", {NULL}, 6306, "tcp"}, {"ufmp", {NULL}, 6306, "udp"}, {"scup", {NULL}, 6315, "tcp"}, {"scup-disc", {NULL}, 6315, "udp"}, {"abb-escp", {NULL}, 6316, "tcp"}, {"abb-escp", {NULL}, 6316, "udp"}, {"repsvc", {NULL}, 6320, "tcp"}, {"repsvc", {NULL}, 6320, "udp"}, {"emp-server1", {NULL}, 6321, "tcp"}, {"emp-server1", {NULL}, 6321, "udp"}, {"emp-server2", {NULL}, 6322, "tcp"}, {"emp-server2", {NULL}, 6322, "udp"}, {"sflow", {NULL}, 6343, "tcp"}, {"sflow", {NULL}, 6343, "udp"}, {"gnutella-svc", {NULL}, 6346, "tcp"}, {"gnutella-svc", {NULL}, 6346, "udp"}, {"gnutella-rtr", {NULL}, 6347, "tcp"}, {"gnutella-rtr", {NULL}, 6347, "udp"}, {"adap", {NULL}, 6350, "tcp"}, {"adap", {NULL}, 6350, "udp"}, {"pmcs", {NULL}, 6355, "tcp"}, {"pmcs", {NULL}, 6355, "udp"}, {"metaedit-mu", {NULL}, 6360, "tcp"}, {"metaedit-mu", {NULL}, 6360, "udp"}, {"metaedit-se", {NULL}, 6370, "tcp"}, {"metaedit-se", {NULL}, 6370, "udp"}, {"metatude-mds", {NULL}, 6382, "tcp"}, {"metatude-mds", {NULL}, 6382, "udp"}, {"clariion-evr01", {NULL}, 6389, "tcp"}, {"clariion-evr01", {NULL}, 6389, "udp"}, {"metaedit-ws", {NULL}, 6390, "tcp"}, {"metaedit-ws", {NULL}, 6390, "udp"}, {"faxcomservice", {NULL}, 6417, "tcp"}, {"faxcomservice", {NULL}, 6417, "udp"}, {"syserverremote", {NULL}, 6418, "tcp"}, {"svdrp", {NULL}, 6419, "tcp"}, {"nim-vdrshell", {NULL}, 6420, "tcp"}, {"nim-vdrshell", {NULL}, 6420, "udp"}, {"nim-wan", {NULL}, 6421, "tcp"}, {"nim-wan", {NULL}, 6421, "udp"}, {"pgbouncer", {NULL}, 6432, "tcp"}, {"sun-sr-https", {NULL}, 6443, "tcp"}, {"sun-sr-https", {NULL}, 6443, "udp"}, {"sge_qmaster", {NULL}, 6444, "tcp"}, {"sge_qmaster", {NULL}, 6444, "udp"}, {"sge_execd", {NULL}, 6445, "tcp"}, {"sge_execd", {NULL}, 6445, "udp"}, {"mysql-proxy", {NULL}, 6446, "tcp"}, {"mysql-proxy", {NULL}, 6446, "udp"}, {"skip-cert-recv", {NULL}, 6455, "tcp"}, {"skip-cert-send", {NULL}, 6456, "udp"}, {"lvision-lm", {NULL}, 6471, "tcp"}, {"lvision-lm", {NULL}, 6471, "udp"}, {"sun-sr-http", {NULL}, 6480, "tcp"}, {"sun-sr-http", {NULL}, 6480, "udp"}, {"servicetags", {NULL}, 6481, "tcp"}, {"servicetags", {NULL}, 6481, "udp"}, {"ldoms-mgmt", {NULL}, 6482, "tcp"}, {"ldoms-mgmt", {NULL}, 6482, "udp"}, {"SunVTS-RMI", {NULL}, 6483, "tcp"}, {"SunVTS-RMI", {NULL}, 6483, "udp"}, {"sun-sr-jms", {NULL}, 6484, "tcp"}, {"sun-sr-jms", {NULL}, 6484, "udp"}, {"sun-sr-iiop", {NULL}, 6485, "tcp"}, {"sun-sr-iiop", {NULL}, 6485, "udp"}, {"sun-sr-iiops", {NULL}, 6486, "tcp"}, {"sun-sr-iiops", {NULL}, 6486, "udp"}, {"sun-sr-iiop-aut", {NULL}, 6487, "tcp"}, {"sun-sr-iiop-aut", {NULL}, 6487, "udp"}, {"sun-sr-jmx", {NULL}, 6488, "tcp"}, {"sun-sr-jmx", {NULL}, 6488, "udp"}, {"sun-sr-admin", {NULL}, 6489, "tcp"}, {"sun-sr-admin", {NULL}, 6489, "udp"}, {"boks", {NULL}, 6500, "tcp"}, {"boks", {NULL}, 6500, "udp"}, {"boks_servc", {NULL}, 6501, "tcp"}, {"boks_servc", {NULL}, 6501, "udp"}, {"boks_servm", {NULL}, 6502, "tcp"}, {"boks_servm", {NULL}, 6502, "udp"}, {"boks_clntd", {NULL}, 6503, "tcp"}, {"boks_clntd", {NULL}, 6503, "udp"}, {"badm_priv", {NULL}, 6505, "tcp"}, {"badm_priv", {NULL}, 6505, "udp"}, {"badm_pub", {NULL}, 6506, "tcp"}, {"badm_pub", {NULL}, 6506, "udp"}, {"bdir_priv", {NULL}, 6507, "tcp"}, {"bdir_priv", {NULL}, 6507, "udp"}, {"bdir_pub", {NULL}, 6508, "tcp"}, {"bdir_pub", {NULL}, 6508, "udp"}, {"mgcs-mfp-port", {NULL}, 6509, "tcp"}, {"mgcs-mfp-port", {NULL}, 6509, "udp"}, {"mcer-port", {NULL}, 6510, "tcp"}, {"mcer-port", {NULL}, 6510, "udp"}, {"netconf-tls", {NULL}, 6513, "tcp"}, {"syslog-tls", {NULL}, 6514, "tcp"}, {"syslog-tls", {NULL}, 6514, "udp"}, {"syslog-tls", {NULL}, 6514, "dccp"}, {"elipse-rec", {NULL}, 6515, "tcp"}, {"elipse-rec", {NULL}, 6515, "udp"}, {"lds-distrib", {NULL}, 6543, "tcp"}, {"lds-distrib", {NULL}, 6543, "udp"}, {"lds-dump", {NULL}, 6544, "tcp"}, {"lds-dump", {NULL}, 6544, "udp"}, {"apc-6547", {NULL}, 6547, "tcp"}, {"apc-6547", {NULL}, 6547, "udp"}, {"apc-6548", {NULL}, 6548, "tcp"}, {"apc-6548", {NULL}, 6548, "udp"}, {"apc-6549", {NULL}, 6549, "tcp"}, {"apc-6549", {NULL}, 6549, "udp"}, {"fg-sysupdate", {NULL}, 6550, "tcp"}, {"fg-sysupdate", {NULL}, 6550, "udp"}, {"sum", {NULL}, 6551, "tcp"}, {"sum", {NULL}, 6551, "udp"}, {"xdsxdm", {NULL}, 6558, "tcp"}, {"xdsxdm", {NULL}, 6558, "udp"}, {"sane-port", {NULL}, 6566, "tcp"}, {"sane-port", {NULL}, 6566, "udp"}, {"esp", {NULL}, 6567, "tcp"}, {"esp", {NULL}, 6567, "udp"}, {"canit_store", {NULL}, 6568, "tcp"}, {"rp-reputation", {NULL}, 6568, "udp"}, {"affiliate", {NULL}, 6579, "tcp"}, {"affiliate", {NULL}, 6579, "udp"}, {"parsec-master", {NULL}, 6580, "tcp"}, {"parsec-master", {NULL}, 6580, "udp"}, {"parsec-peer", {NULL}, 6581, "tcp"}, {"parsec-peer", {NULL}, 6581, "udp"}, {"parsec-game", {NULL}, 6582, "tcp"}, {"parsec-game", {NULL}, 6582, "udp"}, {"joaJewelSuite", {NULL}, 6583, "tcp"}, {"joaJewelSuite", {NULL}, 6583, "udp"}, {"mshvlm", {NULL}, 6600, "tcp"}, {"mstmg-sstp", {NULL}, 6601, "tcp"}, {"wsscomfrmwk", {NULL}, 6602, "tcp"}, {"odette-ftps", {NULL}, 6619, "tcp"}, {"odette-ftps", {NULL}, 6619, "udp"}, {"kftp-data", {NULL}, 6620, "tcp"}, {"kftp-data", {NULL}, 6620, "udp"}, {"kftp", {NULL}, 6621, "tcp"}, {"kftp", {NULL}, 6621, "udp"}, {"mcftp", {NULL}, 6622, "tcp"}, {"mcftp", {NULL}, 6622, "udp"}, {"ktelnet", {NULL}, 6623, "tcp"}, {"ktelnet", {NULL}, 6623, "udp"}, {"datascaler-db", {NULL}, 6624, "tcp"}, {"datascaler-ctl", {NULL}, 6625, "tcp"}, {"wago-service", {NULL}, 6626, "tcp"}, {"wago-service", {NULL}, 6626, "udp"}, {"nexgen", {NULL}, 6627, "tcp"}, {"nexgen", {NULL}, 6627, "udp"}, {"afesc-mc", {NULL}, 6628, "tcp"}, {"afesc-mc", {NULL}, 6628, "udp"}, {"mxodbc-connect", {NULL}, 6632, "tcp"}, {"pcs-sf-ui-man", {NULL}, 6655, "tcp"}, {"emgmsg", {NULL}, 6656, "tcp"}, {"palcom-disc", {NULL}, 6657, "udp"}, {"vocaltec-gold", {NULL}, 6670, "tcp"}, {"vocaltec-gold", {NULL}, 6670, "udp"}, {"p4p-portal", {NULL}, 6671, "tcp"}, {"p4p-portal", {NULL}, 6671, "udp"}, {"vision_server", {NULL}, 6672, "tcp"}, {"vision_server", {NULL}, 6672, "udp"}, {"vision_elmd", {NULL}, 6673, "tcp"}, {"vision_elmd", {NULL}, 6673, "udp"}, {"vfbp", {NULL}, 6678, "tcp"}, {"vfbp-disc", {NULL}, 6678, "udp"}, {"osaut", {NULL}, 6679, "tcp"}, {"osaut", {NULL}, 6679, "udp"}, {"clever-ctrace", {NULL}, 6687, "tcp"}, {"clever-tcpip", {NULL}, 6688, "tcp"}, {"tsa", {NULL}, 6689, "tcp"}, {"tsa", {NULL}, 6689, "udp"}, {"babel", {NULL}, 6697, "udp"}, {"kti-icad-srvr", {NULL}, 6701, "tcp"}, {"kti-icad-srvr", {NULL}, 6701, "udp"}, {"e-design-net", {NULL}, 6702, "tcp"}, {"e-design-net", {NULL}, 6702, "udp"}, {"e-design-web", {NULL}, 6703, "tcp"}, {"e-design-web", {NULL}, 6703, "udp"}, {"frc-hp", {NULL}, 6704, "sctp"}, {"frc-mp", {NULL}, 6705, "sctp"}, {"frc-lp", {NULL}, 6706, "sctp"}, {"ibprotocol", {NULL}, 6714, "tcp"}, {"ibprotocol", {NULL}, 6714, "udp"}, {"fibotrader-com", {NULL}, 6715, "tcp"}, {"fibotrader-com", {NULL}, 6715, "udp"}, {"bmc-perf-agent", {NULL}, 6767, "tcp"}, {"bmc-perf-agent", {NULL}, 6767, "udp"}, {"bmc-perf-mgrd", {NULL}, 6768, "tcp"}, {"bmc-perf-mgrd", {NULL}, 6768, "udp"}, {"adi-gxp-srvprt", {NULL}, 6769, "tcp"}, {"adi-gxp-srvprt", {NULL}, 6769, "udp"}, {"plysrv-http", {NULL}, 6770, "tcp"}, {"plysrv-http", {NULL}, 6770, "udp"}, {"plysrv-https", {NULL}, 6771, "tcp"}, {"plysrv-https", {NULL}, 6771, "udp"}, {"dgpf-exchg", {NULL}, 6785, "tcp"}, {"dgpf-exchg", {NULL}, 6785, "udp"}, {"smc-jmx", {NULL}, 6786, "tcp"}, {"smc-jmx", {NULL}, 6786, "udp"}, {"smc-admin", {NULL}, 6787, "tcp"}, {"smc-admin", {NULL}, 6787, "udp"}, {"smc-http", {NULL}, 6788, "tcp"}, {"smc-http", {NULL}, 6788, "udp"}, {"smc-https", {NULL}, 6789, "tcp"}, {"smc-https", {NULL}, 6789, "udp"}, {"hnmp", {NULL}, 6790, "tcp"}, {"hnmp", {NULL}, 6790, "udp"}, {"hnm", {NULL}, 6791, "tcp"}, {"hnm", {NULL}, 6791, "udp"}, {"acnet", {NULL}, 6801, "tcp"}, {"acnet", {NULL}, 6801, "udp"}, {"pentbox-sim", {NULL}, 6817, "tcp"}, {"ambit-lm", {NULL}, 6831, "tcp"}, {"ambit-lm", {NULL}, 6831, "udp"}, {"netmo-default", {NULL}, 6841, "tcp"}, {"netmo-default", {NULL}, 6841, "udp"}, {"netmo-http", {NULL}, 6842, "tcp"}, {"netmo-http", {NULL}, 6842, "udp"}, {"iccrushmore", {NULL}, 6850, "tcp"}, {"iccrushmore", {NULL}, 6850, "udp"}, {"acctopus-cc", {NULL}, 6868, "tcp"}, {"acctopus-st", {NULL}, 6868, "udp"}, {"muse", {NULL}, 6888, "tcp"}, {"muse", {NULL}, 6888, "udp"}, {"jetstream", {NULL}, 6901, "tcp"}, {"xsmsvc", {NULL}, 6936, "tcp"}, {"xsmsvc", {NULL}, 6936, "udp"}, {"bioserver", {NULL}, 6946, "tcp"}, {"bioserver", {NULL}, 6946, "udp"}, {"otlp", {NULL}, 6951, "tcp"}, {"otlp", {NULL}, 6951, "udp"}, {"jmact3", {NULL}, 6961, "tcp"}, {"jmact3", {NULL}, 6961, "udp"}, {"jmevt2", {NULL}, 6962, "tcp"}, {"jmevt2", {NULL}, 6962, "udp"}, {"swismgr1", {NULL}, 6963, "tcp"}, {"swismgr1", {NULL}, 6963, "udp"}, {"swismgr2", {NULL}, 6964, "tcp"}, {"swismgr2", {NULL}, 6964, "udp"}, {"swistrap", {NULL}, 6965, "tcp"}, {"swistrap", {NULL}, 6965, "udp"}, {"swispol", {NULL}, 6966, "tcp"}, {"swispol", {NULL}, 6966, "udp"}, {"acmsoda", {NULL}, 6969, "tcp"}, {"acmsoda", {NULL}, 6969, "udp"}, {"MobilitySrv", {NULL}, 6997, "tcp"}, {"MobilitySrv", {NULL}, 6997, "udp"}, {"iatp-highpri", {NULL}, 6998, "tcp"}, {"iatp-highpri", {NULL}, 6998, "udp"}, {"iatp-normalpri", {NULL}, 6999, "tcp"}, {"iatp-normalpri", {NULL}, 6999, "udp"}, {"afs3-fileserver", {NULL}, 7000, "tcp"}, {"afs3-fileserver", {NULL}, 7000, "udp"}, {"afs3-callback", {NULL}, 7001, "tcp"}, {"afs3-callback", {NULL}, 7001, "udp"}, {"afs3-prserver", {NULL}, 7002, "tcp"}, {"afs3-prserver", {NULL}, 7002, "udp"}, {"afs3-vlserver", {NULL}, 7003, "tcp"}, {"afs3-vlserver", {NULL}, 7003, "udp"}, {"afs3-kaserver", {NULL}, 7004, "tcp"}, {"afs3-kaserver", {NULL}, 7004, "udp"}, {"afs3-volser", {NULL}, 7005, "tcp"}, {"afs3-volser", {NULL}, 7005, "udp"}, {"afs3-errors", {NULL}, 7006, "tcp"}, {"afs3-errors", {NULL}, 7006, "udp"}, {"afs3-bos", {NULL}, 7007, "tcp"}, {"afs3-bos", {NULL}, 7007, "udp"}, {"afs3-update", {NULL}, 7008, "tcp"}, {"afs3-update", {NULL}, 7008, "udp"}, {"afs3-rmtsys", {NULL}, 7009, "tcp"}, {"afs3-rmtsys", {NULL}, 7009, "udp"}, {"ups-onlinet", {NULL}, 7010, "tcp"}, {"ups-onlinet", {NULL}, 7010, "udp"}, {"talon-disc", {NULL}, 7011, "tcp"}, {"talon-disc", {NULL}, 7011, "udp"}, {"talon-engine", {NULL}, 7012, "tcp"}, {"talon-engine", {NULL}, 7012, "udp"}, {"microtalon-dis", {NULL}, 7013, "tcp"}, {"microtalon-dis", {NULL}, 7013, "udp"}, {"microtalon-com", {NULL}, 7014, "tcp"}, {"microtalon-com", {NULL}, 7014, "udp"}, {"talon-webserver", {NULL}, 7015, "tcp"}, {"talon-webserver", {NULL}, 7015, "udp"}, {"dpserve", {NULL}, 7020, "tcp"}, {"dpserve", {NULL}, 7020, "udp"}, {"dpserveadmin", {NULL}, 7021, "tcp"}, {"dpserveadmin", {NULL}, 7021, "udp"}, {"ctdp", {NULL}, 7022, "tcp"}, {"ctdp", {NULL}, 7022, "udp"}, {"ct2nmcs", {NULL}, 7023, "tcp"}, {"ct2nmcs", {NULL}, 7023, "udp"}, {"vmsvc", {NULL}, 7024, "tcp"}, {"vmsvc", {NULL}, 7024, "udp"}, {"vmsvc-2", {NULL}, 7025, "tcp"}, {"vmsvc-2", {NULL}, 7025, "udp"}, {"op-probe", {NULL}, 7030, "tcp"}, {"op-probe", {NULL}, 7030, "udp"}, {"arcp", {NULL}, 7070, "tcp"}, {"arcp", {NULL}, 7070, "udp"}, {"iwg1", {NULL}, 7071, "tcp"}, {"iwg1", {NULL}, 7071, "udp"}, {"empowerid", {NULL}, 7080, "tcp"}, {"empowerid", {NULL}, 7080, "udp"}, {"lazy-ptop", {NULL}, 7099, "tcp"}, {"lazy-ptop", {NULL}, 7099, "udp"}, {"font-service", {NULL}, 7100, "tcp"}, {"font-service", {NULL}, 7100, "udp"}, {"elcn", {NULL}, 7101, "tcp"}, {"elcn", {NULL}, 7101, "udp"}, {"aes-x170", {NULL}, 7107, "udp"}, {"virprot-lm", {NULL}, 7121, "tcp"}, {"virprot-lm", {NULL}, 7121, "udp"}, {"scenidm", {NULL}, 7128, "tcp"}, {"scenidm", {NULL}, 7128, "udp"}, {"scenccs", {NULL}, 7129, "tcp"}, {"scenccs", {NULL}, 7129, "udp"}, {"cabsm-comm", {NULL}, 7161, "tcp"}, {"cabsm-comm", {NULL}, 7161, "udp"}, {"caistoragemgr", {NULL}, 7162, "tcp"}, {"caistoragemgr", {NULL}, 7162, "udp"}, {"cacsambroker", {NULL}, 7163, "tcp"}, {"cacsambroker", {NULL}, 7163, "udp"}, {"fsr", {NULL}, 7164, "tcp"}, {"fsr", {NULL}, 7164, "udp"}, {"doc-server", {NULL}, 7165, "tcp"}, {"doc-server", {NULL}, 7165, "udp"}, {"aruba-server", {NULL}, 7166, "tcp"}, {"aruba-server", {NULL}, 7166, "udp"}, {"casrmagent", {NULL}, 7167, "tcp"}, {"cnckadserver", {NULL}, 7168, "tcp"}, {"ccag-pib", {NULL}, 7169, "tcp"}, {"ccag-pib", {NULL}, 7169, "udp"}, {"nsrp", {NULL}, 7170, "tcp"}, {"nsrp", {NULL}, 7170, "udp"}, {"drm-production", {NULL}, 7171, "tcp"}, {"drm-production", {NULL}, 7171, "udp"}, {"zsecure", {NULL}, 7173, "tcp"}, {"clutild", {NULL}, 7174, "tcp"}, {"clutild", {NULL}, 7174, "udp"}, {"fodms", {NULL}, 7200, "tcp"}, {"fodms", {NULL}, 7200, "udp"}, {"dlip", {NULL}, 7201, "tcp"}, {"dlip", {NULL}, 7201, "udp"}, {"ramp", {NULL}, 7227, "tcp"}, {"ramp", {NULL}, 7227, "udp"}, {"citrixupp", {NULL}, 7228, "tcp"}, {"citrixuppg", {NULL}, 7229, "tcp"}, {"pads", {NULL}, 7237, "tcp"}, {"cnap", {NULL}, 7262, "tcp"}, {"cnap", {NULL}, 7262, "udp"}, {"watchme-7272", {NULL}, 7272, "tcp"}, {"watchme-7272", {NULL}, 7272, "udp"}, {"oma-rlp", {NULL}, 7273, "tcp"}, {"oma-rlp", {NULL}, 7273, "udp"}, {"oma-rlp-s", {NULL}, 7274, "tcp"}, {"oma-rlp-s", {NULL}, 7274, "udp"}, {"oma-ulp", {NULL}, 7275, "tcp"}, {"oma-ulp", {NULL}, 7275, "udp"}, {"oma-ilp", {NULL}, 7276, "tcp"}, {"oma-ilp", {NULL}, 7276, "udp"}, {"oma-ilp-s", {NULL}, 7277, "tcp"}, {"oma-ilp-s", {NULL}, 7277, "udp"}, {"oma-dcdocbs", {NULL}, 7278, "tcp"}, {"oma-dcdocbs", {NULL}, 7278, "udp"}, {"ctxlic", {NULL}, 7279, "tcp"}, {"ctxlic", {NULL}, 7279, "udp"}, {"itactionserver1", {NULL}, 7280, "tcp"}, {"itactionserver1", {NULL}, 7280, "udp"}, {"itactionserver2", {NULL}, 7281, "tcp"}, {"itactionserver2", {NULL}, 7281, "udp"}, {"mzca-action", {NULL}, 7282, "tcp"}, {"mzca-alert", {NULL}, 7282, "udp"}, {"lcm-server", {NULL}, 7365, "tcp"}, {"lcm-server", {NULL}, 7365, "udp"}, {"mindfilesys", {NULL}, 7391, "tcp"}, {"mindfilesys", {NULL}, 7391, "udp"}, {"mrssrendezvous", {NULL}, 7392, "tcp"}, {"mrssrendezvous", {NULL}, 7392, "udp"}, {"nfoldman", {NULL}, 7393, "tcp"}, {"nfoldman", {NULL}, 7393, "udp"}, {"fse", {NULL}, 7394, "tcp"}, {"fse", {NULL}, 7394, "udp"}, {"winqedit", {NULL}, 7395, "tcp"}, {"winqedit", {NULL}, 7395, "udp"}, {"hexarc", {NULL}, 7397, "tcp"}, {"hexarc", {NULL}, 7397, "udp"}, {"rtps-discovery", {NULL}, 7400, "tcp"}, {"rtps-discovery", {NULL}, 7400, "udp"}, {"rtps-dd-ut", {NULL}, 7401, "tcp"}, {"rtps-dd-ut", {NULL}, 7401, "udp"}, {"rtps-dd-mt", {NULL}, 7402, "tcp"}, {"rtps-dd-mt", {NULL}, 7402, "udp"}, {"ionixnetmon", {NULL}, 7410, "tcp"}, {"ionixnetmon", {NULL}, 7410, "udp"}, {"mtportmon", {NULL}, 7421, "tcp"}, {"mtportmon", {NULL}, 7421, "udp"}, {"pmdmgr", {NULL}, 7426, "tcp"}, {"pmdmgr", {NULL}, 7426, "udp"}, {"oveadmgr", {NULL}, 7427, "tcp"}, {"oveadmgr", {NULL}, 7427, "udp"}, {"ovladmgr", {NULL}, 7428, "tcp"}, {"ovladmgr", {NULL}, 7428, "udp"}, {"opi-sock", {NULL}, 7429, "tcp"}, {"opi-sock", {NULL}, 7429, "udp"}, {"xmpv7", {NULL}, 7430, "tcp"}, {"xmpv7", {NULL}, 7430, "udp"}, {"pmd", {NULL}, 7431, "tcp"}, {"pmd", {NULL}, 7431, "udp"}, {"faximum", {NULL}, 7437, "tcp"}, {"faximum", {NULL}, 7437, "udp"}, {"oracleas-https", {NULL}, 7443, "tcp"}, {"oracleas-https", {NULL}, 7443, "udp"}, {"rise", {NULL}, 7473, "tcp"}, {"rise", {NULL}, 7473, "udp"}, {"telops-lmd", {NULL}, 7491, "tcp"}, {"telops-lmd", {NULL}, 7491, "udp"}, {"silhouette", {NULL}, 7500, "tcp"}, {"silhouette", {NULL}, 7500, "udp"}, {"ovbus", {NULL}, 7501, "tcp"}, {"ovbus", {NULL}, 7501, "udp"}, {"acplt", {NULL}, 7509, "tcp"}, {"ovhpas", {NULL}, 7510, "tcp"}, {"ovhpas", {NULL}, 7510, "udp"}, {"pafec-lm", {NULL}, 7511, "tcp"}, {"pafec-lm", {NULL}, 7511, "udp"}, {"saratoga", {NULL}, 7542, "tcp"}, {"saratoga", {NULL}, 7542, "udp"}, {"atul", {NULL}, 7543, "tcp"}, {"atul", {NULL}, 7543, "udp"}, {"nta-ds", {NULL}, 7544, "tcp"}, {"nta-ds", {NULL}, 7544, "udp"}, {"nta-us", {NULL}, 7545, "tcp"}, {"nta-us", {NULL}, 7545, "udp"}, {"cfs", {NULL}, 7546, "tcp"}, {"cfs", {NULL}, 7546, "udp"}, {"cwmp", {NULL}, 7547, "tcp"}, {"cwmp", {NULL}, 7547, "udp"}, {"tidp", {NULL}, 7548, "tcp"}, {"tidp", {NULL}, 7548, "udp"}, {"nls-tl", {NULL}, 7549, "tcp"}, {"nls-tl", {NULL}, 7549, "udp"}, {"sncp", {NULL}, 7560, "tcp"}, {"sncp", {NULL}, 7560, "udp"}, {"cfw", {NULL}, 7563, "tcp"}, {"vsi-omega", {NULL}, 7566, "tcp"}, {"vsi-omega", {NULL}, 7566, "udp"}, {"dell-eql-asm", {NULL}, 7569, "tcp"}, {"aries-kfinder", {NULL}, 7570, "tcp"}, {"aries-kfinder", {NULL}, 7570, "udp"}, {"sun-lm", {NULL}, 7588, "tcp"}, {"sun-lm", {NULL}, 7588, "udp"}, {"indi", {NULL}, 7624, "tcp"}, {"indi", {NULL}, 7624, "udp"}, {"simco", {NULL}, 7626, "tcp"}, {"simco", {NULL}, 7626, "sctp"}, {"soap-http", {NULL}, 7627, "tcp"}, {"soap-http", {NULL}, 7627, "udp"}, {"zen-pawn", {NULL}, 7628, "tcp"}, {"zen-pawn", {NULL}, 7628, "udp"}, {"xdas", {NULL}, 7629, "tcp"}, {"xdas", {NULL}, 7629, "udp"}, {"hawk", {NULL}, 7630, "tcp"}, {"tesla-sys-msg", {NULL}, 7631, "tcp"}, {"pmdfmgt", {NULL}, 7633, "tcp"}, {"pmdfmgt", {NULL}, 7633, "udp"}, {"cuseeme", {NULL}, 7648, "tcp"}, {"cuseeme", {NULL}, 7648, "udp"}, {"imqstomp", {NULL}, 7672, "tcp"}, {"imqstomps", {NULL}, 7673, "tcp"}, {"imqtunnels", {NULL}, 7674, "tcp"}, {"imqtunnels", {NULL}, 7674, "udp"}, {"imqtunnel", {NULL}, 7675, "tcp"}, {"imqtunnel", {NULL}, 7675, "udp"}, {"imqbrokerd", {NULL}, 7676, "tcp"}, {"imqbrokerd", {NULL}, 7676, "udp"}, {"sun-user-https", {NULL}, 7677, "tcp"}, {"sun-user-https", {NULL}, 7677, "udp"}, {"pando-pub", {NULL}, 7680, "tcp"}, {"pando-pub", {NULL}, 7680, "udp"}, {"collaber", {NULL}, 7689, "tcp"}, {"collaber", {NULL}, 7689, "udp"}, {"klio", {NULL}, 7697, "tcp"}, {"klio", {NULL}, 7697, "udp"}, {"em7-secom", {NULL}, 7700, "tcp"}, {"sync-em7", {NULL}, 7707, "tcp"}, {"sync-em7", {NULL}, 7707, "udp"}, {"scinet", {NULL}, 7708, "tcp"}, {"scinet", {NULL}, 7708, "udp"}, {"medimageportal", {NULL}, 7720, "tcp"}, {"medimageportal", {NULL}, 7720, "udp"}, {"nsdeepfreezectl", {NULL}, 7724, "tcp"}, {"nsdeepfreezectl", {NULL}, 7724, "udp"}, {"nitrogen", {NULL}, 7725, "tcp"}, {"nitrogen", {NULL}, 7725, "udp"}, {"freezexservice", {NULL}, 7726, "tcp"}, {"freezexservice", {NULL}, 7726, "udp"}, {"trident-data", {NULL}, 7727, "tcp"}, {"trident-data", {NULL}, 7727, "udp"}, {"smip", {NULL}, 7734, "tcp"}, {"smip", {NULL}, 7734, "udp"}, {"aiagent", {NULL}, 7738, "tcp"}, {"aiagent", {NULL}, 7738, "udp"}, {"scriptview", {NULL}, 7741, "tcp"}, {"scriptview", {NULL}, 7741, "udp"}, {"msss", {NULL}, 7742, "tcp"}, {"sstp-1", {NULL}, 7743, "tcp"}, {"sstp-1", {NULL}, 7743, "udp"}, {"raqmon-pdu", {NULL}, 7744, "tcp"}, {"raqmon-pdu", {NULL}, 7744, "udp"}, {"prgp", {NULL}, 7747, "tcp"}, {"prgp", {NULL}, 7747, "udp"}, {"cbt", {NULL}, 7777, "tcp"}, {"cbt", {NULL}, 7777, "udp"}, {"interwise", {NULL}, 7778, "tcp"}, {"interwise", {NULL}, 7778, "udp"}, {"vstat", {NULL}, 7779, "tcp"}, {"vstat", {NULL}, 7779, "udp"}, {"accu-lmgr", {NULL}, 7781, "tcp"}, {"accu-lmgr", {NULL}, 7781, "udp"}, {"minivend", {NULL}, 7786, "tcp"}, {"minivend", {NULL}, 7786, "udp"}, {"popup-reminders", {NULL}, 7787, "tcp"}, {"popup-reminders", {NULL}, 7787, "udp"}, {"office-tools", {NULL}, 7789, "tcp"}, {"office-tools", {NULL}, 7789, "udp"}, {"q3ade", {NULL}, 7794, "tcp"}, {"q3ade", {NULL}, 7794, "udp"}, {"pnet-conn", {NULL}, 7797, "tcp"}, {"pnet-conn", {NULL}, 7797, "udp"}, {"pnet-enc", {NULL}, 7798, "tcp"}, {"pnet-enc", {NULL}, 7798, "udp"}, {"altbsdp", {NULL}, 7799, "tcp"}, {"altbsdp", {NULL}, 7799, "udp"}, {"asr", {NULL}, 7800, "tcp"}, {"asr", {NULL}, 7800, "udp"}, {"ssp-client", {NULL}, 7801, "tcp"}, {"ssp-client", {NULL}, 7801, "udp"}, {"rbt-wanopt", {NULL}, 7810, "tcp"}, {"rbt-wanopt", {NULL}, 7810, "udp"}, {"apc-7845", {NULL}, 7845, "tcp"}, {"apc-7845", {NULL}, 7845, "udp"}, {"apc-7846", {NULL}, 7846, "tcp"}, {"apc-7846", {NULL}, 7846, "udp"}, {"mobileanalyzer", {NULL}, 7869, "tcp"}, {"rbt-smc", {NULL}, 7870, "tcp"}, {"pss", {NULL}, 7880, "tcp"}, {"pss", {NULL}, 7880, "udp"}, {"ubroker", {NULL}, 7887, "tcp"}, {"ubroker", {NULL}, 7887, "udp"}, {"mevent", {NULL}, 7900, "tcp"}, {"mevent", {NULL}, 7900, "udp"}, {"tnos-sp", {NULL}, 7901, "tcp"}, {"tnos-sp", {NULL}, 7901, "udp"}, {"tnos-dp", {NULL}, 7902, "tcp"}, {"tnos-dp", {NULL}, 7902, "udp"}, {"tnos-dps", {NULL}, 7903, "tcp"}, {"tnos-dps", {NULL}, 7903, "udp"}, {"qo-secure", {NULL}, 7913, "tcp"}, {"qo-secure", {NULL}, 7913, "udp"}, {"t2-drm", {NULL}, 7932, "tcp"}, {"t2-drm", {NULL}, 7932, "udp"}, {"t2-brm", {NULL}, 7933, "tcp"}, {"t2-brm", {NULL}, 7933, "udp"}, {"supercell", {NULL}, 7967, "tcp"}, {"supercell", {NULL}, 7967, "udp"}, {"micromuse-ncps", {NULL}, 7979, "tcp"}, {"micromuse-ncps", {NULL}, 7979, "udp"}, {"quest-vista", {NULL}, 7980, "tcp"}, {"quest-vista", {NULL}, 7980, "udp"}, {"sossd-collect", {NULL}, 7981, "tcp"}, {"sossd-agent", {NULL}, 7982, "tcp"}, {"sossd-disc", {NULL}, 7982, "udp"}, {"pushns", {NULL}, 7997, "tcp"}, {"usicontentpush", {NULL}, 7998, "udp"}, {"irdmi2", {NULL}, 7999, "tcp"}, {"irdmi2", {NULL}, 7999, "udp"}, {"irdmi", {NULL}, 8000, "tcp"}, {"irdmi", {NULL}, 8000, "udp"}, {"vcom-tunnel", {NULL}, 8001, "tcp"}, {"vcom-tunnel", {NULL}, 8001, "udp"}, {"teradataordbms", {NULL}, 8002, "tcp"}, {"teradataordbms", {NULL}, 8002, "udp"}, {"mcreport", {NULL}, 8003, "tcp"}, {"mcreport", {NULL}, 8003, "udp"}, {"mxi", {NULL}, 8005, "tcp"}, {"mxi", {NULL}, 8005, "udp"}, {"http-alt", {NULL}, 8008, "tcp"}, {"http-alt", {NULL}, 8008, "udp"}, {"qbdb", {NULL}, 8019, "tcp"}, {"qbdb", {NULL}, 8019, "udp"}, {"intu-ec-svcdisc", {NULL}, 8020, "tcp"}, {"intu-ec-svcdisc", {NULL}, 8020, "udp"}, {"intu-ec-client", {NULL}, 8021, "tcp"}, {"intu-ec-client", {NULL}, 8021, "udp"}, {"oa-system", {NULL}, 8022, "tcp"}, {"oa-system", {NULL}, 8022, "udp"}, {"ca-audit-da", {NULL}, 8025, "tcp"}, {"ca-audit-da", {NULL}, 8025, "udp"}, {"ca-audit-ds", {NULL}, 8026, "tcp"}, {"ca-audit-ds", {NULL}, 8026, "udp"}, {"pro-ed", {NULL}, 8032, "tcp"}, {"pro-ed", {NULL}, 8032, "udp"}, {"mindprint", {NULL}, 8033, "tcp"}, {"mindprint", {NULL}, 8033, "udp"}, {"vantronix-mgmt", {NULL}, 8034, "tcp"}, {"vantronix-mgmt", {NULL}, 8034, "udp"}, {"ampify", {NULL}, 8040, "tcp"}, {"ampify", {NULL}, 8040, "udp"}, {"fs-agent", {NULL}, 8042, "tcp"}, {"fs-server", {NULL}, 8043, "tcp"}, {"fs-mgmt", {NULL}, 8044, "tcp"}, {"senomix01", {NULL}, 8052, "tcp"}, {"senomix01", {NULL}, 8052, "udp"}, {"senomix02", {NULL}, 8053, "tcp"}, {"senomix02", {NULL}, 8053, "udp"}, {"senomix03", {NULL}, 8054, "tcp"}, {"senomix03", {NULL}, 8054, "udp"}, {"senomix04", {NULL}, 8055, "tcp"}, {"senomix04", {NULL}, 8055, "udp"}, {"senomix05", {NULL}, 8056, "tcp"}, {"senomix05", {NULL}, 8056, "udp"}, {"senomix06", {NULL}, 8057, "tcp"}, {"senomix06", {NULL}, 8057, "udp"}, {"senomix07", {NULL}, 8058, "tcp"}, {"senomix07", {NULL}, 8058, "udp"}, {"senomix08", {NULL}, 8059, "tcp"}, {"senomix08", {NULL}, 8059, "udp"}, {"gadugadu", {NULL}, 8074, "tcp"}, {"gadugadu", {NULL}, 8074, "udp"}, {"http-alt", {NULL}, 8080, "tcp"}, {"http-alt", {NULL}, 8080, "udp"}, {"sunproxyadmin", {NULL}, 8081, "tcp"}, {"sunproxyadmin", {NULL}, 8081, "udp"}, {"us-cli", {NULL}, 8082, "tcp"}, {"us-cli", {NULL}, 8082, "udp"}, {"us-srv", {NULL}, 8083, "tcp"}, {"us-srv", {NULL}, 8083, "udp"}, {"d-s-n", {NULL}, 8086, "tcp"}, {"d-s-n", {NULL}, 8086, "udp"}, {"simplifymedia", {NULL}, 8087, "tcp"}, {"simplifymedia", {NULL}, 8087, "udp"}, {"radan-http", {NULL}, 8088, "tcp"}, {"radan-http", {NULL}, 8088, "udp"}, {"jamlink", {NULL}, 8091, "tcp"}, {"sac", {NULL}, 8097, "tcp"}, {"sac", {NULL}, 8097, "udp"}, {"xprint-server", {NULL}, 8100, "tcp"}, {"xprint-server", {NULL}, 8100, "udp"}, {"ldoms-migr", {NULL}, 8101, "tcp"}, {"mtl8000-matrix", {NULL}, 8115, "tcp"}, {"mtl8000-matrix", {NULL}, 8115, "udp"}, {"cp-cluster", {NULL}, 8116, "tcp"}, {"cp-cluster", {NULL}, 8116, "udp"}, {"privoxy", {NULL}, 8118, "tcp"}, {"privoxy", {NULL}, 8118, "udp"}, {"apollo-data", {NULL}, 8121, "tcp"}, {"apollo-data", {NULL}, 8121, "udp"}, {"apollo-admin", {NULL}, 8122, "tcp"}, {"apollo-admin", {NULL}, 8122, "udp"}, {"paycash-online", {NULL}, 8128, "tcp"}, {"paycash-online", {NULL}, 8128, "udp"}, {"paycash-wbp", {NULL}, 8129, "tcp"}, {"paycash-wbp", {NULL}, 8129, "udp"}, {"indigo-vrmi", {NULL}, 8130, "tcp"}, {"indigo-vrmi", {NULL}, 8130, "udp"}, {"indigo-vbcp", {NULL}, 8131, "tcp"}, {"indigo-vbcp", {NULL}, 8131, "udp"}, {"dbabble", {NULL}, 8132, "tcp"}, {"dbabble", {NULL}, 8132, "udp"}, {"isdd", {NULL}, 8148, "tcp"}, {"isdd", {NULL}, 8148, "udp"}, {"patrol", {NULL}, 8160, "tcp"}, {"patrol", {NULL}, 8160, "udp"}, {"patrol-snmp", {NULL}, 8161, "tcp"}, {"patrol-snmp", {NULL}, 8161, "udp"}, {"vmware-fdm", {NULL}, 8182, "tcp"}, {"vmware-fdm", {NULL}, 8182, "udp"}, {"proremote", {NULL}, 8183, "tcp"}, {"itach", {NULL}, 8184, "tcp"}, {"itach", {NULL}, 8184, "udp"}, {"spytechphone", {NULL}, 8192, "tcp"}, {"spytechphone", {NULL}, 8192, "udp"}, {"blp1", {NULL}, 8194, "tcp"}, {"blp1", {NULL}, 8194, "udp"}, {"blp2", {NULL}, 8195, "tcp"}, {"blp2", {NULL}, 8195, "udp"}, {"vvr-data", {NULL}, 8199, "tcp"}, {"vvr-data", {NULL}, 8199, "udp"}, {"trivnet1", {NULL}, 8200, "tcp"}, {"trivnet1", {NULL}, 8200, "udp"}, {"trivnet2", {NULL}, 8201, "tcp"}, {"trivnet2", {NULL}, 8201, "udp"}, {"lm-perfworks", {NULL}, 8204, "tcp"}, {"lm-perfworks", {NULL}, 8204, "udp"}, {"lm-instmgr", {NULL}, 8205, "tcp"}, {"lm-instmgr", {NULL}, 8205, "udp"}, {"lm-dta", {NULL}, 8206, "tcp"}, {"lm-dta", {NULL}, 8206, "udp"}, {"lm-sserver", {NULL}, 8207, "tcp"}, {"lm-sserver", {NULL}, 8207, "udp"}, {"lm-webwatcher", {NULL}, 8208, "tcp"}, {"lm-webwatcher", {NULL}, 8208, "udp"}, {"rexecj", {NULL}, 8230, "tcp"}, {"rexecj", {NULL}, 8230, "udp"}, {"synapse-nhttps", {NULL}, 8243, "tcp"}, {"synapse-nhttps", {NULL}, 8243, "udp"}, {"pando-sec", {NULL}, 8276, "tcp"}, {"pando-sec", {NULL}, 8276, "udp"}, {"synapse-nhttp", {NULL}, 8280, "tcp"}, {"synapse-nhttp", {NULL}, 8280, "udp"}, {"blp3", {NULL}, 8292, "tcp"}, {"blp3", {NULL}, 8292, "udp"}, {"hiperscan-id", {NULL}, 8293, "tcp"}, {"blp4", {NULL}, 8294, "tcp"}, {"blp4", {NULL}, 8294, "udp"}, {"tmi", {NULL}, 8300, "tcp"}, {"tmi", {NULL}, 8300, "udp"}, {"amberon", {NULL}, 8301, "tcp"}, {"amberon", {NULL}, 8301, "udp"}, {"tnp-discover", {NULL}, 8320, "tcp"}, {"tnp-discover", {NULL}, 8320, "udp"}, {"tnp", {NULL}, 8321, "tcp"}, {"tnp", {NULL}, 8321, "udp"}, {"server-find", {NULL}, 8351, "tcp"}, {"server-find", {NULL}, 8351, "udp"}, {"cruise-enum", {NULL}, 8376, "tcp"}, {"cruise-enum", {NULL}, 8376, "udp"}, {"cruise-swroute", {NULL}, 8377, "tcp"}, {"cruise-swroute", {NULL}, 8377, "udp"}, {"cruise-config", {NULL}, 8378, "tcp"}, {"cruise-config", {NULL}, 8378, "udp"}, {"cruise-diags", {NULL}, 8379, "tcp"}, {"cruise-diags", {NULL}, 8379, "udp"}, {"cruise-update", {NULL}, 8380, "tcp"}, {"cruise-update", {NULL}, 8380, "udp"}, {"m2mservices", {NULL}, 8383, "tcp"}, {"m2mservices", {NULL}, 8383, "udp"}, {"cvd", {NULL}, 8400, "tcp"}, {"cvd", {NULL}, 8400, "udp"}, {"sabarsd", {NULL}, 8401, "tcp"}, {"sabarsd", {NULL}, 8401, "udp"}, {"abarsd", {NULL}, 8402, "tcp"}, {"abarsd", {NULL}, 8402, "udp"}, {"admind", {NULL}, 8403, "tcp"}, {"admind", {NULL}, 8403, "udp"}, {"svcloud", {NULL}, 8404, "tcp"}, {"svbackup", {NULL}, 8405, "tcp"}, {"espeech", {NULL}, 8416, "tcp"}, {"espeech", {NULL}, 8416, "udp"}, {"espeech-rtp", {NULL}, 8417, "tcp"}, {"espeech-rtp", {NULL}, 8417, "udp"}, {"cybro-a-bus", {NULL}, 8442, "tcp"}, {"cybro-a-bus", {NULL}, 8442, "udp"}, {"pcsync-https", {NULL}, 8443, "tcp"}, {"pcsync-https", {NULL}, 8443, "udp"}, {"pcsync-http", {NULL}, 8444, "tcp"}, {"pcsync-http", {NULL}, 8444, "udp"}, {"npmp", {NULL}, 8450, "tcp"}, {"npmp", {NULL}, 8450, "udp"}, {"cisco-avp", {NULL}, 8470, "tcp"}, {"pim-port", {NULL}, 8471, "tcp"}, {"pim-port", {NULL}, 8471, "sctp"}, {"otv", {NULL}, 8472, "tcp"}, {"otv", {NULL}, 8472, "udp"}, {"vp2p", {NULL}, 8473, "tcp"}, {"vp2p", {NULL}, 8473, "udp"}, {"noteshare", {NULL}, 8474, "tcp"}, {"noteshare", {NULL}, 8474, "udp"}, {"fmtp", {NULL}, 8500, "tcp"}, {"fmtp", {NULL}, 8500, "udp"}, {"rtsp-alt", {NULL}, 8554, "tcp"}, {"rtsp-alt", {NULL}, 8554, "udp"}, {"d-fence", {NULL}, 8555, "tcp"}, {"d-fence", {NULL}, 8555, "udp"}, {"oap-admin", {NULL}, 8567, "tcp"}, {"oap-admin", {NULL}, 8567, "udp"}, {"asterix", {NULL}, 8600, "tcp"}, {"asterix", {NULL}, 8600, "udp"}, {"canon-mfnp", {NULL}, 8610, "tcp"}, {"canon-mfnp", {NULL}, 8610, "udp"}, {"canon-bjnp1", {NULL}, 8611, "tcp"}, {"canon-bjnp1", {NULL}, 8611, "udp"}, {"canon-bjnp2", {NULL}, 8612, "tcp"}, {"canon-bjnp2", {NULL}, 8612, "udp"}, {"canon-bjnp3", {NULL}, 8613, "tcp"}, {"canon-bjnp3", {NULL}, 8613, "udp"}, {"canon-bjnp4", {NULL}, 8614, "tcp"}, {"canon-bjnp4", {NULL}, 8614, "udp"}, {"sun-as-jmxrmi", {NULL}, 8686, "tcp"}, {"sun-as-jmxrmi", {NULL}, 8686, "udp"}, {"vnyx", {NULL}, 8699, "tcp"}, {"vnyx", {NULL}, 8699, "udp"}, {"dtp-net", {NULL}, 8732, "udp"}, {"ibus", {NULL}, 8733, "tcp"}, {"ibus", {NULL}, 8733, "udp"}, {"mc-appserver", {NULL}, 8763, "tcp"}, {"mc-appserver", {NULL}, 8763, "udp"}, {"openqueue", {NULL}, 8764, "tcp"}, {"openqueue", {NULL}, 8764, "udp"}, {"ultraseek-http", {NULL}, 8765, "tcp"}, {"ultraseek-http", {NULL}, 8765, "udp"}, {"dpap", {NULL}, 8770, "tcp"}, {"dpap", {NULL}, 8770, "udp"}, {"msgclnt", {NULL}, 8786, "tcp"}, {"msgclnt", {NULL}, 8786, "udp"}, {"msgsrvr", {NULL}, 8787, "tcp"}, {"msgsrvr", {NULL}, 8787, "udp"}, {"sunwebadmin", {NULL}, 8800, "tcp"}, {"sunwebadmin", {NULL}, 8800, "udp"}, {"truecm", {NULL}, 8804, "tcp"}, {"truecm", {NULL}, 8804, "udp"}, {"dxspider", {NULL}, 8873, "tcp"}, {"dxspider", {NULL}, 8873, "udp"}, {"cddbp-alt", {NULL}, 8880, "tcp"}, {"cddbp-alt", {NULL}, 8880, "udp"}, {"secure-mqtt", {NULL}, 8883, "tcp"}, {"secure-mqtt", {NULL}, 8883, "udp"}, {"ddi-tcp-1", {NULL}, 8888, "tcp"}, {"ddi-udp-1", {NULL}, 8888, "udp"}, {"ddi-tcp-2", {NULL}, 8889, "tcp"}, {"ddi-udp-2", {NULL}, 8889, "udp"}, {"ddi-tcp-3", {NULL}, 8890, "tcp"}, {"ddi-udp-3", {NULL}, 8890, "udp"}, {"ddi-tcp-4", {NULL}, 8891, "tcp"}, {"ddi-udp-4", {NULL}, 8891, "udp"}, {"ddi-tcp-5", {NULL}, 8892, "tcp"}, {"ddi-udp-5", {NULL}, 8892, "udp"}, {"ddi-tcp-6", {NULL}, 8893, "tcp"}, {"ddi-udp-6", {NULL}, 8893, "udp"}, {"ddi-tcp-7", {NULL}, 8894, "tcp"}, {"ddi-udp-7", {NULL}, 8894, "udp"}, {"ospf-lite", {NULL}, 8899, "tcp"}, {"ospf-lite", {NULL}, 8899, "udp"}, {"jmb-cds1", {NULL}, 8900, "tcp"}, {"jmb-cds1", {NULL}, 8900, "udp"}, {"jmb-cds2", {NULL}, 8901, "tcp"}, {"jmb-cds2", {NULL}, 8901, "udp"}, {"manyone-http", {NULL}, 8910, "tcp"}, {"manyone-http", {NULL}, 8910, "udp"}, {"manyone-xml", {NULL}, 8911, "tcp"}, {"manyone-xml", {NULL}, 8911, "udp"}, {"wcbackup", {NULL}, 8912, "tcp"}, {"wcbackup", {NULL}, 8912, "udp"}, {"dragonfly", {NULL}, 8913, "tcp"}, {"dragonfly", {NULL}, 8913, "udp"}, {"twds", {NULL}, 8937, "tcp"}, {"cumulus-admin", {NULL}, 8954, "tcp"}, {"cumulus-admin", {NULL}, 8954, "udp"}, {"sunwebadmins", {NULL}, 8989, "tcp"}, {"sunwebadmins", {NULL}, 8989, "udp"}, {"http-wmap", {NULL}, 8990, "tcp"}, {"http-wmap", {NULL}, 8990, "udp"}, {"https-wmap", {NULL}, 8991, "tcp"}, {"https-wmap", {NULL}, 8991, "udp"}, {"bctp", {NULL}, 8999, "tcp"}, {"bctp", {NULL}, 8999, "udp"}, {"cslistener", {NULL}, 9000, "tcp"}, {"cslistener", {NULL}, 9000, "udp"}, {"etlservicemgr", {NULL}, 9001, "tcp"}, {"etlservicemgr", {NULL}, 9001, "udp"}, {"dynamid", {NULL}, 9002, "tcp"}, {"dynamid", {NULL}, 9002, "udp"}, {"ogs-client", {NULL}, 9007, "udp"}, {"ogs-server", {NULL}, 9008, "tcp"}, {"pichat", {NULL}, 9009, "tcp"}, {"pichat", {NULL}, 9009, "udp"}, {"sdr", {NULL}, 9010, "tcp"}, {"tambora", {NULL}, 9020, "tcp"}, {"tambora", {NULL}, 9020, "udp"}, {"panagolin-ident", {NULL}, 9021, "tcp"}, {"panagolin-ident", {NULL}, 9021, "udp"}, {"paragent", {NULL}, 9022, "tcp"}, {"paragent", {NULL}, 9022, "udp"}, {"swa-1", {NULL}, 9023, "tcp"}, {"swa-1", {NULL}, 9023, "udp"}, {"swa-2", {NULL}, 9024, "tcp"}, {"swa-2", {NULL}, 9024, "udp"}, {"swa-3", {NULL}, 9025, "tcp"}, {"swa-3", {NULL}, 9025, "udp"}, {"swa-4", {NULL}, 9026, "tcp"}, {"swa-4", {NULL}, 9026, "udp"}, {"versiera", {NULL}, 9050, "tcp"}, {"fio-cmgmt", {NULL}, 9051, "tcp"}, {"glrpc", {NULL}, 9080, "tcp"}, {"glrpc", {NULL}, 9080, "udp"}, {"lcs-ap", {NULL}, 9082, "sctp"}, {"emc-pp-mgmtsvc", {NULL}, 9083, "tcp"}, {"aurora", {NULL}, 9084, "tcp"}, {"aurora", {NULL}, 9084, "udp"}, {"aurora", {NULL}, 9084, "sctp"}, {"ibm-rsyscon", {NULL}, 9085, "tcp"}, {"ibm-rsyscon", {NULL}, 9085, "udp"}, {"net2display", {NULL}, 9086, "tcp"}, {"net2display", {NULL}, 9086, "udp"}, {"classic", {NULL}, 9087, "tcp"}, {"classic", {NULL}, 9087, "udp"}, {"sqlexec", {NULL}, 9088, "tcp"}, {"sqlexec", {NULL}, 9088, "udp"}, {"sqlexec-ssl", {NULL}, 9089, "tcp"}, {"sqlexec-ssl", {NULL}, 9089, "udp"}, {"websm", {NULL}, 9090, "tcp"}, {"websm", {NULL}, 9090, "udp"}, {"xmltec-xmlmail", {NULL}, 9091, "tcp"}, {"xmltec-xmlmail", {NULL}, 9091, "udp"}, {"XmlIpcRegSvc", {NULL}, 9092, "tcp"}, {"XmlIpcRegSvc", {NULL}, 9092, "udp"}, {"hp-pdl-datastr", {NULL}, 9100, "tcp"}, {"hp-pdl-datastr", {NULL}, 9100, "udp"}, {"pdl-datastream", {NULL}, 9100, "tcp"}, {"pdl-datastream", {NULL}, 9100, "udp"}, {"bacula-dir", {NULL}, 9101, "tcp"}, {"bacula-dir", {NULL}, 9101, "udp"}, {"bacula-fd", {NULL}, 9102, "tcp"}, {"bacula-fd", {NULL}, 9102, "udp"}, {"bacula-sd", {NULL}, 9103, "tcp"}, {"bacula-sd", {NULL}, 9103, "udp"}, {"peerwire", {NULL}, 9104, "tcp"}, {"peerwire", {NULL}, 9104, "udp"}, {"xadmin", {NULL}, 9105, "tcp"}, {"xadmin", {NULL}, 9105, "udp"}, {"astergate", {NULL}, 9106, "tcp"}, {"astergate-disc", {NULL}, 9106, "udp"}, {"astergatefax", {NULL}, 9107, "tcp"}, {"mxit", {NULL}, 9119, "tcp"}, {"mxit", {NULL}, 9119, "udp"}, {"dddp", {NULL}, 9131, "tcp"}, {"dddp", {NULL}, 9131, "udp"}, {"apani1", {NULL}, 9160, "tcp"}, {"apani1", {NULL}, 9160, "udp"}, {"apani2", {NULL}, 9161, "tcp"}, {"apani2", {NULL}, 9161, "udp"}, {"apani3", {NULL}, 9162, "tcp"}, {"apani3", {NULL}, 9162, "udp"}, {"apani4", {NULL}, 9163, "tcp"}, {"apani4", {NULL}, 9163, "udp"}, {"apani5", {NULL}, 9164, "tcp"}, {"apani5", {NULL}, 9164, "udp"}, {"sun-as-jpda", {NULL}, 9191, "tcp"}, {"sun-as-jpda", {NULL}, 9191, "udp"}, {"wap-wsp", {NULL}, 9200, "tcp"}, {"wap-wsp", {NULL}, 9200, "udp"}, {"wap-wsp-wtp", {NULL}, 9201, "tcp"}, {"wap-wsp-wtp", {NULL}, 9201, "udp"}, {"wap-wsp-s", {NULL}, 9202, "tcp"}, {"wap-wsp-s", {NULL}, 9202, "udp"}, {"wap-wsp-wtp-s", {NULL}, 9203, "tcp"}, {"wap-wsp-wtp-s", {NULL}, 9203, "udp"}, {"wap-vcard", {NULL}, 9204, "tcp"}, {"wap-vcard", {NULL}, 9204, "udp"}, {"wap-vcal", {NULL}, 9205, "tcp"}, {"wap-vcal", {NULL}, 9205, "udp"}, {"wap-vcard-s", {NULL}, 9206, "tcp"}, {"wap-vcard-s", {NULL}, 9206, "udp"}, {"wap-vcal-s", {NULL}, 9207, "tcp"}, {"wap-vcal-s", {NULL}, 9207, "udp"}, {"rjcdb-vcards", {NULL}, 9208, "tcp"}, {"rjcdb-vcards", {NULL}, 9208, "udp"}, {"almobile-system", {NULL}, 9209, "tcp"}, {"almobile-system", {NULL}, 9209, "udp"}, {"oma-mlp", {NULL}, 9210, "tcp"}, {"oma-mlp", {NULL}, 9210, "udp"}, {"oma-mlp-s", {NULL}, 9211, "tcp"}, {"oma-mlp-s", {NULL}, 9211, "udp"}, {"serverviewdbms", {NULL}, 9212, "tcp"}, {"serverviewdbms", {NULL}, 9212, "udp"}, {"serverstart", {NULL}, 9213, "tcp"}, {"serverstart", {NULL}, 9213, "udp"}, {"ipdcesgbs", {NULL}, 9214, "tcp"}, {"ipdcesgbs", {NULL}, 9214, "udp"}, {"insis", {NULL}, 9215, "tcp"}, {"insis", {NULL}, 9215, "udp"}, {"acme", {NULL}, 9216, "tcp"}, {"acme", {NULL}, 9216, "udp"}, {"fsc-port", {NULL}, 9217, "tcp"}, {"fsc-port", {NULL}, 9217, "udp"}, {"teamcoherence", {NULL}, 9222, "tcp"}, {"teamcoherence", {NULL}, 9222, "udp"}, {"mon", {NULL}, 9255, "tcp"}, {"mon", {NULL}, 9255, "udp"}, {"pegasus", {NULL}, 9278, "tcp"}, {"pegasus", {NULL}, 9278, "udp"}, {"pegasus-ctl", {NULL}, 9279, "tcp"}, {"pegasus-ctl", {NULL}, 9279, "udp"}, {"pgps", {NULL}, 9280, "tcp"}, {"pgps", {NULL}, 9280, "udp"}, {"swtp-port1", {NULL}, 9281, "tcp"}, {"swtp-port1", {NULL}, 9281, "udp"}, {"swtp-port2", {NULL}, 9282, "tcp"}, {"swtp-port2", {NULL}, 9282, "udp"}, {"callwaveiam", {NULL}, 9283, "tcp"}, {"callwaveiam", {NULL}, 9283, "udp"}, {"visd", {NULL}, 9284, "tcp"}, {"visd", {NULL}, 9284, "udp"}, {"n2h2server", {NULL}, 9285, "tcp"}, {"n2h2server", {NULL}, 9285, "udp"}, {"n2receive", {NULL}, 9286, "udp"}, {"cumulus", {NULL}, 9287, "tcp"}, {"cumulus", {NULL}, 9287, "udp"}, {"armtechdaemon", {NULL}, 9292, "tcp"}, {"armtechdaemon", {NULL}, 9292, "udp"}, {"storview", {NULL}, 9293, "tcp"}, {"storview", {NULL}, 9293, "udp"}, {"armcenterhttp", {NULL}, 9294, "tcp"}, {"armcenterhttp", {NULL}, 9294, "udp"}, {"armcenterhttps", {NULL}, 9295, "tcp"}, {"armcenterhttps", {NULL}, 9295, "udp"}, {"vrace", {NULL}, 9300, "tcp"}, {"vrace", {NULL}, 9300, "udp"}, {"sphinxql", {NULL}, 9306, "tcp"}, {"sphinxapi", {NULL}, 9312, "tcp"}, {"secure-ts", {NULL}, 9318, "tcp"}, {"secure-ts", {NULL}, 9318, "udp"}, {"guibase", {NULL}, 9321, "tcp"}, {"guibase", {NULL}, 9321, "udp"}, {"mpidcmgr", {NULL}, 9343, "tcp"}, {"mpidcmgr", {NULL}, 9343, "udp"}, {"mphlpdmc", {NULL}, 9344, "tcp"}, {"mphlpdmc", {NULL}, 9344, "udp"}, {"ctechlicensing", {NULL}, 9346, "tcp"}, {"ctechlicensing", {NULL}, 9346, "udp"}, {"fjdmimgr", {NULL}, 9374, "tcp"}, {"fjdmimgr", {NULL}, 9374, "udp"}, {"boxp", {NULL}, 9380, "tcp"}, {"boxp", {NULL}, 9380, "udp"}, {"d2dconfig", {NULL}, 9387, "tcp"}, {"d2ddatatrans", {NULL}, 9388, "tcp"}, {"adws", {NULL}, 9389, "tcp"}, {"otp", {NULL}, 9390, "tcp"}, {"fjinvmgr", {NULL}, 9396, "tcp"}, {"fjinvmgr", {NULL}, 9396, "udp"}, {"mpidcagt", {NULL}, 9397, "tcp"}, {"mpidcagt", {NULL}, 9397, "udp"}, {"sec-t4net-srv", {NULL}, 9400, "tcp"}, {"sec-t4net-srv", {NULL}, 9400, "udp"}, {"sec-t4net-clt", {NULL}, 9401, "tcp"}, {"sec-t4net-clt", {NULL}, 9401, "udp"}, {"sec-pc2fax-srv", {NULL}, 9402, "tcp"}, {"sec-pc2fax-srv", {NULL}, 9402, "udp"}, {"git", {NULL}, 9418, "tcp"}, {"git", {NULL}, 9418, "udp"}, {"tungsten-https", {NULL}, 9443, "tcp"}, {"tungsten-https", {NULL}, 9443, "udp"}, {"wso2esb-console", {NULL}, 9444, "tcp"}, {"wso2esb-console", {NULL}, 9444, "udp"}, {"sntlkeyssrvr", {NULL}, 9450, "tcp"}, {"sntlkeyssrvr", {NULL}, 9450, "udp"}, {"ismserver", {NULL}, 9500, "tcp"}, {"ismserver", {NULL}, 9500, "udp"}, {"sma-spw", {NULL}, 9522, "udp"}, {"mngsuite", {NULL}, 9535, "tcp"}, {"mngsuite", {NULL}, 9535, "udp"}, {"laes-bf", {NULL}, 9536, "tcp"}, {"laes-bf", {NULL}, 9536, "udp"}, {"trispen-sra", {NULL}, 9555, "tcp"}, {"trispen-sra", {NULL}, 9555, "udp"}, {"ldgateway", {NULL}, 9592, "tcp"}, {"ldgateway", {NULL}, 9592, "udp"}, {"cba8", {NULL}, 9593, "tcp"}, {"cba8", {NULL}, 9593, "udp"}, {"msgsys", {NULL}, 9594, "tcp"}, {"msgsys", {NULL}, 9594, "udp"}, {"pds", {NULL}, 9595, "tcp"}, {"pds", {NULL}, 9595, "udp"}, {"mercury-disc", {NULL}, 9596, "tcp"}, {"mercury-disc", {NULL}, 9596, "udp"}, {"pd-admin", {NULL}, 9597, "tcp"}, {"pd-admin", {NULL}, 9597, "udp"}, {"vscp", {NULL}, 9598, "tcp"}, {"vscp", {NULL}, 9598, "udp"}, {"robix", {NULL}, 9599, "tcp"}, {"robix", {NULL}, 9599, "udp"}, {"micromuse-ncpw", {NULL}, 9600, "tcp"}, {"micromuse-ncpw", {NULL}, 9600, "udp"}, {"streamcomm-ds", {NULL}, 9612, "tcp"}, {"streamcomm-ds", {NULL}, 9612, "udp"}, {"iadt-tls", {NULL}, 9614, "tcp"}, {"erunbook_agent", {NULL}, 9616, "tcp"}, {"erunbook_server", {NULL}, 9617, "tcp"}, {"condor", {NULL}, 9618, "tcp"}, {"condor", {NULL}, 9618, "udp"}, {"odbcpathway", {NULL}, 9628, "tcp"}, {"odbcpathway", {NULL}, 9628, "udp"}, {"uniport", {NULL}, 9629, "tcp"}, {"uniport", {NULL}, 9629, "udp"}, {"peoctlr", {NULL}, 9630, "tcp"}, {"peocoll", {NULL}, 9631, "tcp"}, {"mc-comm", {NULL}, 9632, "udp"}, {"pqsflows", {NULL}, 9640, "tcp"}, {"xmms2", {NULL}, 9667, "tcp"}, {"xmms2", {NULL}, 9667, "udp"}, {"tec5-sdctp", {NULL}, 9668, "tcp"}, {"tec5-sdctp", {NULL}, 9668, "udp"}, {"client-wakeup", {NULL}, 9694, "tcp"}, {"client-wakeup", {NULL}, 9694, "udp"}, {"ccnx", {NULL}, 9695, "tcp"}, {"ccnx", {NULL}, 9695, "udp"}, {"board-roar", {NULL}, 9700, "tcp"}, {"board-roar", {NULL}, 9700, "udp"}, {"l5nas-parchan", {NULL}, 9747, "tcp"}, {"l5nas-parchan", {NULL}, 9747, "udp"}, {"board-voip", {NULL}, 9750, "tcp"}, {"board-voip", {NULL}, 9750, "udp"}, {"rasadv", {NULL}, 9753, "tcp"}, {"rasadv", {NULL}, 9753, "udp"}, {"tungsten-http", {NULL}, 9762, "tcp"}, {"tungsten-http", {NULL}, 9762, "udp"}, {"davsrc", {NULL}, 9800, "tcp"}, {"davsrc", {NULL}, 9800, "udp"}, {"sstp-2", {NULL}, 9801, "tcp"}, {"sstp-2", {NULL}, 9801, "udp"}, {"davsrcs", {NULL}, 9802, "tcp"}, {"davsrcs", {NULL}, 9802, "udp"}, {"sapv1", {NULL}, 9875, "tcp"}, {"sapv1", {NULL}, 9875, "udp"}, {"sd", {NULL}, 9876, "tcp"}, {"sd", {NULL}, 9876, "udp"}, {"cyborg-systems", {NULL}, 9888, "tcp"}, {"cyborg-systems", {NULL}, 9888, "udp"}, {"gt-proxy", {NULL}, 9889, "tcp"}, {"gt-proxy", {NULL}, 9889, "udp"}, {"monkeycom", {NULL}, 9898, "tcp"}, {"monkeycom", {NULL}, 9898, "udp"}, {"sctp-tunneling", {NULL}, 9899, "tcp"}, {"sctp-tunneling", {NULL}, 9899, "udp"}, {"iua", {NULL}, 9900, "tcp"}, {"iua", {NULL}, 9900, "udp"}, {"iua", {NULL}, 9900, "sctp"}, {"enrp", {NULL}, 9901, "udp"}, {"enrp-sctp", {NULL}, 9901, "sctp"}, {"enrp-sctp-tls", {NULL}, 9902, "sctp"}, {"domaintime", {NULL}, 9909, "tcp"}, {"domaintime", {NULL}, 9909, "udp"}, {"sype-transport", {NULL}, 9911, "tcp"}, {"sype-transport", {NULL}, 9911, "udp"}, {"apc-9950", {NULL}, 9950, "tcp"}, {"apc-9950", {NULL}, 9950, "udp"}, {"apc-9951", {NULL}, 9951, "tcp"}, {"apc-9951", {NULL}, 9951, "udp"}, {"apc-9952", {NULL}, 9952, "tcp"}, {"apc-9952", {NULL}, 9952, "udp"}, {"acis", {NULL}, 9953, "tcp"}, {"acis", {NULL}, 9953, "udp"}, {"odnsp", {NULL}, 9966, "tcp"}, {"odnsp", {NULL}, 9966, "udp"}, {"dsm-scm-target", {NULL}, 9987, "tcp"}, {"dsm-scm-target", {NULL}, 9987, "udp"}, {"nsesrvr", {NULL}, 9988, "tcp"}, {"osm-appsrvr", {NULL}, 9990, "tcp"}, {"osm-appsrvr", {NULL}, 9990, "udp"}, {"osm-oev", {NULL}, 9991, "tcp"}, {"osm-oev", {NULL}, 9991, "udp"}, {"palace-1", {NULL}, 9992, "tcp"}, {"palace-1", {NULL}, 9992, "udp"}, {"palace-2", {NULL}, 9993, "tcp"}, {"palace-2", {NULL}, 9993, "udp"}, {"palace-3", {NULL}, 9994, "tcp"}, {"palace-3", {NULL}, 9994, "udp"}, {"palace-4", {NULL}, 9995, "tcp"}, {"palace-4", {NULL}, 9995, "udp"}, {"palace-5", {NULL}, 9996, "tcp"}, {"palace-5", {NULL}, 9996, "udp"}, {"palace-6", {NULL}, 9997, "tcp"}, {"palace-6", {NULL}, 9997, "udp"}, {"distinct32", {NULL}, 9998, "tcp"}, {"distinct32", {NULL}, 9998, "udp"}, {"distinct", {NULL}, 9999, "tcp"}, {"distinct", {NULL}, 9999, "udp"}, {"ndmp", {NULL}, 10000, "tcp"}, {"ndmp", {NULL}, 10000, "udp"}, {"scp-config", {NULL}, 10001, "tcp"}, {"scp-config", {NULL}, 10001, "udp"}, {"documentum", {NULL}, 10002, "tcp"}, {"documentum", {NULL}, 10002, "udp"}, {"documentum_s", {NULL}, 10003, "tcp"}, {"documentum_s", {NULL}, 10003, "udp"}, {"emcrmirccd", {NULL}, 10004, "tcp"}, {"emcrmird", {NULL}, 10005, "tcp"}, {"mvs-capacity", {NULL}, 10007, "tcp"}, {"mvs-capacity", {NULL}, 10007, "udp"}, {"octopus", {NULL}, 10008, "tcp"}, {"octopus", {NULL}, 10008, "udp"}, {"swdtp-sv", {NULL}, 10009, "tcp"}, {"swdtp-sv", {NULL}, 10009, "udp"}, {"rxapi", {NULL}, 10010, "tcp"}, {"zabbix-agent", {NULL}, 10050, "tcp"}, {"zabbix-agent", {NULL}, 10050, "udp"}, {"zabbix-trapper", {NULL}, 10051, "tcp"}, {"zabbix-trapper", {NULL}, 10051, "udp"}, {"qptlmd", {NULL}, 10055, "tcp"}, {"amanda", {NULL}, 10080, "tcp"}, {"amanda", {NULL}, 10080, "udp"}, {"famdc", {NULL}, 10081, "tcp"}, {"famdc", {NULL}, 10081, "udp"}, {"itap-ddtp", {NULL}, 10100, "tcp"}, {"itap-ddtp", {NULL}, 10100, "udp"}, {"ezmeeting-2", {NULL}, 10101, "tcp"}, {"ezmeeting-2", {NULL}, 10101, "udp"}, {"ezproxy-2", {NULL}, 10102, "tcp"}, {"ezproxy-2", {NULL}, 10102, "udp"}, {"ezrelay", {NULL}, 10103, "tcp"}, {"ezrelay", {NULL}, 10103, "udp"}, {"swdtp", {NULL}, 10104, "tcp"}, {"swdtp", {NULL}, 10104, "udp"}, {"bctp-server", {NULL}, 10107, "tcp"}, {"bctp-server", {NULL}, 10107, "udp"}, {"nmea-0183", {NULL}, 10110, "tcp"}, {"nmea-0183", {NULL}, 10110, "udp"}, {"netiq-endpoint", {NULL}, 10113, "tcp"}, {"netiq-endpoint", {NULL}, 10113, "udp"}, {"netiq-qcheck", {NULL}, 10114, "tcp"}, {"netiq-qcheck", {NULL}, 10114, "udp"}, {"netiq-endpt", {NULL}, 10115, "tcp"}, {"netiq-endpt", {NULL}, 10115, "udp"}, {"netiq-voipa", {NULL}, 10116, "tcp"}, {"netiq-voipa", {NULL}, 10116, "udp"}, {"iqrm", {NULL}, 10117, "tcp"}, {"iqrm", {NULL}, 10117, "udp"}, {"bmc-perf-sd", {NULL}, 10128, "tcp"}, {"bmc-perf-sd", {NULL}, 10128, "udp"}, {"bmc-gms", {NULL}, 10129, "tcp"}, {"qb-db-server", {NULL}, 10160, "tcp"}, {"qb-db-server", {NULL}, 10160, "udp"}, {"snmptls", {NULL}, 10161, "tcp"}, {"snmpdtls", {NULL}, 10161, "udp"}, {"snmptls-trap", {NULL}, 10162, "tcp"}, {"snmpdtls-trap", {NULL}, 10162, "udp"}, {"trisoap", {NULL}, 10200, "tcp"}, {"trisoap", {NULL}, 10200, "udp"}, {"rsms", {NULL}, 10201, "tcp"}, {"rscs", {NULL}, 10201, "udp"}, {"apollo-relay", {NULL}, 10252, "tcp"}, {"apollo-relay", {NULL}, 10252, "udp"}, {"axis-wimp-port", {NULL}, 10260, "tcp"}, {"axis-wimp-port", {NULL}, 10260, "udp"}, {"blocks", {NULL}, 10288, "tcp"}, {"blocks", {NULL}, 10288, "udp"}, {"cosir", {NULL}, 10321, "tcp"}, {"hip-nat-t", {NULL}, 10500, "udp"}, {"MOS-lower", {NULL}, 10540, "tcp"}, {"MOS-lower", {NULL}, 10540, "udp"}, {"MOS-upper", {NULL}, 10541, "tcp"}, {"MOS-upper", {NULL}, 10541, "udp"}, {"MOS-aux", {NULL}, 10542, "tcp"}, {"MOS-aux", {NULL}, 10542, "udp"}, {"MOS-soap", {NULL}, 10543, "tcp"}, {"MOS-soap", {NULL}, 10543, "udp"}, {"MOS-soap-opt", {NULL}, 10544, "tcp"}, {"MOS-soap-opt", {NULL}, 10544, "udp"}, {"gap", {NULL}, 10800, "tcp"}, {"gap", {NULL}, 10800, "udp"}, {"lpdg", {NULL}, 10805, "tcp"}, {"lpdg", {NULL}, 10805, "udp"}, {"nbd", {NULL}, 10809, "tcp"}, {"nmc-disc", {NULL}, 10810, "udp"}, {"helix", {NULL}, 10860, "tcp"}, {"helix", {NULL}, 10860, "udp"}, {"rmiaux", {NULL}, 10990, "tcp"}, {"rmiaux", {NULL}, 10990, "udp"}, {"irisa", {NULL}, 11000, "tcp"}, {"irisa", {NULL}, 11000, "udp"}, {"metasys", {NULL}, 11001, "tcp"}, {"metasys", {NULL}, 11001, "udp"}, {"netapp-icmgmt", {NULL}, 11104, "tcp"}, {"netapp-icdata", {NULL}, 11105, "tcp"}, {"sgi-lk", {NULL}, 11106, "tcp"}, {"sgi-lk", {NULL}, 11106, "udp"}, {"vce", {NULL}, 11111, "tcp"}, {"vce", {NULL}, 11111, "udp"}, {"dicom", {NULL}, 11112, "tcp"}, {"dicom", {NULL}, 11112, "udp"}, {"suncacao-snmp", {NULL}, 11161, "tcp"}, {"suncacao-snmp", {NULL}, 11161, "udp"}, {"suncacao-jmxmp", {NULL}, 11162, "tcp"}, {"suncacao-jmxmp", {NULL}, 11162, "udp"}, {"suncacao-rmi", {NULL}, 11163, "tcp"}, {"suncacao-rmi", {NULL}, 11163, "udp"}, {"suncacao-csa", {NULL}, 11164, "tcp"}, {"suncacao-csa", {NULL}, 11164, "udp"}, {"suncacao-websvc", {NULL}, 11165, "tcp"}, {"suncacao-websvc", {NULL}, 11165, "udp"}, {"snss", {NULL}, 11171, "udp"}, {"oemcacao-jmxmp", {NULL}, 11172, "tcp"}, {"oemcacao-rmi", {NULL}, 11174, "tcp"}, {"oemcacao-websvc", {NULL}, 11175, "tcp"}, {"smsqp", {NULL}, 11201, "tcp"}, {"smsqp", {NULL}, 11201, "udp"}, {"wifree", {NULL}, 11208, "tcp"}, {"wifree", {NULL}, 11208, "udp"}, {"memcache", {NULL}, 11211, "tcp"}, {"memcache", {NULL}, 11211, "udp"}, {"imip", {NULL}, 11319, "tcp"}, {"imip", {NULL}, 11319, "udp"}, {"imip-channels", {NULL}, 11320, "tcp"}, {"imip-channels", {NULL}, 11320, "udp"}, {"arena-server", {NULL}, 11321, "tcp"}, {"arena-server", {NULL}, 11321, "udp"}, {"atm-uhas", {NULL}, 11367, "tcp"}, {"atm-uhas", {NULL}, 11367, "udp"}, {"hkp", {NULL}, 11371, "tcp"}, {"hkp", {NULL}, 11371, "udp"}, {"asgcypresstcps", {NULL}, 11489, "tcp"}, {"tempest-port", {NULL}, 11600, "tcp"}, {"tempest-port", {NULL}, 11600, "udp"}, {"h323callsigalt", {NULL}, 11720, "tcp"}, {"h323callsigalt", {NULL}, 11720, "udp"}, {"intrepid-ssl", {NULL}, 11751, "tcp"}, {"intrepid-ssl", {NULL}, 11751, "udp"}, {"xoraya", {NULL}, 11876, "tcp"}, {"xoraya", {NULL}, 11876, "udp"}, {"x2e-disc", {NULL}, 11877, "udp"}, {"sysinfo-sp", {NULL}, 11967, "tcp"}, {"sysinfo-sp", {NULL}, 11967, "udp"}, {"wmereceiving", {NULL}, 11997, "sctp"}, {"wmedistribution", {NULL}, 11998, "sctp"}, {"wmereporting", {NULL}, 11999, "sctp"}, {"entextxid", {NULL}, 12000, "tcp"}, {"entextxid", {NULL}, 12000, "udp"}, {"entextnetwk", {NULL}, 12001, "tcp"}, {"entextnetwk", {NULL}, 12001, "udp"}, {"entexthigh", {NULL}, 12002, "tcp"}, {"entexthigh", {NULL}, 12002, "udp"}, {"entextmed", {NULL}, 12003, "tcp"}, {"entextmed", {NULL}, 12003, "udp"}, {"entextlow", {NULL}, 12004, "tcp"}, {"entextlow", {NULL}, 12004, "udp"}, {"dbisamserver1", {NULL}, 12005, "tcp"}, {"dbisamserver1", {NULL}, 12005, "udp"}, {"dbisamserver2", {NULL}, 12006, "tcp"}, {"dbisamserver2", {NULL}, 12006, "udp"}, {"accuracer", {NULL}, 12007, "tcp"}, {"accuracer", {NULL}, 12007, "udp"}, {"accuracer-dbms", {NULL}, 12008, "tcp"}, {"accuracer-dbms", {NULL}, 12008, "udp"}, {"edbsrvr", {NULL}, 12010, "tcp"}, {"vipera", {NULL}, 12012, "tcp"}, {"vipera", {NULL}, 12012, "udp"}, {"vipera-ssl", {NULL}, 12013, "tcp"}, {"vipera-ssl", {NULL}, 12013, "udp"}, {"rets-ssl", {NULL}, 12109, "tcp"}, {"rets-ssl", {NULL}, 12109, "udp"}, {"nupaper-ss", {NULL}, 12121, "tcp"}, {"nupaper-ss", {NULL}, 12121, "udp"}, {"cawas", {NULL}, 12168, "tcp"}, {"cawas", {NULL}, 12168, "udp"}, {"hivep", {NULL}, 12172, "tcp"}, {"hivep", {NULL}, 12172, "udp"}, {"linogridengine", {NULL}, 12300, "tcp"}, {"linogridengine", {NULL}, 12300, "udp"}, {"warehouse-sss", {NULL}, 12321, "tcp"}, {"warehouse-sss", {NULL}, 12321, "udp"}, {"warehouse", {NULL}, 12322, "tcp"}, {"warehouse", {NULL}, 12322, "udp"}, {"italk", {NULL}, 12345, "tcp"}, {"italk", {NULL}, 12345, "udp"}, {"tsaf", {NULL}, 12753, "tcp"}, {"tsaf", {NULL}, 12753, "udp"}, {"i-zipqd", {NULL}, 13160, "tcp"}, {"i-zipqd", {NULL}, 13160, "udp"}, {"bcslogc", {NULL}, 13216, "tcp"}, {"bcslogc", {NULL}, 13216, "udp"}, {"rs-pias", {NULL}, 13217, "tcp"}, {"rs-pias", {NULL}, 13217, "udp"}, {"emc-vcas-tcp", {NULL}, 13218, "tcp"}, {"emc-vcas-udp", {NULL}, 13218, "udp"}, {"powwow-client", {NULL}, 13223, "tcp"}, {"powwow-client", {NULL}, 13223, "udp"}, {"powwow-server", {NULL}, 13224, "tcp"}, {"powwow-server", {NULL}, 13224, "udp"}, {"doip-data", {NULL}, 13400, "tcp"}, {"doip-disc", {NULL}, 13400, "udp"}, {"bprd", {NULL}, 13720, "tcp"}, {"bprd", {NULL}, 13720, "udp"}, {"bpdbm", {NULL}, 13721, "tcp"}, {"bpdbm", {NULL}, 13721, "udp"}, {"bpjava-msvc", {NULL}, 13722, "tcp"}, {"bpjava-msvc", {NULL}, 13722, "udp"}, {"vnetd", {NULL}, 13724, "tcp"}, {"vnetd", {NULL}, 13724, "udp"}, {"bpcd", {NULL}, 13782, "tcp"}, {"bpcd", {NULL}, 13782, "udp"}, {"vopied", {NULL}, 13783, "tcp"}, {"vopied", {NULL}, 13783, "udp"}, {"nbdb", {NULL}, 13785, "tcp"}, {"nbdb", {NULL}, 13785, "udp"}, {"nomdb", {NULL}, 13786, "tcp"}, {"nomdb", {NULL}, 13786, "udp"}, {"dsmcc-config", {NULL}, 13818, "tcp"}, {"dsmcc-config", {NULL}, 13818, "udp"}, {"dsmcc-session", {NULL}, 13819, "tcp"}, {"dsmcc-session", {NULL}, 13819, "udp"}, {"dsmcc-passthru", {NULL}, 13820, "tcp"}, {"dsmcc-passthru", {NULL}, 13820, "udp"}, {"dsmcc-download", {NULL}, 13821, "tcp"}, {"dsmcc-download", {NULL}, 13821, "udp"}, {"dsmcc-ccp", {NULL}, 13822, "tcp"}, {"dsmcc-ccp", {NULL}, 13822, "udp"}, {"bmdss", {NULL}, 13823, "tcp"}, {"dta-systems", {NULL}, 13929, "tcp"}, {"dta-systems", {NULL}, 13929, "udp"}, {"medevolve", {NULL}, 13930, "tcp"}, {"scotty-ft", {NULL}, 14000, "tcp"}, {"scotty-ft", {NULL}, 14000, "udp"}, {"sua", {NULL}, 14001, "tcp"}, {"sua", {NULL}, 14001, "udp"}, {"sua", {NULL}, 14001, "sctp"}, {"sage-best-com1", {NULL}, 14033, "tcp"}, {"sage-best-com1", {NULL}, 14033, "udp"}, {"sage-best-com2", {NULL}, 14034, "tcp"}, {"sage-best-com2", {NULL}, 14034, "udp"}, {"vcs-app", {NULL}, 14141, "tcp"}, {"vcs-app", {NULL}, 14141, "udp"}, {"icpp", {NULL}, 14142, "tcp"}, {"icpp", {NULL}, 14142, "udp"}, {"gcm-app", {NULL}, 14145, "tcp"}, {"gcm-app", {NULL}, 14145, "udp"}, {"vrts-tdd", {NULL}, 14149, "tcp"}, {"vrts-tdd", {NULL}, 14149, "udp"}, {"vcscmd", {NULL}, 14150, "tcp"}, {"vad", {NULL}, 14154, "tcp"}, {"vad", {NULL}, 14154, "udp"}, {"cps", {NULL}, 14250, "tcp"}, {"cps", {NULL}, 14250, "udp"}, {"ca-web-update", {NULL}, 14414, "tcp"}, {"ca-web-update", {NULL}, 14414, "udp"}, {"hde-lcesrvr-1", {NULL}, 14936, "tcp"}, {"hde-lcesrvr-1", {NULL}, 14936, "udp"}, {"hde-lcesrvr-2", {NULL}, 14937, "tcp"}, {"hde-lcesrvr-2", {NULL}, 14937, "udp"}, {"hydap", {NULL}, 15000, "tcp"}, {"hydap", {NULL}, 15000, "udp"}, {"xpilot", {NULL}, 15345, "tcp"}, {"xpilot", {NULL}, 15345, "udp"}, {"3link", {NULL}, 15363, "tcp"}, {"3link", {NULL}, 15363, "udp"}, {"cisco-snat", {NULL}, 15555, "tcp"}, {"cisco-snat", {NULL}, 15555, "udp"}, {"bex-xr", {NULL}, 15660, "tcp"}, {"bex-xr", {NULL}, 15660, "udp"}, {"ptp", {NULL}, 15740, "tcp"}, {"ptp", {NULL}, 15740, "udp"}, {"2ping", {NULL}, 15998, "udp"}, {"programmar", {NULL}, 15999, "tcp"}, {"fmsas", {NULL}, 16000, "tcp"}, {"fmsascon", {NULL}, 16001, "tcp"}, {"gsms", {NULL}, 16002, "tcp"}, {"alfin", {NULL}, 16003, "udp"}, {"jwpc", {NULL}, 16020, "tcp"}, {"jwpc-bin", {NULL}, 16021, "tcp"}, {"sun-sea-port", {NULL}, 16161, "tcp"}, {"sun-sea-port", {NULL}, 16161, "udp"}, {"solaris-audit", {NULL}, 16162, "tcp"}, {"etb4j", {NULL}, 16309, "tcp"}, {"etb4j", {NULL}, 16309, "udp"}, {"pduncs", {NULL}, 16310, "tcp"}, {"pduncs", {NULL}, 16310, "udp"}, {"pdefmns", {NULL}, 16311, "tcp"}, {"pdefmns", {NULL}, 16311, "udp"}, {"netserialext1", {NULL}, 16360, "tcp"}, {"netserialext1", {NULL}, 16360, "udp"}, {"netserialext2", {NULL}, 16361, "tcp"}, {"netserialext2", {NULL}, 16361, "udp"}, {"netserialext3", {NULL}, 16367, "tcp"}, {"netserialext3", {NULL}, 16367, "udp"}, {"netserialext4", {NULL}, 16368, "tcp"}, {"netserialext4", {NULL}, 16368, "udp"}, {"connected", {NULL}, 16384, "tcp"}, {"connected", {NULL}, 16384, "udp"}, {"xoms", {NULL}, 16619, "tcp"}, {"newbay-snc-mc", {NULL}, 16900, "tcp"}, {"newbay-snc-mc", {NULL}, 16900, "udp"}, {"sgcip", {NULL}, 16950, "tcp"}, {"sgcip", {NULL}, 16950, "udp"}, {"intel-rci-mp", {NULL}, 16991, "tcp"}, {"intel-rci-mp", {NULL}, 16991, "udp"}, {"amt-soap-http", {NULL}, 16992, "tcp"}, {"amt-soap-http", {NULL}, 16992, "udp"}, {"amt-soap-https", {NULL}, 16993, "tcp"}, {"amt-soap-https", {NULL}, 16993, "udp"}, {"amt-redir-tcp", {NULL}, 16994, "tcp"}, {"amt-redir-tcp", {NULL}, 16994, "udp"}, {"amt-redir-tls", {NULL}, 16995, "tcp"}, {"amt-redir-tls", {NULL}, 16995, "udp"}, {"isode-dua", {NULL}, 17007, "tcp"}, {"isode-dua", {NULL}, 17007, "udp"}, {"soundsvirtual", {NULL}, 17185, "tcp"}, {"soundsvirtual", {NULL}, 17185, "udp"}, {"chipper", {NULL}, 17219, "tcp"}, {"chipper", {NULL}, 17219, "udp"}, {"integrius-stp", {NULL}, 17234, "tcp"}, {"integrius-stp", {NULL}, 17234, "udp"}, {"ssh-mgmt", {NULL}, 17235, "tcp"}, {"ssh-mgmt", {NULL}, 17235, "udp"}, {"db-lsp", {NULL}, 17500, "tcp"}, {"db-lsp-disc", {NULL}, 17500, "udp"}, {"ea", {NULL}, 17729, "tcp"}, {"ea", {NULL}, 17729, "udp"}, {"zep", {NULL}, 17754, "tcp"}, {"zep", {NULL}, 17754, "udp"}, {"zigbee-ip", {NULL}, 17755, "tcp"}, {"zigbee-ip", {NULL}, 17755, "udp"}, {"zigbee-ips", {NULL}, 17756, "tcp"}, {"zigbee-ips", {NULL}, 17756, "udp"}, {"sw-orion", {NULL}, 17777, "tcp"}, {"biimenu", {NULL}, 18000, "tcp"}, {"biimenu", {NULL}, 18000, "udp"}, {"radpdf", {NULL}, 18104, "tcp"}, {"racf", {NULL}, 18136, "tcp"}, {"opsec-cvp", {NULL}, 18181, "tcp"}, {"opsec-cvp", {NULL}, 18181, "udp"}, {"opsec-ufp", {NULL}, 18182, "tcp"}, {"opsec-ufp", {NULL}, 18182, "udp"}, {"opsec-sam", {NULL}, 18183, "tcp"}, {"opsec-sam", {NULL}, 18183, "udp"}, {"opsec-lea", {NULL}, 18184, "tcp"}, {"opsec-lea", {NULL}, 18184, "udp"}, {"opsec-omi", {NULL}, 18185, "tcp"}, {"opsec-omi", {NULL}, 18185, "udp"}, {"ohsc", {NULL}, 18186, "tcp"}, {"ohsc", {NULL}, 18186, "udp"}, {"opsec-ela", {NULL}, 18187, "tcp"}, {"opsec-ela", {NULL}, 18187, "udp"}, {"checkpoint-rtm", {NULL}, 18241, "tcp"}, {"checkpoint-rtm", {NULL}, 18241, "udp"}, {"gv-pf", {NULL}, 18262, "tcp"}, {"gv-pf", {NULL}, 18262, "udp"}, {"ac-cluster", {NULL}, 18463, "tcp"}, {"ac-cluster", {NULL}, 18463, "udp"}, {"rds-ib", {NULL}, 18634, "tcp"}, {"rds-ib", {NULL}, 18634, "udp"}, {"rds-ip", {NULL}, 18635, "tcp"}, {"rds-ip", {NULL}, 18635, "udp"}, {"ique", {NULL}, 18769, "tcp"}, {"ique", {NULL}, 18769, "udp"}, {"infotos", {NULL}, 18881, "tcp"}, {"infotos", {NULL}, 18881, "udp"}, {"apc-necmp", {NULL}, 18888, "tcp"}, {"apc-necmp", {NULL}, 18888, "udp"}, {"igrid", {NULL}, 19000, "tcp"}, {"igrid", {NULL}, 19000, "udp"}, {"j-link", {NULL}, 19020, "tcp"}, {"opsec-uaa", {NULL}, 19191, "tcp"}, {"opsec-uaa", {NULL}, 19191, "udp"}, {"ua-secureagent", {NULL}, 19194, "tcp"}, {"ua-secureagent", {NULL}, 19194, "udp"}, {"keysrvr", {NULL}, 19283, "tcp"}, {"keysrvr", {NULL}, 19283, "udp"}, {"keyshadow", {NULL}, 19315, "tcp"}, {"keyshadow", {NULL}, 19315, "udp"}, {"mtrgtrans", {NULL}, 19398, "tcp"}, {"mtrgtrans", {NULL}, 19398, "udp"}, {"hp-sco", {NULL}, 19410, "tcp"}, {"hp-sco", {NULL}, 19410, "udp"}, {"hp-sca", {NULL}, 19411, "tcp"}, {"hp-sca", {NULL}, 19411, "udp"}, {"hp-sessmon", {NULL}, 19412, "tcp"}, {"hp-sessmon", {NULL}, 19412, "udp"}, {"fxuptp", {NULL}, 19539, "tcp"}, {"fxuptp", {NULL}, 19539, "udp"}, {"sxuptp", {NULL}, 19540, "tcp"}, {"sxuptp", {NULL}, 19540, "udp"}, {"jcp", {NULL}, 19541, "tcp"}, {"jcp", {NULL}, 19541, "udp"}, {"iec-104-sec", {NULL}, 19998, "tcp"}, {"dnp-sec", {NULL}, 19999, "tcp"}, {"dnp-sec", {NULL}, 19999, "udp"}, {"dnp", {NULL}, 20000, "tcp"}, {"dnp", {NULL}, 20000, "udp"}, {"microsan", {NULL}, 20001, "tcp"}, {"microsan", {NULL}, 20001, "udp"}, {"commtact-http", {NULL}, 20002, "tcp"}, {"commtact-http", {NULL}, 20002, "udp"}, {"commtact-https", {NULL}, 20003, "tcp"}, {"commtact-https", {NULL}, 20003, "udp"}, {"openwebnet", {NULL}, 20005, "tcp"}, {"openwebnet", {NULL}, 20005, "udp"}, {"ss-idi-disc", {NULL}, 20012, "udp"}, {"ss-idi", {NULL}, 20013, "tcp"}, {"opendeploy", {NULL}, 20014, "tcp"}, {"opendeploy", {NULL}, 20014, "udp"}, {"nburn_id", {NULL}, 20034, "tcp"}, {"nburn_id", {NULL}, 20034, "udp"}, {"tmophl7mts", {NULL}, 20046, "tcp"}, {"tmophl7mts", {NULL}, 20046, "udp"}, {"mountd", {NULL}, 20048, "tcp"}, {"mountd", {NULL}, 20048, "udp"}, {"nfsrdma", {NULL}, 20049, "tcp"}, {"nfsrdma", {NULL}, 20049, "udp"}, {"nfsrdma", {NULL}, 20049, "sctp"}, {"tolfab", {NULL}, 20167, "tcp"}, {"tolfab", {NULL}, 20167, "udp"}, {"ipdtp-port", {NULL}, 20202, "tcp"}, {"ipdtp-port", {NULL}, 20202, "udp"}, {"ipulse-ics", {NULL}, 20222, "tcp"}, {"ipulse-ics", {NULL}, 20222, "udp"}, {"emwavemsg", {NULL}, 20480, "tcp"}, {"emwavemsg", {NULL}, 20480, "udp"}, {"track", {NULL}, 20670, "tcp"}, {"track", {NULL}, 20670, "udp"}, {"athand-mmp", {NULL}, 20999, "tcp"}, {"athand-mmp", {NULL}, 20999, "udp"}, {"irtrans", {NULL}, 21000, "tcp"}, {"irtrans", {NULL}, 21000, "udp"}, {"dfserver", {NULL}, 21554, "tcp"}, {"dfserver", {NULL}, 21554, "udp"}, {"vofr-gateway", {NULL}, 21590, "tcp"}, {"vofr-gateway", {NULL}, 21590, "udp"}, {"tvpm", {NULL}, 21800, "tcp"}, {"tvpm", {NULL}, 21800, "udp"}, {"webphone", {NULL}, 21845, "tcp"}, {"webphone", {NULL}, 21845, "udp"}, {"netspeak-is", {NULL}, 21846, "tcp"}, {"netspeak-is", {NULL}, 21846, "udp"}, {"netspeak-cs", {NULL}, 21847, "tcp"}, {"netspeak-cs", {NULL}, 21847, "udp"}, {"netspeak-acd", {NULL}, 21848, "tcp"}, {"netspeak-acd", {NULL}, 21848, "udp"}, {"netspeak-cps", {NULL}, 21849, "tcp"}, {"netspeak-cps", {NULL}, 21849, "udp"}, {"snapenetio", {NULL}, 22000, "tcp"}, {"snapenetio", {NULL}, 22000, "udp"}, {"optocontrol", {NULL}, 22001, "tcp"}, {"optocontrol", {NULL}, 22001, "udp"}, {"optohost002", {NULL}, 22002, "tcp"}, {"optohost002", {NULL}, 22002, "udp"}, {"optohost003", {NULL}, 22003, "tcp"}, {"optohost003", {NULL}, 22003, "udp"}, {"optohost004", {NULL}, 22004, "tcp"}, {"optohost004", {NULL}, 22004, "udp"}, {"optohost004", {NULL}, 22005, "tcp"}, {"optohost004", {NULL}, 22005, "udp"}, {"dcap", {NULL}, 22125, "tcp"}, {"gsidcap", {NULL}, 22128, "tcp"}, {"wnn6", {NULL}, 22273, "tcp"}, {"wnn6", {NULL}, 22273, "udp"}, {"cis", {NULL}, 22305, "tcp"}, {"cis", {NULL}, 22305, "udp"}, {"cis-secure", {NULL}, 22343, "tcp"}, {"cis-secure", {NULL}, 22343, "udp"}, {"WibuKey", {NULL}, 22347, "tcp"}, {"WibuKey", {NULL}, 22347, "udp"}, {"CodeMeter", {NULL}, 22350, "tcp"}, {"CodeMeter", {NULL}, 22350, "udp"}, {"vocaltec-wconf", {NULL}, 22555, "tcp"}, {"vocaltec-phone", {NULL}, 22555, "udp"}, {"talikaserver", {NULL}, 22763, "tcp"}, {"talikaserver", {NULL}, 22763, "udp"}, {"aws-brf", {NULL}, 22800, "tcp"}, {"aws-brf", {NULL}, 22800, "udp"}, {"brf-gw", {NULL}, 22951, "tcp"}, {"brf-gw", {NULL}, 22951, "udp"}, {"inovaport1", {NULL}, 23000, "tcp"}, {"inovaport1", {NULL}, 23000, "udp"}, {"inovaport2", {NULL}, 23001, "tcp"}, {"inovaport2", {NULL}, 23001, "udp"}, {"inovaport3", {NULL}, 23002, "tcp"}, {"inovaport3", {NULL}, 23002, "udp"}, {"inovaport4", {NULL}, 23003, "tcp"}, {"inovaport4", {NULL}, 23003, "udp"}, {"inovaport5", {NULL}, 23004, "tcp"}, {"inovaport5", {NULL}, 23004, "udp"}, {"inovaport6", {NULL}, 23005, "tcp"}, {"inovaport6", {NULL}, 23005, "udp"}, {"s102", {NULL}, 23272, "udp"}, {"elxmgmt", {NULL}, 23333, "tcp"}, {"elxmgmt", {NULL}, 23333, "udp"}, {"novar-dbase", {NULL}, 23400, "tcp"}, {"novar-dbase", {NULL}, 23400, "udp"}, {"novar-alarm", {NULL}, 23401, "tcp"}, {"novar-alarm", {NULL}, 23401, "udp"}, {"novar-global", {NULL}, 23402, "tcp"}, {"novar-global", {NULL}, 23402, "udp"}, {"aequus", {NULL}, 23456, "tcp"}, {"aequus-alt", {NULL}, 23457, "tcp"}, {"med-ltp", {NULL}, 24000, "tcp"}, {"med-ltp", {NULL}, 24000, "udp"}, {"med-fsp-rx", {NULL}, 24001, "tcp"}, {"med-fsp-rx", {NULL}, 24001, "udp"}, {"med-fsp-tx", {NULL}, 24002, "tcp"}, {"med-fsp-tx", {NULL}, 24002, "udp"}, {"med-supp", {NULL}, 24003, "tcp"}, {"med-supp", {NULL}, 24003, "udp"}, {"med-ovw", {NULL}, 24004, "tcp"}, {"med-ovw", {NULL}, 24004, "udp"}, {"med-ci", {NULL}, 24005, "tcp"}, {"med-ci", {NULL}, 24005, "udp"}, {"med-net-svc", {NULL}, 24006, "tcp"}, {"med-net-svc", {NULL}, 24006, "udp"}, {"filesphere", {NULL}, 24242, "tcp"}, {"filesphere", {NULL}, 24242, "udp"}, {"vista-4gl", {NULL}, 24249, "tcp"}, {"vista-4gl", {NULL}, 24249, "udp"}, {"ild", {NULL}, 24321, "tcp"}, {"ild", {NULL}, 24321, "udp"}, {"intel_rci", {NULL}, 24386, "tcp"}, {"intel_rci", {NULL}, 24386, "udp"}, {"tonidods", {NULL}, 24465, "tcp"}, {"tonidods", {NULL}, 24465, "udp"}, {"binkp", {NULL}, 24554, "tcp"}, {"binkp", {NULL}, 24554, "udp"}, {"canditv", {NULL}, 24676, "tcp"}, {"canditv", {NULL}, 24676, "udp"}, {"flashfiler", {NULL}, 24677, "tcp"}, {"flashfiler", {NULL}, 24677, "udp"}, {"proactivate", {NULL}, 24678, "tcp"}, {"proactivate", {NULL}, 24678, "udp"}, {"tcc-http", {NULL}, 24680, "tcp"}, {"tcc-http", {NULL}, 24680, "udp"}, {"cslg", {NULL}, 24754, "tcp"}, {"find", {NULL}, 24922, "tcp"}, {"find", {NULL}, 24922, "udp"}, {"icl-twobase1", {NULL}, 25000, "tcp"}, {"icl-twobase1", {NULL}, 25000, "udp"}, {"icl-twobase2", {NULL}, 25001, "tcp"}, {"icl-twobase2", {NULL}, 25001, "udp"}, {"icl-twobase3", {NULL}, 25002, "tcp"}, {"icl-twobase3", {NULL}, 25002, "udp"}, {"icl-twobase4", {NULL}, 25003, "tcp"}, {"icl-twobase4", {NULL}, 25003, "udp"}, {"icl-twobase5", {NULL}, 25004, "tcp"}, {"icl-twobase5", {NULL}, 25004, "udp"}, {"icl-twobase6", {NULL}, 25005, "tcp"}, {"icl-twobase6", {NULL}, 25005, "udp"}, {"icl-twobase7", {NULL}, 25006, "tcp"}, {"icl-twobase7", {NULL}, 25006, "udp"}, {"icl-twobase8", {NULL}, 25007, "tcp"}, {"icl-twobase8", {NULL}, 25007, "udp"}, {"icl-twobase9", {NULL}, 25008, "tcp"}, {"icl-twobase9", {NULL}, 25008, "udp"}, {"icl-twobase10", {NULL}, 25009, "tcp"}, {"icl-twobase10", {NULL}, 25009, "udp"}, {"rna", {NULL}, 25471, "sctp"}, {"sauterdongle", {NULL}, 25576, "tcp"}, {"vocaltec-hos", {NULL}, 25793, "tcp"}, {"vocaltec-hos", {NULL}, 25793, "udp"}, {"tasp-net", {NULL}, 25900, "tcp"}, {"tasp-net", {NULL}, 25900, "udp"}, {"niobserver", {NULL}, 25901, "tcp"}, {"niobserver", {NULL}, 25901, "udp"}, {"nilinkanalyst", {NULL}, 25902, "tcp"}, {"nilinkanalyst", {NULL}, 25902, "udp"}, {"niprobe", {NULL}, 25903, "tcp"}, {"niprobe", {NULL}, 25903, "udp"}, {"quake", {NULL}, 26000, "tcp"}, {"quake", {NULL}, 26000, "udp"}, {"scscp", {NULL}, 26133, "tcp"}, {"scscp", {NULL}, 26133, "udp"}, {"wnn6-ds", {NULL}, 26208, "tcp"}, {"wnn6-ds", {NULL}, 26208, "udp"}, {"ezproxy", {NULL}, 26260, "tcp"}, {"ezproxy", {NULL}, 26260, "udp"}, {"ezmeeting", {NULL}, 26261, "tcp"}, {"ezmeeting", {NULL}, 26261, "udp"}, {"k3software-svr", {NULL}, 26262, "tcp"}, {"k3software-svr", {NULL}, 26262, "udp"}, {"k3software-cli", {NULL}, 26263, "tcp"}, {"k3software-cli", {NULL}, 26263, "udp"}, {"exoline-tcp", {NULL}, 26486, "tcp"}, {"exoline-udp", {NULL}, 26486, "udp"}, {"exoconfig", {NULL}, 26487, "tcp"}, {"exoconfig", {NULL}, 26487, "udp"}, {"exonet", {NULL}, 26489, "tcp"}, {"exonet", {NULL}, 26489, "udp"}, {"imagepump", {NULL}, 27345, "tcp"}, {"imagepump", {NULL}, 27345, "udp"}, {"jesmsjc", {NULL}, 27442, "tcp"}, {"jesmsjc", {NULL}, 27442, "udp"}, {"kopek-httphead", {NULL}, 27504, "tcp"}, {"kopek-httphead", {NULL}, 27504, "udp"}, {"ars-vista", {NULL}, 27782, "tcp"}, {"ars-vista", {NULL}, 27782, "udp"}, {"tw-auth-key", {NULL}, 27999, "tcp"}, {"tw-auth-key", {NULL}, 27999, "udp"}, {"nxlmd", {NULL}, 28000, "tcp"}, {"nxlmd", {NULL}, 28000, "udp"}, {"pqsp", {NULL}, 28001, "tcp"}, {"siemensgsm", {NULL}, 28240, "tcp"}, {"siemensgsm", {NULL}, 28240, "udp"}, {"sgsap", {NULL}, 29118, "sctp"}, {"otmp", {NULL}, 29167, "tcp"}, {"otmp", {NULL}, 29167, "udp"}, {"sbcap", {NULL}, 29168, "sctp"}, {"iuhsctpassoc", {NULL}, 29169, "sctp"}, {"pago-services1", {NULL}, 30001, "tcp"}, {"pago-services1", {NULL}, 30001, "udp"}, {"pago-services2", {NULL}, 30002, "tcp"}, {"pago-services2", {NULL}, 30002, "udp"}, {"kingdomsonline", {NULL}, 30260, "tcp"}, {"kingdomsonline", {NULL}, 30260, "udp"}, {"ovobs", {NULL}, 30999, "tcp"}, {"ovobs", {NULL}, 30999, "udp"}, {"autotrac-acp", {NULL}, 31020, "tcp"}, {"yawn", {NULL}, 31029, "udp"}, {"xqosd", {NULL}, 31416, "tcp"}, {"xqosd", {NULL}, 31416, "udp"}, {"tetrinet", {NULL}, 31457, "tcp"}, {"tetrinet", {NULL}, 31457, "udp"}, {"lm-mon", {NULL}, 31620, "tcp"}, {"lm-mon", {NULL}, 31620, "udp"}, {"dsx_monitor", {NULL}, 31685, "tcp"}, {"gamesmith-port", {NULL}, 31765, "tcp"}, {"gamesmith-port", {NULL}, 31765, "udp"}, {"iceedcp_tx", {NULL}, 31948, "tcp"}, {"iceedcp_tx", {NULL}, 31948, "udp"}, {"iceedcp_rx", {NULL}, 31949, "tcp"}, {"iceedcp_rx", {NULL}, 31949, "udp"}, {"iracinghelper", {NULL}, 32034, "tcp"}, {"iracinghelper", {NULL}, 32034, "udp"}, {"t1distproc60", {NULL}, 32249, "tcp"}, {"t1distproc60", {NULL}, 32249, "udp"}, {"apm-link", {NULL}, 32483, "tcp"}, {"apm-link", {NULL}, 32483, "udp"}, {"sec-ntb-clnt", {NULL}, 32635, "tcp"}, {"sec-ntb-clnt", {NULL}, 32635, "udp"}, {"DMExpress", {NULL}, 32636, "tcp"}, {"DMExpress", {NULL}, 32636, "udp"}, {"filenet-powsrm", {NULL}, 32767, "tcp"}, {"filenet-powsrm", {NULL}, 32767, "udp"}, {"filenet-tms", {NULL}, 32768, "tcp"}, {"filenet-tms", {NULL}, 32768, "udp"}, {"filenet-rpc", {NULL}, 32769, "tcp"}, {"filenet-rpc", {NULL}, 32769, "udp"}, {"filenet-nch", {NULL}, 32770, "tcp"}, {"filenet-nch", {NULL}, 32770, "udp"}, {"filenet-rmi", {NULL}, 32771, "tcp"}, {"filenet-rmi", {NULL}, 32771, "udp"}, {"filenet-pa", {NULL}, 32772, "tcp"}, {"filenet-pa", {NULL}, 32772, "udp"}, {"filenet-cm", {NULL}, 32773, "tcp"}, {"filenet-cm", {NULL}, 32773, "udp"}, {"filenet-re", {NULL}, 32774, "tcp"}, {"filenet-re", {NULL}, 32774, "udp"}, {"filenet-pch", {NULL}, 32775, "tcp"}, {"filenet-pch", {NULL}, 32775, "udp"}, {"filenet-peior", {NULL}, 32776, "tcp"}, {"filenet-peior", {NULL}, 32776, "udp"}, {"filenet-obrok", {NULL}, 32777, "tcp"}, {"filenet-obrok", {NULL}, 32777, "udp"}, {"mlsn", {NULL}, 32801, "tcp"}, {"mlsn", {NULL}, 32801, "udp"}, {"retp", {NULL}, 32811, "tcp"}, {"idmgratm", {NULL}, 32896, "tcp"}, {"idmgratm", {NULL}, 32896, "udp"}, {"aurora-balaena", {NULL}, 33123, "tcp"}, {"aurora-balaena", {NULL}, 33123, "udp"}, {"diamondport", {NULL}, 33331, "tcp"}, {"diamondport", {NULL}, 33331, "udp"}, {"dgi-serv", {NULL}, 33333, "tcp"}, {"traceroute", {NULL}, 33434, "tcp"}, {"traceroute", {NULL}, 33434, "udp"}, {"snip-slave", {NULL}, 33656, "tcp"}, {"snip-slave", {NULL}, 33656, "udp"}, {"turbonote-2", {NULL}, 34249, "tcp"}, {"turbonote-2", {NULL}, 34249, "udp"}, {"p-net-local", {NULL}, 34378, "tcp"}, {"p-net-local", {NULL}, 34378, "udp"}, {"p-net-remote", {NULL}, 34379, "tcp"}, {"p-net-remote", {NULL}, 34379, "udp"}, {"dhanalakshmi", {NULL}, 34567, "tcp"}, {"profinet-rt", {NULL}, 34962, "tcp"}, {"profinet-rt", {NULL}, 34962, "udp"}, {"profinet-rtm", {NULL}, 34963, "tcp"}, {"profinet-rtm", {NULL}, 34963, "udp"}, {"profinet-cm", {NULL}, 34964, "tcp"}, {"profinet-cm", {NULL}, 34964, "udp"}, {"ethercat", {NULL}, 34980, "tcp"}, {"ethercat", {NULL}, 34980, "udp"}, {"allpeers", {NULL}, 36001, "tcp"}, {"allpeers", {NULL}, 36001, "udp"}, {"s1-control", {NULL}, 36412, "sctp"}, {"x2-control", {NULL}, 36422, "sctp"}, {"m2ap", {NULL}, 36443, "sctp"}, {"m3ap", {NULL}, 36444, "sctp"}, {"kastenxpipe", {NULL}, 36865, "tcp"}, {"kastenxpipe", {NULL}, 36865, "udp"}, {"neckar", {NULL}, 37475, "tcp"}, {"neckar", {NULL}, 37475, "udp"}, {"unisys-eportal", {NULL}, 37654, "tcp"}, {"unisys-eportal", {NULL}, 37654, "udp"}, {"galaxy7-data", {NULL}, 38201, "tcp"}, {"galaxy7-data", {NULL}, 38201, "udp"}, {"fairview", {NULL}, 38202, "tcp"}, {"fairview", {NULL}, 38202, "udp"}, {"agpolicy", {NULL}, 38203, "tcp"}, {"agpolicy", {NULL}, 38203, "udp"}, {"turbonote-1", {NULL}, 39681, "tcp"}, {"turbonote-1", {NULL}, 39681, "udp"}, {"safetynetp", {NULL}, 40000, "tcp"}, {"safetynetp", {NULL}, 40000, "udp"}, {"cscp", {NULL}, 40841, "tcp"}, {"cscp", {NULL}, 40841, "udp"}, {"csccredir", {NULL}, 40842, "tcp"}, {"csccredir", {NULL}, 40842, "udp"}, {"csccfirewall", {NULL}, 40843, "tcp"}, {"csccfirewall", {NULL}, 40843, "udp"}, {"ortec-disc", {NULL}, 40853, "udp"}, {"fs-qos", {NULL}, 41111, "tcp"}, {"fs-qos", {NULL}, 41111, "udp"}, {"tentacle", {NULL}, 41121, "tcp"}, {"crestron-cip", {NULL}, 41794, "tcp"}, {"crestron-cip", {NULL}, 41794, "udp"}, {"crestron-ctp", {NULL}, 41795, "tcp"}, {"crestron-ctp", {NULL}, 41795, "udp"}, {"candp", {NULL}, 42508, "tcp"}, {"candp", {NULL}, 42508, "udp"}, {"candrp", {NULL}, 42509, "tcp"}, {"candrp", {NULL}, 42509, "udp"}, {"caerpc", {NULL}, 42510, "tcp"}, {"caerpc", {NULL}, 42510, "udp"}, {"reachout", {NULL}, 43188, "tcp"}, {"reachout", {NULL}, 43188, "udp"}, {"ndm-agent-port", {NULL}, 43189, "tcp"}, {"ndm-agent-port", {NULL}, 43189, "udp"}, {"ip-provision", {NULL}, 43190, "tcp"}, {"ip-provision", {NULL}, 43190, "udp"}, {"noit-transport", {NULL}, 43191, "tcp"}, {"ew-mgmt", {NULL}, 43440, "tcp"}, {"ew-disc-cmd", {NULL}, 43440, "udp"}, {"ciscocsdb", {NULL}, 43441, "tcp"}, {"ciscocsdb", {NULL}, 43441, "udp"}, {"pmcd", {NULL}, 44321, "tcp"}, {"pmcd", {NULL}, 44321, "udp"}, {"pmcdproxy", {NULL}, 44322, "tcp"}, {"pmcdproxy", {NULL}, 44322, "udp"}, {"pcp", {NULL}, 44323, "udp"}, {"rbr-debug", {NULL}, 44553, "tcp"}, {"rbr-debug", {NULL}, 44553, "udp"}, {"EtherNet/IP-2", {NULL}, 44818, "tcp"}, {"EtherNet/IP-2", {NULL}, 44818, "udp"}, {"invision-ag", {NULL}, 45054, "tcp"}, {"invision-ag", {NULL}, 45054, "udp"}, {"eba", {NULL}, 45678, "tcp"}, {"eba", {NULL}, 45678, "udp"}, {"qdb2service", {NULL}, 45825, "tcp"}, {"qdb2service", {NULL}, 45825, "udp"}, {"ssr-servermgr", {NULL}, 45966, "tcp"}, {"ssr-servermgr", {NULL}, 45966, "udp"}, {"mediabox", {NULL}, 46999, "tcp"}, {"mediabox", {NULL}, 46999, "udp"}, {"mbus", {NULL}, 47000, "tcp"}, {"mbus", {NULL}, 47000, "udp"}, {"winrm", {NULL}, 47001, "tcp"}, {"dbbrowse", {NULL}, 47557, "tcp"}, {"dbbrowse", {NULL}, 47557, "udp"}, {"directplaysrvr", {NULL}, 47624, "tcp"}, {"directplaysrvr", {NULL}, 47624, "udp"}, {"ap", {NULL}, 47806, "tcp"}, {"ap", {NULL}, 47806, "udp"}, {"bacnet", {NULL}, 47808, "tcp"}, {"bacnet", {NULL}, 47808, "udp"}, {"nimcontroller", {NULL}, 48000, "tcp"}, {"nimcontroller", {NULL}, 48000, "udp"}, {"nimspooler", {NULL}, 48001, "tcp"}, {"nimspooler", {NULL}, 48001, "udp"}, {"nimhub", {NULL}, 48002, "tcp"}, {"nimhub", {NULL}, 48002, "udp"}, {"nimgtw", {NULL}, 48003, "tcp"}, {"nimgtw", {NULL}, 48003, "udp"}, {"nimbusdb", {NULL}, 48004, "tcp"}, {"nimbusdbctrl", {NULL}, 48005, "tcp"}, {"3gpp-cbsp", {NULL}, 48049, "tcp"}, {"isnetserv", {NULL}, 48128, "tcp"}, {"isnetserv", {NULL}, 48128, "udp"}, {"blp5", {NULL}, 48129, "tcp"}, {"blp5", {NULL}, 48129, "udp"}, {"com-bardac-dw", {NULL}, 48556, "tcp"}, {"com-bardac-dw", {NULL}, 48556, "udp"}, {"iqobject", {NULL}, 48619, "tcp"}, {"iqobject", {NULL}, 48619, "udp"}, #endif /* USE_IANA_REGISTERED_PORTS */ { NULL, {NULL}, 0, NULL } }; struct servent *getservbyport(int port, const char *proto) { unsigned short u_port; const char *protocol = NULL; int i, error = 0; u_port = ntohs((unsigned short)port); if (proto) { switch (strlen(proto)) { case 3: if (!strncasecmp(proto, "tcp", 3)) protocol = "tcp"; else if (!strncasecmp(proto, "udp", 3)) protocol = "udp"; else error = WSAEFAULT; break; case 4: if (!strncasecmp(proto, "sctp", 4)) protocol = "sctp"; else if (!strncasecmp(proto, "dccp", 4)) protocol = "dccp"; else error = WSAEFAULT; break; default: error = WSAEFAULT; } } if (!error) { for (i = 0; i < (sizeof(IANAports) / sizeof(IANAports[0])) - 1; i++) { if (u_port == IANAports[i].s_port) { if (!protocol || !strcasecmp(protocol, IANAports[i].s_proto)) return (struct servent *)&IANAports[i]; } } error = WSANO_DATA; } SET_SOCKERRNO(error); return NULL; } #endif /* _WIN32_WCE */ node-v4.2.6/deps/cares/src/ares_platform.h000644 000766 000024 00000002201 12650222322 020563 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_PLATFORM_H #define HEADER_CARES_PLATFORM_H /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004 - 2011 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #if defined(WIN32) && !defined(MSDOS) typedef enum { WIN_UNKNOWN, WIN_3X, WIN_9X, WIN_NT, WIN_CE } win_platform; win_platform ares__getplatform(void); #endif #if defined(_WIN32_WCE) struct servent *getservbyport(int port, const char *proto); #endif #endif /* HEADER_CARES_PLATFORM_H */ node-v4.2.6/deps/cares/src/ares_private.h000644 000766 000024 00000023540 12650222322 020422 0ustar00iojsstaff000000 000000 #ifndef __ARES_PRIVATE_H #define __ARES_PRIVATE_H /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004-2010 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Define WIN32 when build target is Win32 API */ #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) #define WIN32 #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef WATT32 #include #include #define writev(s,v,c) writev_s(s,v,c) #define HAVE_WRITEV 1 #endif #define DEFAULT_TIMEOUT 5000 /* milliseconds */ #define DEFAULT_TRIES 4 #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif #if defined(WIN32) && !defined(WATT32) #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" #define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" #define NAMESERVER "NameServer" #define DHCPNAMESERVER "DhcpNameServer" #define DATABASEPATH "DatabasePath" #define WIN_PATH_HOSTS "\\hosts" #elif defined(WATT32) #define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" #elif defined(NETWARE) #define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" #define PATH_HOSTS "sys:/etc/hosts" #elif defined(__riscos__) #define PATH_HOSTS "InetDBase:Hosts" #else #define PATH_RESOLV_CONF "/etc/resolv.conf" #ifdef ETC_INET #define PATH_HOSTS "/etc/inet/hosts" #else #define PATH_HOSTS "/etc/hosts" #endif #endif #define ARES_ID_KEY_LEN 31 #include "ares_ipv6.h" #include "ares_llist.h" #ifndef HAVE_GETENV # include "ares_getenv.h" # define getenv(ptr) ares_getenv(ptr) #endif #ifndef HAVE_STRDUP # include "ares_strdup.h" # define strdup(ptr) ares_strdup(ptr) #endif #ifndef HAVE_STRCASECMP # include "ares_strcasecmp.h" # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2) #endif #ifndef HAVE_STRNCASECMP # include "ares_strcasecmp.h" # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) #endif #ifndef HAVE_WRITEV # include "ares_writev.h" # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) #endif /********* EDNS defines section ******/ #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested in RFC2671 */ #define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ #define EDNSFIXEDSZ 11 /* Size of EDNS header */ /********* EDNS defines section ******/ struct ares_addr { int family; union { struct in_addr addr4; struct ares_in6_addr addr6; } addr; }; #define addrV4 addr.addr4 #define addrV6 addr.addr6 struct query; struct send_request { /* Remaining data to send */ const unsigned char *data; size_t len; /* The query for which we're sending this data */ struct query* owner_query; /* The buffer we're using, if we have our own copy of the packet */ unsigned char *data_storage; /* Next request in queue */ struct send_request *next; }; struct server_state { struct ares_addr addr; ares_socket_t udp_socket; ares_socket_t tcp_socket; /* Mini-buffer for reading the length word */ unsigned char tcp_lenbuf[2]; int tcp_lenbuf_pos; int tcp_length; /* Buffer for reading actual TCP data */ unsigned char *tcp_buffer; int tcp_buffer_pos; /* TCP output queue */ struct send_request *qhead; struct send_request *qtail; /* Which incarnation of this connection is this? We don't want to * retransmit requests into the very same socket, but if the server * closes on us and we re-open the connection, then we do want to * re-send. */ int tcp_connection_generation; /* Circular, doubly-linked list of outstanding queries to this server */ struct list_node queries_to_server; /* Link back to owning channel */ ares_channel channel; /* Is this server broken? We mark connections as broken when a * request that is queued for sending times out. */ int is_broken; }; /* State to represent a DNS query */ struct query { /* Query ID from qbuf, for faster lookup, and current timeout */ unsigned short qid; struct timeval timeout; /* * Links for the doubly-linked lists in which we insert a query. * These circular, doubly-linked lists that are hash-bucketed based * the attributes we care about, help making most important * operations O(1). */ struct list_node queries_by_qid; /* hopefully in same cache line as qid */ struct list_node queries_by_timeout; struct list_node queries_to_server; struct list_node all_queries; /* Query buf with length at beginning, for TCP transmission */ unsigned char *tcpbuf; int tcplen; /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ const unsigned char *qbuf; int qlen; ares_callback callback; void *arg; /* Query status */ int try_count; /* Number of times we tried this query already. */ int server; /* Server this query has last been sent to. */ struct query_server_info *server_info; /* per-server state */ int using_tcp; int error_status; int timeouts; /* number of timeouts we saw for this request */ }; /* Per-server state for a query */ struct query_server_info { int skip_server; /* should we skip server, due to errors, etc? */ int tcp_connection_generation; /* into which TCP connection did we send? */ }; /* An IP address pattern; matches an IP address X if X & mask == addr */ #define PATTERN_MASK 0x1 #define PATTERN_CIDR 0x2 struct apattern { union { struct in_addr addr4; struct ares_in6_addr addr6; } addr; union { struct in_addr addr4; struct ares_in6_addr addr6; unsigned short bits; } mask; int family; unsigned short type; }; typedef struct rc4_key { unsigned char state[256]; unsigned char x; unsigned char y; } rc4_key; struct ares_channeldata { /* Configuration data */ int flags; int timeout; /* in milliseconds */ int tries; int ndots; int rotate; /* if true, all servers specified are used */ int udp_port; int tcp_port; int socket_send_buffer_size; int socket_receive_buffer_size; char **domains; int ndomains; struct apattern *sortlist; int nsort; char *lookups; int ednspsz; /* For binding to local devices and/or IP addresses. Leave * them null/zero for no binding. */ char local_dev_name[32]; unsigned int local_ip4; unsigned char local_ip6[16]; int optmask; /* the option bitfield passed in at init time */ /* Server addresses and communications state */ struct server_state *servers; int nservers; /* ID to use for next query */ unsigned short next_id; /* key to use when generating new ids */ rc4_key id_key; /* Generation number to use for the next TCP socket open/close */ int tcp_connection_generation; /* The time at which we last called process_timeouts(). Uses integer seconds just to draw the line somewhere. */ time_t last_timeout_processed; /* Last server we sent a query to. */ int last_server; /* Circular, doubly-linked list of queries, bucketed various ways.... */ /* All active queries in a single list: */ struct list_node all_queries; /* Queries bucketed by qid, for quickly dispatching DNS responses: */ #define ARES_QID_TABLE_SIZE 2048 struct list_node queries_by_qid[ARES_QID_TABLE_SIZE]; /* Queries bucketed by timeout, for quickly handling timeouts: */ #define ARES_TIMEOUT_TABLE_SIZE 1024 struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE]; ares_sock_state_cb sock_state_cb; void *sock_state_cb_data; ares_sock_create_callback sock_create_cb; void *sock_create_cb_data; }; /* return true if now is exactly check time or later */ int ares__timedout(struct timeval *now, struct timeval *check); /* returns ARES_SUCCESS if library has been initialized */ int ares_library_initialized(void); void ares__send_query(ares_channel channel, struct query *query, struct timeval *now); void ares__close_sockets(ares_channel channel, struct server_state *server); int ares__get_hostent(FILE *fp, int family, struct hostent **host); int ares__read_line(FILE *fp, char **buf, size_t *bufsize); void ares__free_query(struct query *query); unsigned short ares__generate_new_id(rc4_key* key); struct timeval ares__tvnow(void); int ares__expand_name_for_response(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen); void ares__init_servers_state(ares_channel channel); void ares__destroy_servers_state(ares_channel channel); #if 0 /* Not used */ long ares__tvdiff(struct timeval t1, struct timeval t2); #endif #define ARES_SWAP_BYTE(a,b) \ { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } #define SOCK_STATE_CALLBACK(c, s, r, w) \ do { \ if ((c)->sock_state_cb) \ (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ } WHILE_FALSE #ifdef CURLDEBUG /* This is low-level hard-hacking memory leak tracking and similar. Using the libcurl lowlevel code from within library is ugly and only works when c-ares is built and linked with a similarly curldebug-enabled libcurl, but we do this anyway for convenience. */ #define HEADER_CURL_SETUP_ONCE_H #include "../lib/memdebug.h" #endif #endif /* __ARES_PRIVATE_H */ node-v4.2.6/deps/cares/src/ares_process.c000644 000766 000024 00000121362 12650222322 020422 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2004-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_SYS_UIO_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_NETINET_TCP_H # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef NETWARE # include #endif #include #include #include "ares.h" #include "ares_dns.h" #include "ares_nowarn.h" #include "ares_private.h" static int try_again(int errnum); static void write_tcp_data(ares_channel channel, fd_set *write_fds, ares_socket_t write_fd, struct timeval *now); static void read_tcp_data(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, struct timeval *now); static void read_udp_packets(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, struct timeval *now); static void advance_tcp_send_queue(ares_channel channel, int whichserver, ssize_t num_bytes); static void process_timeouts(ares_channel channel, struct timeval *now); static void process_broken_connections(ares_channel channel, struct timeval *now); static void process_answer(ares_channel channel, unsigned char *abuf, int alen, int whichserver, int tcp, struct timeval *now); static void handle_error(ares_channel channel, int whichserver, struct timeval *now); static void skip_server(ares_channel channel, struct query *query, int whichserver); static void next_server(ares_channel channel, struct query *query, struct timeval *now); static int open_tcp_socket(ares_channel channel, struct server_state *server); static int open_udp_socket(ares_channel channel, struct server_state *server); static int same_questions(const unsigned char *qbuf, int qlen, const unsigned char *abuf, int alen); static int same_address(struct sockaddr *sa, struct ares_addr *aa); static void end_query(ares_channel channel, struct query *query, int status, unsigned char *abuf, int alen); /* return true if now is exactly check time or later */ int ares__timedout(struct timeval *now, struct timeval *check) { long secs = (now->tv_sec - check->tv_sec); if(secs > 0) return 1; /* yes, timed out */ if(secs < 0) return 0; /* nope, not timed out */ /* if the full seconds were identical, check the sub second parts */ return (now->tv_usec - check->tv_usec >= 0); } /* add the specific number of milliseconds to the time in the first argument */ static void timeadd(struct timeval *now, int millisecs) { now->tv_sec += millisecs/1000; now->tv_usec += (millisecs%1000)*1000; if(now->tv_usec >= 1000000) { ++(now->tv_sec); now->tv_usec -= 1000000; } } /* * generic process function */ static void processfds(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, fd_set *write_fds, ares_socket_t write_fd) { struct timeval now = ares__tvnow(); write_tcp_data(channel, write_fds, write_fd, &now); read_tcp_data(channel, read_fds, read_fd, &now); read_udp_packets(channel, read_fds, read_fd, &now); process_timeouts(channel, &now); process_broken_connections(channel, &now); } /* Something interesting happened on the wire, or there was a timeout. * See what's up and respond accordingly. */ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) { processfds(channel, read_fds, ARES_SOCKET_BAD, write_fds, ARES_SOCKET_BAD); } /* Something interesting happened on the wire, or there was a timeout. * See what's up and respond accordingly. */ void ares_process_fd(ares_channel channel, ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid file descriptors */ ares_socket_t write_fd) { processfds(channel, NULL, read_fd, NULL, write_fd); } /* Return 1 if the specified error number describes a readiness error, or 0 * otherwise. This is mostly for HP-UX, which could return EAGAIN or * EWOULDBLOCK. See this man page * * http://devrsrc1.external.hp.com/STKS/cgi-bin/man2html? * manpage=/usr/share/man/man2.Z/send.2 */ static int try_again(int errnum) { #if !defined EWOULDBLOCK && !defined EAGAIN #error "Neither EWOULDBLOCK nor EAGAIN defined" #endif switch (errnum) { #ifdef EWOULDBLOCK case EWOULDBLOCK: return 1; #endif #if defined EAGAIN && EAGAIN != EWOULDBLOCK case EAGAIN: return 1; #endif } return 0; } /* If any TCP sockets select true for writing, write out queued data * we have for them. */ static void write_tcp_data(ares_channel channel, fd_set *write_fds, ares_socket_t write_fd, struct timeval *now) { struct server_state *server; struct send_request *sendreq; struct iovec *vec; int i; ssize_t scount; ssize_t wcount; size_t n; if(!write_fds && (write_fd == ARES_SOCKET_BAD)) /* no possible action */ return; for (i = 0; i < channel->nservers; i++) { /* Make sure server has data to send and is selected in write_fds or write_fd. */ server = &channel->servers[i]; if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD || server->is_broken) continue; if(write_fds) { if(!FD_ISSET(server->tcp_socket, write_fds)) continue; } else { if(server->tcp_socket != write_fd) continue; } if(write_fds) /* If there's an error and we close this socket, then open * another with the same fd to talk to another server, then we * don't want to think that it was the new socket that was * ready. This is not disastrous, but is likely to result in * extra system calls and confusion. */ FD_CLR(server->tcp_socket, write_fds); /* Count the number of send queue items. */ n = 0; for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) n++; /* Allocate iovecs so we can send all our data at once. */ vec = malloc(n * sizeof(struct iovec)); if (vec) { /* Fill in the iovecs and send. */ n = 0; for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) { vec[n].iov_base = (char *) sendreq->data; vec[n].iov_len = sendreq->len; n++; } wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n); free(vec); if (wcount < 0) { if (!try_again(SOCKERRNO)) handle_error(channel, i, now); continue; } /* Advance the send queue by as many bytes as we sent. */ advance_tcp_send_queue(channel, i, wcount); } else { /* Can't allocate iovecs; just send the first request. */ sendreq = server->qhead; scount = swrite(server->tcp_socket, sendreq->data, sendreq->len); if (scount < 0) { if (!try_again(SOCKERRNO)) handle_error(channel, i, now); continue; } /* Advance the send queue by as many bytes as we sent. */ advance_tcp_send_queue(channel, i, scount); } } } /* Consume the given number of bytes from the head of the TCP send queue. */ static void advance_tcp_send_queue(ares_channel channel, int whichserver, ssize_t num_bytes) { struct send_request *sendreq; struct server_state *server = &channel->servers[whichserver]; while (num_bytes > 0) { sendreq = server->qhead; if ((size_t)num_bytes >= sendreq->len) { num_bytes -= sendreq->len; server->qhead = sendreq->next; if (sendreq->data_storage) free(sendreq->data_storage); free(sendreq); if (server->qhead == NULL) { SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 0); server->qtail = NULL; /* qhead is NULL so we cannot continue this loop */ break; } } else { sendreq->data += num_bytes; sendreq->len -= num_bytes; num_bytes = 0; } } } /* If any TCP socket selects true for reading, read some data, * allocate a buffer if we finish reading the length word, and process * a packet if we finish reading one. */ static void read_tcp_data(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, struct timeval *now) { struct server_state *server; int i; ssize_t count; if(!read_fds && (read_fd == ARES_SOCKET_BAD)) /* no possible action */ return; for (i = 0; i < channel->nservers; i++) { /* Make sure the server has a socket and is selected in read_fds. */ server = &channel->servers[i]; if (server->tcp_socket == ARES_SOCKET_BAD || server->is_broken) continue; if(read_fds) { if(!FD_ISSET(server->tcp_socket, read_fds)) continue; } else { if(server->tcp_socket != read_fd) continue; } if(read_fds) /* If there's an error and we close this socket, then open another * with the same fd to talk to another server, then we don't want to * think that it was the new socket that was ready. This is not * disastrous, but is likely to result in extra system calls and * confusion. */ FD_CLR(server->tcp_socket, read_fds); if (server->tcp_lenbuf_pos != 2) { /* We haven't yet read a length word, so read that (or * what's left to read of it). */ count = sread(server->tcp_socket, server->tcp_lenbuf + server->tcp_lenbuf_pos, 2 - server->tcp_lenbuf_pos); if (count <= 0) { if (!(count == -1 && try_again(SOCKERRNO))) handle_error(channel, i, now); continue; } server->tcp_lenbuf_pos += (int)count; if (server->tcp_lenbuf_pos == 2) { /* We finished reading the length word. Decode the * length and allocate a buffer for the data. */ server->tcp_length = server->tcp_lenbuf[0] << 8 | server->tcp_lenbuf[1]; server->tcp_buffer = malloc(server->tcp_length); if (!server->tcp_buffer) handle_error(channel, i, now); server->tcp_buffer_pos = 0; } } else { /* Read data into the allocated buffer. */ count = sread(server->tcp_socket, server->tcp_buffer + server->tcp_buffer_pos, server->tcp_length - server->tcp_buffer_pos); if (count <= 0) { if (!(count == -1 && try_again(SOCKERRNO))) handle_error(channel, i, now); continue; } server->tcp_buffer_pos += (int)count; if (server->tcp_buffer_pos == server->tcp_length) { /* We finished reading this answer; process it and * prepare to read another length word. */ process_answer(channel, server->tcp_buffer, server->tcp_length, i, 1, now); if (server->tcp_buffer) free(server->tcp_buffer); server->tcp_buffer = NULL; server->tcp_lenbuf_pos = 0; server->tcp_buffer_pos = 0; } } } } /* If any UDP sockets select true for reading, process them. */ static void read_udp_packets(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, struct timeval *now) { struct server_state *server; int i; ssize_t count; unsigned char buf[MAXENDSSZ + 1]; #ifdef HAVE_RECVFROM ares_socklen_t fromlen; union { struct sockaddr sa; struct sockaddr_in sa4; struct sockaddr_in6 sa6; } from; #endif if(!read_fds && (read_fd == ARES_SOCKET_BAD)) /* no possible action */ return; for (i = 0; i < channel->nservers; i++) { /* Make sure the server has a socket and is selected in read_fds. */ server = &channel->servers[i]; if (server->udp_socket == ARES_SOCKET_BAD || server->is_broken) continue; if(read_fds) { if(!FD_ISSET(server->udp_socket, read_fds)) continue; } else { if(server->udp_socket != read_fd) continue; } if(read_fds) /* If there's an error and we close this socket, then open * another with the same fd to talk to another server, then we * don't want to think that it was the new socket that was * ready. This is not disastrous, but is likely to result in * extra system calls and confusion. */ FD_CLR(server->udp_socket, read_fds); /* To reduce event loop overhead, read and process as many * packets as we can. */ do { if (server->udp_socket == ARES_SOCKET_BAD) count = 0; else { #ifdef HAVE_RECVFROM if (server->addr.family == AF_INET) fromlen = sizeof(from.sa4); else fromlen = sizeof(from.sa6); count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf), 0, &from.sa, &fromlen); #else count = sread(server->udp_socket, buf, sizeof(buf)); #endif } if (count == -1 && try_again(SOCKERRNO)) continue; else if (count <= 0) handle_error(channel, i, now); #ifdef HAVE_RECVFROM else if (!same_address(&from.sa, &server->addr)) /* The address the response comes from does not match the address we * sent the request to. Someone may be attempting to perform a cache * poisoning attack. */ break; #endif else process_answer(channel, buf, (int)count, i, 0, now); } while (count > 0); } } /* If any queries have timed out, note the timeout and move them on. */ static void process_timeouts(ares_channel channel, struct timeval *now) { time_t t; /* the time of the timeouts we're processing */ struct query *query; struct list_node* list_head; struct list_node* list_node; /* Process all the timeouts that have fired since the last time we processed * timeouts. If things are going well, then we'll have hundreds/thousands of * queries that fall into future buckets, and only a handful of requests * that fall into the "now" bucket, so this should be quite quick. */ for (t = channel->last_timeout_processed; t <= now->tv_sec; t++) { list_head = &(channel->queries_by_timeout[t % ARES_TIMEOUT_TABLE_SIZE]); for (list_node = list_head->next; list_node != list_head; ) { query = list_node->data; list_node = list_node->next; /* in case the query gets deleted */ if (query->timeout.tv_sec && ares__timedout(now, &query->timeout)) { query->error_status = ARES_ETIMEOUT; ++query->timeouts; next_server(channel, query, now); } } } channel->last_timeout_processed = now->tv_sec; } /* Handle an answer from a server. */ static void process_answer(ares_channel channel, unsigned char *abuf, int alen, int whichserver, int tcp, struct timeval *now) { int tc, rcode, packetsz; unsigned short id; struct query *query; struct list_node* list_head; struct list_node* list_node; /* If there's no room in the answer for a header, we can't do much * with it. */ if (alen < HFIXEDSZ) return; /* Grab the query ID, truncate bit, and response code from the packet. */ id = DNS_HEADER_QID(abuf); tc = DNS_HEADER_TC(abuf); rcode = DNS_HEADER_RCODE(abuf); /* Find the query corresponding to this packet. The queries are * hashed/bucketed by query id, so this lookup should be quick. Note that * both the query id and the questions must be the same; when the query id * wraps around we can have multiple outstanding queries with the same query * id, so we need to check both the id and question. */ query = NULL; list_head = &(channel->queries_by_qid[id % ARES_QID_TABLE_SIZE]); for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) { struct query *q = list_node->data; if ((q->qid == id) && same_questions(q->qbuf, q->qlen, abuf, alen)) { query = q; break; } } if (!query) return; packetsz = PACKETSZ; /* If we use EDNS and server answers with one of these RCODES, the protocol * extension is not understood by the responder. We must retry the query * without EDNS enabled. */ if (channel->flags & ARES_FLAG_EDNS) { packetsz = channel->ednspsz; if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL) { int qlen = alen - EDNSFIXEDSZ; channel->flags ^= ARES_FLAG_EDNS; query->tcplen -= EDNSFIXEDSZ; query->qlen -= EDNSFIXEDSZ; query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff); query->tcpbuf[1] = (unsigned char)(qlen & 0xff); DNS_HEADER_SET_ARCOUNT(query->tcpbuf + 2, 0); query->tcpbuf = realloc(query->tcpbuf, query->tcplen); ares__send_query(channel, query, now); return; } } /* If we got a truncated UDP packet and are not ignoring truncation, * don't accept the packet, and switch the query to TCP if we hadn't * done so already. */ if ((tc || alen > packetsz) && !tcp && !(channel->flags & ARES_FLAG_IGNTC)) { if (!query->using_tcp) { query->using_tcp = 1; ares__send_query(channel, query, now); } return; } /* Limit alen to PACKETSZ if we aren't using TCP (only relevant if we * are ignoring truncation. */ if (alen > packetsz && !tcp) alen = packetsz; /* If we aren't passing through all error packets, discard packets * with SERVFAIL, NOTIMP, or REFUSED response codes. */ if (!(channel->flags & ARES_FLAG_NOCHECKRESP)) { if (rcode == SERVFAIL || rcode == NOTIMP || rcode == REFUSED) { skip_server(channel, query, whichserver); if (query->server == whichserver) next_server(channel, query, now); return; } } end_query(channel, query, ARES_SUCCESS, abuf, alen); } /* Close all the connections that are no longer usable. */ static void process_broken_connections(ares_channel channel, struct timeval *now) { int i; for (i = 0; i < channel->nservers; i++) { struct server_state *server = &channel->servers[i]; if (server->is_broken) { handle_error(channel, i, now); } } } /* Swap the contents of two lists */ static void swap_lists(struct list_node* head_a, struct list_node* head_b) { int is_a_empty = ares__is_list_empty(head_a); int is_b_empty = ares__is_list_empty(head_b); struct list_node old_a = *head_a; struct list_node old_b = *head_b; if (is_a_empty) { ares__init_list_head(head_b); } else { *head_b = old_a; old_a.next->prev = head_b; old_a.prev->next = head_b; } if (is_b_empty) { ares__init_list_head(head_a); } else { *head_a = old_b; old_b.next->prev = head_a; old_b.prev->next = head_a; } } static void handle_error(ares_channel channel, int whichserver, struct timeval *now) { struct server_state *server; struct query *query; struct list_node list_head; struct list_node* list_node; server = &channel->servers[whichserver]; /* Reset communications with this server. */ ares__close_sockets(channel, server); /* Tell all queries talking to this server to move on and not try this * server again. We steal the current list of queries that were in-flight to * this server, since when we call next_server this can cause the queries to * be re-sent to this server, which will re-insert these queries in that * same server->queries_to_server list. */ ares__init_list_head(&list_head); swap_lists(&list_head, &(server->queries_to_server)); for (list_node = list_head.next; list_node != &list_head; ) { query = list_node->data; list_node = list_node->next; /* in case the query gets deleted */ assert(query->server == whichserver); skip_server(channel, query, whichserver); next_server(channel, query, now); } /* Each query should have removed itself from our temporary list as * it re-sent itself or finished up... */ assert(ares__is_list_empty(&list_head)); } static void skip_server(ares_channel channel, struct query *query, int whichserver) { /* The given server gave us problems with this query, so if we have the * luxury of using other servers, then let's skip the potentially broken * server and just use the others. If we only have one server and we need to * retry then we should just go ahead and re-use that server, since it's our * only hope; perhaps we just got unlucky, and retrying will work (eg, the * server timed out our TCP connection just as we were sending another * request). */ if (channel->nservers > 1) { query->server_info[whichserver].skip_server = 1; } } static void next_server(ares_channel channel, struct query *query, struct timeval *now) { /* We need to try each server channel->tries times. We have channel->nservers * servers to try. In total, we need to do channel->nservers * channel->tries * attempts. Use query->try to remember how many times we already attempted * this query. Use modular arithmetic to find the next server to try. */ while (++(query->try_count) < (channel->nservers * channel->tries)) { struct server_state *server; /* Move on to the next server. */ query->server = (query->server + 1) % channel->nservers; server = &channel->servers[query->server]; /* We don't want to use this server if (1) we decided this connection is * broken, and thus about to be closed, (2) we've decided to skip this * server because of earlier errors we encountered, or (3) we already * sent this query over this exact connection. */ if (!server->is_broken && !query->server_info[query->server].skip_server && !(query->using_tcp && (query->server_info[query->server].tcp_connection_generation == server->tcp_connection_generation))) { ares__send_query(channel, query, now); return; } /* You might think that with TCP we only need one try. However, even * when using TCP, servers can time-out our connection just as we're * sending a request, or close our connection because they die, or never * send us a reply because they get wedged or tickle a bug that drops * our request. */ } /* If we are here, all attempts to perform query failed. */ end_query(channel, query, query->error_status, NULL, 0); } void ares__send_query(ares_channel channel, struct query *query, struct timeval *now) { struct send_request *sendreq; struct server_state *server; int timeplus; server = &channel->servers[query->server]; if (query->using_tcp) { /* Make sure the TCP socket for this server is set up and queue * a send request. */ if (server->tcp_socket == ARES_SOCKET_BAD) { if (open_tcp_socket(channel, server) == -1) { skip_server(channel, query, query->server); next_server(channel, query, now); return; } } sendreq = calloc(1, sizeof(struct send_request)); if (!sendreq) { end_query(channel, query, ARES_ENOMEM, NULL, 0); return; } /* To make the common case fast, we avoid copies by using the query's * tcpbuf for as long as the query is alive. In the rare case where the * query ends while it's queued for transmission, then we give the * sendreq its own copy of the request packet and put it in * sendreq->data_storage. */ sendreq->data_storage = NULL; sendreq->data = query->tcpbuf; sendreq->len = query->tcplen; sendreq->owner_query = query; sendreq->next = NULL; if (server->qtail) server->qtail->next = sendreq; else { SOCK_STATE_CALLBACK(channel, server->tcp_socket, 1, 1); server->qhead = sendreq; } server->qtail = sendreq; query->server_info[query->server].tcp_connection_generation = server->tcp_connection_generation; } else { if (server->udp_socket == ARES_SOCKET_BAD) { if (open_udp_socket(channel, server) == -1) { skip_server(channel, query, query->server); next_server(channel, query, now); return; } } if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) { /* FIXME: Handle EAGAIN here since it likely can happen. */ skip_server(channel, query, query->server); next_server(channel, query, now); return; } } timeplus = channel->timeout << (query->try_count / channel->nservers); timeplus = (timeplus * (9 + (rand () & 7))) / 16; query->timeout = *now; timeadd(&query->timeout, timeplus); /* Keep track of queries bucketed by timeout, so we can process * timeout events quickly. */ ares__remove_from_list(&(query->queries_by_timeout)); ares__insert_in_list( &(query->queries_by_timeout), &(channel->queries_by_timeout[query->timeout.tv_sec % ARES_TIMEOUT_TABLE_SIZE])); /* Keep track of queries bucketed by server, so we can process server * errors quickly. */ ares__remove_from_list(&(query->queries_to_server)); ares__insert_in_list(&(query->queries_to_server), &(server->queries_to_server)); } /* * setsocknonblock sets the given socket to either blocking or non-blocking * mode based on the 'nonblock' boolean argument. This function is highly * portable. */ static int setsocknonblock(ares_socket_t sockfd, /* operate on this */ int nonblock /* TRUE or FALSE */) { #if defined(USE_BLOCKING_SOCKETS) return 0; /* returns success */ #elif defined(HAVE_FCNTL_O_NONBLOCK) /* most recent unix versions */ int flags; flags = fcntl(sockfd, F_GETFL, 0); if (FALSE != nonblock) return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); else return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); #elif defined(HAVE_IOCTL_FIONBIO) /* older unix versions */ int flags = nonblock ? 1 : 0; return ioctl(sockfd, FIONBIO, &flags); #elif defined(HAVE_IOCTLSOCKET_FIONBIO) #ifdef WATT32 char flags = nonblock ? 1 : 0; #else /* Windows */ unsigned long flags = nonblock ? 1UL : 0UL; #endif return ioctlsocket(sockfd, FIONBIO, &flags); #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) /* Amiga */ long flags = nonblock ? 1L : 0L; return IoctlSocket(sockfd, FIONBIO, flags); #elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) /* BeOS */ long b = nonblock ? 1L : 0L; return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); #else # error "no non-blocking method was found/used/set" #endif } static int configure_socket(ares_socket_t s, int family, ares_channel channel) { union { struct sockaddr sa; struct sockaddr_in sa4; struct sockaddr_in6 sa6; } local; setsocknonblock(s, TRUE); #if defined(FD_CLOEXEC) && !defined(MSDOS) /* Configure the socket fd as close-on-exec. */ if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) return -1; #endif /* Set the socket's send and receive buffer sizes. */ if ((channel->socket_send_buffer_size > 0) && setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void *)&channel->socket_send_buffer_size, sizeof(channel->socket_send_buffer_size)) == -1) return -1; if ((channel->socket_receive_buffer_size > 0) && setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void *)&channel->socket_receive_buffer_size, sizeof(channel->socket_receive_buffer_size)) == -1) return -1; #ifdef SO_BINDTODEVICE if (channel->local_dev_name[0]) { if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, channel->local_dev_name, sizeof(channel->local_dev_name))) { /* Only root can do this, and usually not fatal if it doesn't work, so */ /* just continue on. */ } } #endif if (family == AF_INET) { if (channel->local_ip4) { memset(&local.sa4, 0, sizeof(local.sa4)); local.sa4.sin_family = AF_INET; local.sa4.sin_addr.s_addr = htonl(channel->local_ip4); if (bind(s, &local.sa, sizeof(local.sa4)) < 0) return -1; } } else if (family == AF_INET6) { if (memcmp(channel->local_ip6, &ares_in6addr_any, sizeof(channel->local_ip6)) != 0) { memset(&local.sa6, 0, sizeof(local.sa6)); local.sa6.sin6_family = AF_INET6; memcpy(&local.sa6.sin6_addr, channel->local_ip6, sizeof(channel->local_ip6)); if (bind(s, &local.sa, sizeof(local.sa6)) < 0) return -1; } } return 0; } static int open_tcp_socket(ares_channel channel, struct server_state *server) { ares_socket_t s; int opt; ares_socklen_t salen; union { struct sockaddr_in sa4; struct sockaddr_in6 sa6; } saddr; struct sockaddr *sa; switch (server->addr.family) { case AF_INET: sa = (void *)&saddr.sa4; salen = sizeof(saddr.sa4); memset(sa, 0, salen); saddr.sa4.sin_family = AF_INET; saddr.sa4.sin_port = aresx_sitous(channel->tcp_port); memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4, sizeof(server->addr.addrV4)); break; case AF_INET6: sa = (void *)&saddr.sa6; salen = sizeof(saddr.sa6); memset(sa, 0, salen); saddr.sa6.sin6_family = AF_INET6; saddr.sa6.sin6_port = aresx_sitous(channel->tcp_port); memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6, sizeof(server->addr.addrV6)); break; default: return -1; } /* Acquire a socket. */ s = socket(server->addr.family, SOCK_STREAM, 0); if (s == ARES_SOCKET_BAD) return -1; /* Configure it. */ if (configure_socket(s, server->addr.family, channel) < 0) { sclose(s); return -1; } #ifdef TCP_NODELAY /* * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not * in configure_socket). In general, in DNS lookups we're pretty much * interested in firing off a single request and then waiting for a reply, * so batching isn't very interesting. */ opt = 1; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)) == -1) { sclose(s); return -1; } #endif /* Connect to the server. */ if (connect(s, sa, salen) == -1) { int err = SOCKERRNO; if (err != EINPROGRESS && err != EWOULDBLOCK) { sclose(s); return -1; } } if (channel->sock_create_cb) { int err = channel->sock_create_cb(s, SOCK_STREAM, channel->sock_create_cb_data); if (err < 0) { sclose(s); return err; } } SOCK_STATE_CALLBACK(channel, s, 1, 0); server->tcp_buffer_pos = 0; server->tcp_socket = s; server->tcp_connection_generation = ++channel->tcp_connection_generation; return 0; } static int open_udp_socket(ares_channel channel, struct server_state *server) { ares_socket_t s; ares_socklen_t salen; union { struct sockaddr_in sa4; struct sockaddr_in6 sa6; } saddr; struct sockaddr *sa; switch (server->addr.family) { case AF_INET: sa = (void *)&saddr.sa4; salen = sizeof(saddr.sa4); memset(sa, 0, salen); saddr.sa4.sin_family = AF_INET; saddr.sa4.sin_port = aresx_sitous(channel->udp_port); memcpy(&saddr.sa4.sin_addr, &server->addr.addrV4, sizeof(server->addr.addrV4)); break; case AF_INET6: sa = (void *)&saddr.sa6; salen = sizeof(saddr.sa6); memset(sa, 0, salen); saddr.sa6.sin6_family = AF_INET6; saddr.sa6.sin6_port = aresx_sitous(channel->udp_port); memcpy(&saddr.sa6.sin6_addr, &server->addr.addrV6, sizeof(server->addr.addrV6)); break; default: return -1; } /* Acquire a socket. */ s = socket(server->addr.family, SOCK_DGRAM, 0); if (s == ARES_SOCKET_BAD) return -1; /* Set the socket non-blocking. */ if (configure_socket(s, server->addr.family, channel) < 0) { sclose(s); return -1; } /* Connect to the server. */ if (connect(s, sa, salen) == -1) { int err = SOCKERRNO; if (err != EINPROGRESS && err != EWOULDBLOCK) { sclose(s); return -1; } } if (channel->sock_create_cb) { int err = channel->sock_create_cb(s, SOCK_DGRAM, channel->sock_create_cb_data); if (err < 0) { sclose(s); return err; } } SOCK_STATE_CALLBACK(channel, s, 1, 0); server->udp_socket = s; return 0; } static int same_questions(const unsigned char *qbuf, int qlen, const unsigned char *abuf, int alen) { struct { const unsigned char *p; int qdcount; char *name; long namelen; int type; int dnsclass; } q, a; int i, j; if (qlen < HFIXEDSZ || alen < HFIXEDSZ) return 0; /* Extract qdcount from the request and reply buffers and compare them. */ q.qdcount = DNS_HEADER_QDCOUNT(qbuf); a.qdcount = DNS_HEADER_QDCOUNT(abuf); if (q.qdcount != a.qdcount) return 0; /* For each question in qbuf, find it in abuf. */ q.p = qbuf + HFIXEDSZ; for (i = 0; i < q.qdcount; i++) { /* Decode the question in the query. */ if (ares_expand_name(q.p, qbuf, qlen, &q.name, &q.namelen) != ARES_SUCCESS) return 0; q.p += q.namelen; if (q.p + QFIXEDSZ > qbuf + qlen) { free(q.name); return 0; } q.type = DNS_QUESTION_TYPE(q.p); q.dnsclass = DNS_QUESTION_CLASS(q.p); q.p += QFIXEDSZ; /* Search for this question in the answer. */ a.p = abuf + HFIXEDSZ; for (j = 0; j < a.qdcount; j++) { /* Decode the question in the answer. */ if (ares_expand_name(a.p, abuf, alen, &a.name, &a.namelen) != ARES_SUCCESS) { free(q.name); return 0; } a.p += a.namelen; if (a.p + QFIXEDSZ > abuf + alen) { free(q.name); free(a.name); return 0; } a.type = DNS_QUESTION_TYPE(a.p); a.dnsclass = DNS_QUESTION_CLASS(a.p); a.p += QFIXEDSZ; /* Compare the decoded questions. */ if (strcasecmp(q.name, a.name) == 0 && q.type == a.type && q.dnsclass == a.dnsclass) { free(a.name); break; } free(a.name); } free(q.name); if (j == a.qdcount) return 0; } return 1; } static int same_address(struct sockaddr *sa, struct ares_addr *aa) { void *addr1; void *addr2; if (sa->sa_family == aa->family) { switch (aa->family) { case AF_INET: addr1 = &aa->addrV4; addr2 = &((struct sockaddr_in *)sa)->sin_addr; if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0) return 1; /* match */ break; case AF_INET6: addr1 = &aa->addrV6; addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr; if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0) return 1; /* match */ break; default: break; } } return 0; /* different */ } static void end_query (ares_channel channel, struct query *query, int status, unsigned char *abuf, int alen) { int i; /* First we check to see if this query ended while one of our send * queues still has pointers to it. */ for (i = 0; i < channel->nservers; i++) { struct server_state *server = &channel->servers[i]; struct send_request *sendreq; for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) if (sendreq->owner_query == query) { sendreq->owner_query = NULL; assert(sendreq->data_storage == NULL); if (status == ARES_SUCCESS) { /* We got a reply for this query, but this queued sendreq * points into this soon-to-be-gone query's tcpbuf. Probably * this means we timed out and queued the query for * retransmission, then received a response before actually * retransmitting. This is perfectly fine, so we want to keep * the connection running smoothly if we can. But in the worst * case we may have sent only some prefix of the query, with * some suffix of the query left to send. Also, the buffer may * be queued on multiple queues. To prevent dangling pointers * to the query's tcpbuf and handle these cases, we just give * such sendreqs their own copy of the query packet. */ sendreq->data_storage = malloc(sendreq->len); if (sendreq->data_storage != NULL) { memcpy(sendreq->data_storage, sendreq->data, sendreq->len); sendreq->data = sendreq->data_storage; } } if ((status != ARES_SUCCESS) || (sendreq->data_storage == NULL)) { /* We encountered an error (probably a timeout, suggesting the * DNS server we're talking to is probably unreachable, * wedged, or severely overloaded) or we couldn't copy the * request, so mark the connection as broken. When we get to * process_broken_connections() we'll close the connection and * try to re-send requests to another server. */ server->is_broken = 1; /* Just to be paranoid, zero out this sendreq... */ sendreq->data = NULL; sendreq->len = 0; } } } /* Invoke the callback */ query->callback(query->arg, status, query->timeouts, abuf, alen); ares__free_query(query); /* Simple cleanup policy: if no queries are remaining, close all network * sockets unless STAYOPEN is set. */ if (!(channel->flags & ARES_FLAG_STAYOPEN) && ares__is_list_empty(&(channel->all_queries))) { for (i = 0; i < channel->nservers; i++) ares__close_sockets(channel, &channel->servers[i]); } } void ares__free_query(struct query *query) { /* Remove the query from all the lists in which it is linked */ ares__remove_from_list(&(query->queries_by_qid)); ares__remove_from_list(&(query->queries_by_timeout)); ares__remove_from_list(&(query->queries_to_server)); ares__remove_from_list(&(query->all_queries)); /* Zero out some important stuff, to help catch bugs */ query->callback = NULL; query->arg = NULL; /* Deallocate the memory associated with the query */ free(query->tcpbuf); free(query->server_info); free(query); } node-v4.2.6/deps/cares/src/ares_query.c000644 000766 000024 00000011660 12650222322 020110 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_private.h" struct qquery { ares_callback callback; void *arg; }; static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) { unsigned char x; unsigned char y; unsigned char* state; unsigned char xorIndex; short counter; x = key->x; y = key->y; state = &key->state[0]; for(counter = 0; counter < buffer_len; counter ++) { x = (unsigned char)((x + 1) % 256); y = (unsigned char)((state[x] + y) % 256); ARES_SWAP_BYTE(&state[x], &state[y]); xorIndex = (unsigned char)((state[x] + state[y]) % 256); buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]); } key->x = x; key->y = y; } static struct query* find_query_by_id(ares_channel channel, unsigned short id) { unsigned short qid; struct list_node* list_head; struct list_node* list_node; DNS_HEADER_SET_QID(((unsigned char*)&qid), id); /* Find the query corresponding to this packet. */ list_head = &(channel->queries_by_qid[qid % ARES_QID_TABLE_SIZE]); for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) { struct query *q = list_node->data; if (q->qid == qid) return q; } return NULL; } /* a unique query id is generated using an rc4 key. Since the id may already be used by a running query (as infrequent as it may be), a lookup is performed per id generation. In practice this search should happen only once per newly generated id */ static unsigned short generate_unique_id(ares_channel channel) { unsigned short id; do { id = ares__generate_new_id(&channel->id_key); } while (find_query_by_id(channel, id)); return (unsigned short)id; } unsigned short ares__generate_new_id(rc4_key* key) { unsigned short r=0; rc4(key, (unsigned char *)&r, sizeof(r)); return r; } void ares_query(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) { struct qquery *qquery; unsigned char *qbuf; int qlen, rd, status; /* Compose the query. */ rd = !(channel->flags & ARES_FLAG_NORECURSE); status = ares_create_query(name, dnsclass, type, channel->next_id, rd, &qbuf, &qlen, (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0); if (status != ARES_SUCCESS) { if (qbuf != NULL) free(qbuf); callback(arg, status, 0, NULL, 0); return; } channel->next_id = generate_unique_id(channel); /* Allocate and fill in the query structure. */ qquery = malloc(sizeof(struct qquery)); if (!qquery) { ares_free_string(qbuf); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } qquery->callback = callback; qquery->arg = arg; /* Send it off. qcallback will be called when we get an answer. */ ares_send(channel, qbuf, qlen, qcallback, qquery); ares_free_string(qbuf); } static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct qquery *qquery = (struct qquery *) arg; unsigned int ancount; int rcode; if (status != ARES_SUCCESS) qquery->callback(qquery->arg, status, timeouts, abuf, alen); else { /* Pull the response code and answer count from the packet. */ rcode = DNS_HEADER_RCODE(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); /* Convert errors. */ switch (rcode) { case NOERROR: status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA; break; case FORMERR: status = ARES_EFORMERR; break; case SERVFAIL: status = ARES_ESERVFAIL; break; case NXDOMAIN: status = ARES_ENOTFOUND; break; case NOTIMP: status = ARES_ENOTIMP; break; case REFUSED: status = ARES_EREFUSED; break; } qquery->callback(qquery->arg, status, timeouts, abuf, alen); } free(qquery); } node-v4.2.6/deps/cares/src/ares_rules.h000644 000766 000024 00000010534 12650222322 020101 0ustar00iojsstaff000000 000000 #ifndef __CARES_RULES_H #define __CARES_RULES_H /* Copyright (C) 2009 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* ================================================================ */ /* COMPILE TIME SANITY CHECKS */ /* ================================================================ */ /* * NOTE 1: * ------- * * All checks done in this file are intentionally placed in a public * header file which is pulled by ares.h when an application is * being built using an already built c-ares library. Additionally * this file is also included and used when building the library. * * If compilation fails on this file it is certainly sure that the * problem is elsewhere. It could be a problem in the ares_build.h * header file, or simply that you are using different compilation * settings than those used to build the library. * * Nothing in this file is intended to be modified or adjusted by the * c-ares library user nor by the c-ares library builder. * * Do not deactivate any check, these are done to make sure that the * library is properly built and used. * * You can find further help on the c-ares development mailing list: * http://cool.haxx.se/mailman/listinfo/c-ares/ * * NOTE 2 * ------ * * Some of the following compile time checks are based on the fact * that the dimension of a constant array can not be a negative one. * In this way if the compile time verification fails, the compilation * will fail issuing an error. The error description wording is compiler * dependent but it will be quite similar to one of the following: * * "negative subscript or subscript is too large" * "array must have at least one element" * "-1 is an illegal array size" * "size of array is negative" * * If you are building an application which tries to use an already * built c-ares library and you are getting this kind of errors on * this file, it is a clear indication that there is a mismatch between * how the library was built and how you are trying to use it for your * application. Your already compiled or binary library provider is the * only one who can give you the details you need to properly use it. */ /* * Verify that some macros are actually defined. */ #ifndef CARES_TYPEOF_ARES_SOCKLEN_T # error "CARES_TYPEOF_ARES_SOCKLEN_T definition is missing!" Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_is_missing #endif #ifndef CARES_SIZEOF_ARES_SOCKLEN_T # error "CARES_SIZEOF_ARES_SOCKLEN_T definition is missing!" Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_is_missing #endif /* * Macros private to this header file. */ #define CareschkszEQ(t, s) sizeof(t) == s ? 1 : -1 #define CareschkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 /* * Verify that the size previously defined and expected for * ares_socklen_t is actually the the same as the one reported * by sizeof() at compile time. */ typedef char __cares_rule_02__ [CareschkszEQ(ares_socklen_t, CARES_SIZEOF_ARES_SOCKLEN_T)]; /* * Verify at compile time that the size of ares_socklen_t as reported * by sizeof() is greater or equal than the one reported for int for * the current compilation. */ typedef char __cares_rule_03__ [CareschkszGE(ares_socklen_t, int)]; /* ================================================================ */ /* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ /* ================================================================ */ /* * Get rid of macros private to this header file. */ #undef CareschkszEQ #undef CareschkszGE /* * Get rid of macros not intended to exist beyond this point. */ #undef CARES_PULL_WS2TCPIP_H #undef CARES_PULL_SYS_TYPES_H #undef CARES_PULL_SYS_SOCKET_H #undef CARES_TYPEOF_ARES_SOCKLEN_T #endif /* __CARES_RULES_H */ node-v4.2.6/deps/cares/src/ares_search.c000644 000766 000024 00000022565 12650222322 020216 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_STRINGS_H # include #endif #include "ares.h" #include "ares_private.h" struct search_query { /* Arguments passed to ares_search */ ares_channel channel; char *name; /* copied into an allocated buffer */ int dnsclass; int type; ares_callback callback; void *arg; int status_as_is; /* error status from trying as-is */ int next_domain; /* next search domain to try */ int trying_as_is; /* current query is for name as-is */ int timeouts; /* number of timeouts we saw for this request */ int ever_got_nodata; /* did we ever get ARES_ENODATA along the way? */ }; static void search_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_squery(struct search_query *squery, int status, unsigned char *abuf, int alen); static int cat_domain(const char *name, const char *domain, char **s); static int single_domain(ares_channel channel, const char *name, char **s); void ares_search(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) { struct search_query *squery; char *s; const char *p; int status, ndots; /* If name only yields one domain to search, then we don't have * to keep extra state, so just do an ares_query(). */ status = single_domain(channel, name, &s); if (status != ARES_SUCCESS) { callback(arg, status, 0, NULL, 0); return; } if (s) { ares_query(channel, s, dnsclass, type, callback, arg); free(s); return; } /* Allocate a search_query structure to hold the state necessary for * doing multiple lookups. */ squery = malloc(sizeof(struct search_query)); if (!squery) { callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } squery->channel = channel; squery->name = strdup(name); if (!squery->name) { free(squery); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } squery->dnsclass = dnsclass; squery->type = type; squery->status_as_is = -1; squery->callback = callback; squery->arg = arg; squery->timeouts = 0; squery->ever_got_nodata = 0; /* Count the number of dots in name. */ ndots = 0; for (p = name; *p; p++) { if (*p == '.') ndots++; } /* If ndots is at least the channel ndots threshold (usually 1), * then we try the name as-is first. Otherwise, we try the name * as-is last. */ if (ndots >= channel->ndots) { /* Try the name as-is first. */ squery->next_domain = 0; squery->trying_as_is = 1; ares_query(channel, name, dnsclass, type, search_callback, squery); } else { /* Try the name as-is last; start with the first search domain. */ squery->next_domain = 1; squery->trying_as_is = 0; status = cat_domain(name, channel->domains[0], &s); if (status == ARES_SUCCESS) { ares_query(channel, s, dnsclass, type, search_callback, squery); free(s); } else { /* failed, free the malloc()ed memory */ free(squery->name); free(squery); callback(arg, status, 0, NULL, 0); } } } static void search_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct search_query *squery = (struct search_query *) arg; ares_channel channel = squery->channel; char *s; squery->timeouts += timeouts; /* Stop searching unless we got a non-fatal error. */ if (status != ARES_ENODATA && status != ARES_ESERVFAIL && status != ARES_ENOTFOUND) end_squery(squery, status, abuf, alen); else { /* Save the status if we were trying as-is. */ if (squery->trying_as_is) squery->status_as_is = status; /* * If we ever get ARES_ENODATA along the way, record that; if the search * should run to the very end and we got at least one ARES_ENODATA, * then callers like ares_gethostbyname() may want to try a T_A search * even if the last domain we queried for T_AAAA resource records * returned ARES_ENOTFOUND. */ if (status == ARES_ENODATA) squery->ever_got_nodata = 1; if (squery->next_domain < channel->ndomains) { /* Try the next domain. */ status = cat_domain(squery->name, channel->domains[squery->next_domain], &s); if (status != ARES_SUCCESS) end_squery(squery, status, NULL, 0); else { squery->trying_as_is = 0; squery->next_domain++; ares_query(channel, s, squery->dnsclass, squery->type, search_callback, squery); free(s); } } else if (squery->status_as_is == -1) { /* Try the name as-is at the end. */ squery->trying_as_is = 1; ares_query(channel, squery->name, squery->dnsclass, squery->type, search_callback, squery); } else { if (squery->status_as_is == ARES_ENOTFOUND && squery->ever_got_nodata) { end_squery(squery, ARES_ENODATA, NULL, 0); } else end_squery(squery, squery->status_as_is, NULL, 0); } } } static void end_squery(struct search_query *squery, int status, unsigned char *abuf, int alen) { squery->callback(squery->arg, status, squery->timeouts, abuf, alen); free(squery->name); free(squery); } /* Concatenate two domains. */ static int cat_domain(const char *name, const char *domain, char **s) { size_t nlen = strlen(name); size_t dlen = strlen(domain); *s = malloc(nlen + 1 + dlen + 1); if (!*s) return ARES_ENOMEM; memcpy(*s, name, nlen); (*s)[nlen] = '.'; memcpy(*s + nlen + 1, domain, dlen); (*s)[nlen + 1 + dlen] = 0; return ARES_SUCCESS; } /* Determine if this name only yields one query. If it does, set *s to * the string we should query, in an allocated buffer. If not, set *s * to NULL. */ static int single_domain(ares_channel channel, const char *name, char **s) { size_t len = strlen(name); const char *hostaliases; FILE *fp; char *line = NULL; int status; size_t linesize; const char *p, *q; int error; /* If the name contains a trailing dot, then the single query is the name * sans the trailing dot. */ if ((len > 0) && (name[len - 1] == '.')) { *s = strdup(name); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } if (!(channel->flags & ARES_FLAG_NOALIASES) && !strchr(name, '.')) { /* The name might be a host alias. */ hostaliases = getenv("HOSTALIASES"); if (hostaliases) { fp = fopen(hostaliases, "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { if (strncasecmp(line, name, len) != 0 || !ISSPACE(line[len])) continue; p = line + len; while (ISSPACE(*p)) p++; if (*p) { q = p + 1; while (*q && !ISSPACE(*q)) q++; *s = malloc(q - p + 1); if (*s) { memcpy(*s, p, q - p); (*s)[q - p] = 0; } free(line); fclose(fp); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } } free(line); fclose(fp); if (status != ARES_SUCCESS && status != ARES_EOF) return status; } else { error = ERRNO; switch(error) { case ENOENT: case ESRCH: break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", hostaliases)); *s = NULL; return ARES_EFILE; } } } } if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0) { /* No domain search to do; just try the name as-is. */ *s = strdup(name); return (*s) ? ARES_SUCCESS : ARES_ENOMEM; } *s = NULL; return ARES_SUCCESS; } node-v4.2.6/deps/cares/src/ares_send.c000644 000766 000024 00000007644 12650222322 017703 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_dns.h" #include "ares_private.h" void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, ares_callback callback, void *arg) { struct query *query; int i, packetsz; struct timeval now; /* Verify that the query is at least long enough to hold the header. */ if (qlen < HFIXEDSZ || qlen >= (1 << 16)) { callback(arg, ARES_EBADQUERY, 0, NULL, 0); return; } /* Allocate space for query and allocated fields. */ query = malloc(sizeof(struct query)); if (!query) { callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } query->tcpbuf = malloc(qlen + 2); if (!query->tcpbuf) { free(query); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } query->server_info = malloc(channel->nservers * sizeof(query->server_info[0])); if (!query->server_info) { free(query->tcpbuf); free(query); callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } /* Compute the query ID. Start with no timeout. */ query->qid = DNS_HEADER_QID(qbuf); query->timeout.tv_sec = 0; query->timeout.tv_usec = 0; /* Form the TCP query buffer by prepending qlen (as two * network-order bytes) to qbuf. */ query->tcpbuf[0] = (unsigned char)((qlen >> 8) & 0xff); query->tcpbuf[1] = (unsigned char)(qlen & 0xff); memcpy(query->tcpbuf + 2, qbuf, qlen); query->tcplen = qlen + 2; /* Fill in query arguments. */ query->qbuf = query->tcpbuf + 2; query->qlen = qlen; query->callback = callback; query->arg = arg; /* Initialize query status. */ query->try_count = 0; /* Choose the server to send the query to. If rotation is enabled, keep track * of the next server we want to use. */ query->server = channel->last_server; if (channel->rotate == 1) channel->last_server = (channel->last_server + 1) % channel->nservers; for (i = 0; i < channel->nservers; i++) { query->server_info[i].skip_server = 0; query->server_info[i].tcp_connection_generation = 0; } packetsz = (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : PACKETSZ; query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > packetsz; query->error_status = ARES_ECONNREFUSED; query->timeouts = 0; /* Initialize our list nodes. */ ares__init_list_node(&(query->queries_by_qid), query); ares__init_list_node(&(query->queries_by_timeout), query); ares__init_list_node(&(query->queries_to_server), query); ares__init_list_node(&(query->all_queries), query); /* Chain the query into the list of all queries. */ ares__insert_in_list(&(query->all_queries), &(channel->all_queries)); /* Keep track of queries bucketed by qid, so we can process DNS * responses quickly. */ ares__insert_in_list( &(query->queries_by_qid), &(channel->queries_by_qid[query->qid % ARES_QID_TABLE_SIZE])); /* Perform the first query action. */ now = ares__tvnow(); ares__send_query(channel, query, &now); } node-v4.2.6/deps/cares/src/ares_setup.h000644 000766 000024 00000013567 12650222322 020120 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_SETUP_H #define HEADER_CARES_SETUP_H /* Copyright (C) 2004 - 2012 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* * Define WIN32 when build target is Win32 API */ #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) #define WIN32 #endif /* * Include configuration script results or hand-crafted * configuration file for platforms which lack config tool. */ #ifdef HAVE_CONFIG_H #include "ares_config.h" #else #ifdef WIN32 #include "config-win32.h" #endif #endif /* HAVE_CONFIG_H */ /* ================================================================ */ /* Definition of preprocessor macros/symbols which modify compiler */ /* behaviour or generated code characteristics must be done here, */ /* as appropriate, before any system header file is included. It is */ /* also possible to have them defined in the config file included */ /* before this point. As a result of all this we frown inclusion of */ /* system header files in our config files, avoid this at any cost. */ /* ================================================================ */ /* * AIX 4.3 and newer needs _THREAD_SAFE defined to build * proper reentrant code. Others may also need it. */ #ifdef NEED_THREAD_SAFE # ifndef _THREAD_SAFE # define _THREAD_SAFE # endif #endif /* * Tru64 needs _REENTRANT set for a few function prototypes and * things to appear in the system header files. Unixware needs it * to build proper reentrant code. Others may also need it. */ #ifdef NEED_REENTRANT # ifndef _REENTRANT # define _REENTRANT # endif #endif /* ================================================================ */ /* If you need to include a system header file for your platform, */ /* please, do it beyond the point further indicated in this file. */ /* ================================================================ */ #if 1 # define SIZEOF_SHORT 2 #else /* Disabled for the gyp-ified build. */ /* * c-ares external interface definitions are also used internally, * and might also include required system header files to define them. */ #include /* * Compile time sanity checks must also be done when building the library. */ #include #endif /* ================================================================= */ /* No system header file shall be included in this file before this */ /* point. The only allowed ones are those included from ares_build.h */ /* ================================================================= */ /* * Include header files for windows builds before redefining anything. * Use this preproessor block only to include or exclude windows.h, * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs * to any other further and independent block. Under Cygwin things work * just as under linux (e.g. ) and the winsock headers should * never be included when __CYGWIN__ is defined. configure script takes * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. */ #ifdef HAVE_WINDOWS_H # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif # include # ifdef HAVE_WINSOCK2_H # include # ifdef HAVE_WS2TCPIP_H # include # endif # else # ifdef HAVE_WINSOCK_H # include # endif # endif #endif /* * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else * define USE_WINSOCK to 1 if we have and use WINSOCK API, else * undefine USE_WINSOCK. */ #undef USE_WINSOCK #ifdef HAVE_WINSOCK2_H # define USE_WINSOCK 2 #else # ifdef HAVE_WINSOCK_H # define USE_WINSOCK 1 # endif #endif /* * Work-arounds for systems without configure support */ #ifndef HAVE_CONFIG_H #if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__) #define HAVE_SYS_TIME_H #endif #if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER) #define HAVE_UNISTD_H 1 #endif #if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS) #define HAVE_SYS_UIO_H #endif #endif /* HAVE_CONFIG_H */ /* * Arg 2 type for gethostname in case it hasn't been defined in config file. */ #ifndef GETHOSTNAME_TYPE_ARG2 # ifdef USE_WINSOCK # define GETHOSTNAME_TYPE_ARG2 int # else # define GETHOSTNAME_TYPE_ARG2 size_t # endif #endif #ifdef __POCC__ # include # include # define ESRCH 3 #endif /* * Android does have the arpa/nameser.h header which is detected by configure * but it appears to be empty with recent NDK r7b / r7c, so we undefine here. */ #if (defined(ANDROID) || defined(__ANDROID__)) && defined(HAVE_ARPA_NAMESER_H) # undef HAVE_ARPA_NAMESER_H #endif /* * Recent autoconf versions define these symbols in ares_config.h. We don't * want them (since they collide with the libcurl ones when we build * --enable-debug) so we undef them again here. */ #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef VERSION #undef PACKAGE /* IPv6 compatibility */ #if !defined(HAVE_AF_INET6) #if defined(HAVE_PF_INET6) #define AF_INET6 PF_INET6 #else #define AF_INET6 AF_MAX+1 #endif #endif /* * Include macros and defines that should only be processed once. */ #ifndef __SETUP_ONCE_H #include "setup_once.h" #endif #endif /* HEADER_CARES_SETUP_H */ node-v4.2.6/deps/cares/src/ares_strcasecmp.c000644 000766 000024 00000003150 12650222322 021102 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares_strcasecmp.h" #ifndef HAVE_STRCASECMP int ares_strcasecmp(const char *a, const char *b) { #if defined(HAVE_STRCMPI) return strcmpi(a, b); #elif defined(HAVE_STRICMP) return stricmp(a, b); #else size_t i; for (i = 0; i < (size_t)-1; i++) { int c1 = ISUPPER(a[i]) ? tolower(a[i]) : a[i]; int c2 = ISUPPER(b[i]) ? tolower(b[i]) : b[i]; if (c1 != c2) return c1-c2; if (!c1) break; } return 0; #endif } #endif #ifndef HAVE_STRNCASECMP int ares_strncasecmp(const char *a, const char *b, size_t n) { #if defined(HAVE_STRNCMPI) return strncmpi(a, b, n); #elif defined(HAVE_STRNICMP) return strnicmp(a, b, n); #else size_t i; for (i = 0; i < n; i++) { int c1 = ISUPPER(a[i]) ? tolower(a[i]) : a[i]; int c2 = ISUPPER(b[i]) ? tolower(b[i]) : b[i]; if (c1 != c2) return c1-c2; if (!c1) break; } return 0; #endif } #endif node-v4.2.6/deps/cares/src/ares_strcasecmp.h000644 000766 000024 00000002007 12650222322 021107 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_STRCASECMP_H #define HEADER_CARES_STRCASECMP_H /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifndef HAVE_STRCASECMP extern int ares_strcasecmp(const char *a, const char *b); #endif #ifndef HAVE_STRNCASECMP extern int ares_strncasecmp(const char *a, const char *b, size_t n); #endif #endif /* HEADER_CARES_STRCASECMP_H */ node-v4.2.6/deps/cares/src/ares_strdup.c000644 000766 000024 00000002162 12650222322 020261 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares_strdup.h" #ifndef HAVE_STRDUP char *ares_strdup(const char *s1) { size_t sz; char * s2; if(s1) { sz = strlen(s1); if(sz < (size_t)-1) { sz++; if(sz < ((size_t)-1) / sizeof(char)) { s2 = malloc(sz * sizeof(char)); if(s2) { memcpy(s2, s1, sz * sizeof(char)); return s2; } } } } return (char *)NULL; } #endif node-v4.2.6/deps/cares/src/ares_strdup.h000644 000766 000024 00000001601 12650222322 020263 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_STRDUP_H #define HEADER_CARES_STRDUP_H /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifndef HAVE_STRDUP extern char *ares_strdup(const char *s1); #endif #endif /* HEADER_CARES_STRDUP_H */ node-v4.2.6/deps/cares/src/ares_strerror.c000644 000766 000024 00000003553 12650222322 020627 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include #include "ares.h" const char *ares_strerror(int code) { /* Return a string literal from a table. */ const char *errtext[] = { "Successful completion", "DNS server returned answer with no data", "DNS server claims query was misformatted", "DNS server returned general failure", "Domain name not found", "DNS server does not implement requested operation", "DNS server refused query", "Misformatted DNS query", "Misformatted domain name", "Unsupported address family", "Misformatted DNS reply", "Could not contact DNS servers", "Timeout while contacting DNS servers", "End of file", "Error reading file", "Out of memory", "Channel is being destroyed", "Misformatted string", "Illegal flags specified", "Given hostname is not numeric", "Illegal hints flags specified", "c-ares library initialization not yet performed", "Error loading iphlpapi.dll", "Could not find GetNetworkParams function", "DNS query cancelled" }; if(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext))) return errtext[code]; else return "unknown"; } node-v4.2.6/deps/cares/src/ares_timeout.c000644 000766 000024 00000005270 12650222322 020431 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_LIMITS_H #include #endif #include "ares.h" #include "ares_private.h" /* return time offset between now and (future) check, in milliseconds */ static long timeoffset(struct timeval *now, struct timeval *check) { return (check->tv_sec - now->tv_sec)*1000 + (check->tv_usec - now->tv_usec)/1000; } /* WARNING: Beware that this is linear in the number of outstanding * requests! You are probably far better off just calling ares_process() * once per second, rather than calling ares_timeout() to figure out * when to next call ares_process(). */ struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, struct timeval *tvbuf) { struct query *query; struct list_node* list_head; struct list_node* list_node; struct timeval now; struct timeval nextstop; long offset, min_offset; /* No queries, no timeout (and no fetch of the current time). */ if (ares__is_list_empty(&(channel->all_queries))) return maxtv; /* Find the minimum timeout for the current set of queries. */ now = ares__tvnow(); min_offset = -1; list_head = &(channel->all_queries); for (list_node = list_head->next; list_node != list_head; list_node = list_node->next) { query = list_node->data; if (query->timeout.tv_sec == 0) continue; offset = timeoffset(&now, &query->timeout); if (offset < 0) offset = 0; if (min_offset == -1 || offset < min_offset) min_offset = offset; } /* If we found a minimum timeout and it's sooner than the one specified in * maxtv (if any), return it. Otherwise go with maxtv. */ if (min_offset != -1) { int ioffset = (min_offset > (long)INT_MAX) ? INT_MAX : (int)min_offset; nextstop.tv_sec = ioffset/1000; nextstop.tv_usec = (ioffset%1000)*1000; if (!maxtv || ares__timedout(maxtv, &nextstop)) { *tvbuf = nextstop; return tvbuf; } } return maxtv; } node-v4.2.6/deps/cares/src/ares_version.c000644 000766 000024 00000000236 12650222322 020425 0ustar00iojsstaff000000 000000 #include "ares_setup.h" #include "ares.h" const char *ares_version(int *version) { if(version) *version = ARES_VERSION; return ARES_VERSION_STR; } node-v4.2.6/deps/cares/src/ares_writev.c000644 000766 000024 00000003363 12650222322 020264 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #ifdef HAVE_LIMITS_H # include #endif #include "ares.h" #include "ares_private.h" #ifndef HAVE_WRITEV ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) { char *buffer, *bp; int i; size_t bytes = 0; ssize_t result; /* Validate iovcnt */ if (iovcnt <= 0) { SET_ERRNO(EINVAL); return (-1); } /* Validate and find the sum of the iov_len values in the iov array */ for (i = 0; i < iovcnt; i++) { if (iov[i].iov_len > INT_MAX - bytes) { SET_ERRNO(EINVAL); return (-1); } bytes += iov[i].iov_len; } if (bytes == 0) return (0); /* Allocate a temporary buffer to hold the data */ buffer = malloc(bytes); if (!buffer) { SET_ERRNO(ENOMEM); return (-1); } /* Copy the data into buffer */ for (bp = buffer, i = 0; i < iovcnt; ++i) { memcpy (bp, iov[i].iov_base, iov[i].iov_len); bp += iov[i].iov_len; } /* Send buffer contents */ result = swrite(s, buffer, bytes); free(buffer); return (result); } #endif node-v4.2.6/deps/cares/src/ares_writev.h000644 000766 000024 00000002114 12650222322 020262 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_WRITEV_H #define HEADER_CARES_WRITEV_H /* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #include "ares_setup.h" #include "ares.h" #ifndef HAVE_WRITEV /* Structure for scatter/gather I/O. */ struct iovec { void *iov_base; /* Pointer to data. */ size_t iov_len; /* Length of data. */ }; extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt); #endif #endif /* HEADER_CARES_WRITEV_H */ node-v4.2.6/deps/cares/src/AUTHORS000644 000766 000024 00000001566 12650222322 016641 0ustar00iojsstaff000000 000000 c-ares is based on ares, and these are the people that have worked on it since the fork was made: Albert Chin Alexander Lazic Alexey Simak Andreas Rieke Andrew C. Morrow Ashish Sharma Ben Greear Ben Noordhuis BogDan Vatra Brad House Brad Spencer Bram Matthys Dan Fandrich Daniel Johnson Daniel Stenberg David Stuart Denis Bilenko Dima Tisnek Dirk Manske Dominick Meglio Doug Goldstein Duncan Wilcox Eino Tuominen Erik Kline George Neill Gisle Vanem Guenter Knauf Guilherme Balena Versiani Gunter Knauf Henrik Stoerner Jakub Hrozek James Bursa Jérémy Lal Marko Kreen Michael Wallner Mike Crowe Nick Alcock Nick Mathewson Patrik Thunstrom Peter Pentchev Phil Blundell Poul Thomas Lomholt Ravi Pratap Robin Cornelius Sebastian at basti79.de Shmulik Regev Stefan Bühler Steinar H. Gunderson Tofu Linden Tom Hughes Tor Arntsen Vlad Dinulescu William Ahern Yang Tse liren at vivisimo.com node-v4.2.6/deps/cares/src/bitncmp.c000644 000766 000024 00000003137 12650222322 017365 0ustar00iojsstaff000000 000000 /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef HAVE_BITNCMP #include "ares_setup.h" #include "bitncmp.h" /* * int * bitncmp(l, r, n) * compare bit masks l and r, for n bits. * return: * -1, 1, or 0 in the libc tradition. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0x11110000 in its fourth octet. * author: * Paul Vixie (ISC), June 1996 */ int ares__bitncmp(const void *l, const void *r, int n) { unsigned int lb, rb; int x, b; b = n / 8; x = memcmp(l, r, b); if (x || (n % 8) == 0) return (x); lb = ((const unsigned char *)l)[b]; rb = ((const unsigned char *)r)[b]; for (b = n % 8; b > 0; b--) { if ((lb & 0x80) != (rb & 0x80)) { if (lb & 0x80) return (1); return (-1); } lb <<= 1; rb <<= 1; } return (0); } #endif node-v4.2.6/deps/cares/src/bitncmp.h000644 000766 000024 00000001611 12650222322 017365 0ustar00iojsstaff000000 000000 #ifndef __ARES_BITNCMP_H #define __ARES_BITNCMP_H /* Copyright (C) 2005, 2013 by Dominick Meglio * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #ifndef HAVE_BITNCMP int ares__bitncmp(const void *l, const void *r, int n); #else #define ares__bitncmp(x,y,z) bitncmp(x,y,z) #endif #endif /* __ARES_BITNCMP_H */ node-v4.2.6/deps/cares/src/config-win32.h000644 000766 000024 00000027522 12650222322 020147 0ustar00iojsstaff000000 000000 #ifndef HEADER_CARES_CONFIG_WIN32_H #define HEADER_CARES_CONFIG_WIN32_H /* Copyright (C) 2004 - 2011 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ /* ================================================================ */ /* c-ares/config-win32.h - Hand crafted config file for Windows */ /* ================================================================ */ /* ---------------------------------------------------------------- */ /* HEADER FILES */ /* ---------------------------------------------------------------- */ /* Define if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define if you have the header file. */ #if defined(__MINGW32__) || defined(__POCC__) #define HAVE_GETOPT_H 1 #endif /* Define if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the header file. */ #ifndef __SALFORDC__ #define HAVE_PROCESS_H 1 #endif /* Define if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define if you have the header file */ /* #define HAVE_SYS_TIME_H 1 */ /* Define if you have the header file. */ #define HAVE_TIME_H 1 /* Define if you have the header file. */ #if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ defined(__POCC__) #define HAVE_UNISTD_H 1 #endif /* Define if you have the header file. */ #define HAVE_WINDOWS_H 1 /* Define if you have the header file. */ #define HAVE_WINSOCK_H 1 /* Define if you have the header file. */ #ifndef __SALFORDC__ #define HAVE_WINSOCK2_H 1 #endif /* Define if you have the header file. */ #ifndef __SALFORDC__ #define HAVE_WS2TCPIP_H 1 #endif /* ---------------------------------------------------------------- */ /* OTHER HEADER INFO */ /* ---------------------------------------------------------------- */ /* Define if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you can safely include both and . */ /* #define TIME_WITH_SYS_TIME 1 */ /* ---------------------------------------------------------------- */ /* FUNCTIONS */ /* ---------------------------------------------------------------- */ /* Define if you have the closesocket function. */ #define HAVE_CLOSESOCKET 1 /* Define if you have the getenv function. */ #define HAVE_GETENV 1 /* Define if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define if you have the ioctlsocket function. */ #define HAVE_IOCTLSOCKET 1 /* Define if you have a working ioctlsocket FIONBIO function. */ #define HAVE_IOCTLSOCKET_FIONBIO 1 /* Define if you have the strcasecmp function. */ /* #define HAVE_STRCASECMP 1 */ /* Define if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define if you have the stricmp function. */ #define HAVE_STRICMP 1 /* Define if you have the strncasecmp function. */ /* #define HAVE_STRNCASECMP 1 */ /* Define if you have the strnicmp function. */ #define HAVE_STRNICMP 1 /* Define if you have the recv function. */ #define HAVE_RECV 1 /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 SOCKET /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 char * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 int /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 SOCKET /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 char /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 int /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 int /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define if you have the send function. */ #define HAVE_SEND 1 /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 SOCKET /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 char * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 int /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* Specifics for the Watt-32 tcp/ip stack. */ #ifdef WATT32 #define SOCKET int #define NS_INADDRSZ 4 #define HAVE_ARPA_NAMESER_H 1 #define HAVE_ARPA_INET_H 1 #define HAVE_NETDB_H 1 #define HAVE_NETINET_IN_H 1 #define HAVE_SYS_SOCKET_H 1 #define HAVE_NETINET_TCP_H 1 #define HAVE_AF_INET6 1 #define HAVE_PF_INET6 1 #define HAVE_STRUCT_IN6_ADDR 1 #define HAVE_STRUCT_SOCKADDR_IN6 1 #undef HAVE_WINSOCK_H #undef HAVE_WINSOCK2_H #undef HAVE_WS2TCPIP_H #endif /* ---------------------------------------------------------------- */ /* TYPEDEF REPLACEMENTS */ /* ---------------------------------------------------------------- */ /* Define if in_addr_t is not an available 'typedefed' type. */ #define in_addr_t unsigned long /* Define to the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define if ssize_t is not an available 'typedefed' type. */ #ifndef _SSIZE_T_DEFINED # if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ defined(__POCC__) || \ defined(__MINGW32__) # elif defined(_WIN64) # define _SSIZE_T_DEFINED # define ssize_t __int64 # else # define _SSIZE_T_DEFINED # define ssize_t int # endif #endif /* ---------------------------------------------------------------- */ /* TYPE SIZES */ /* ---------------------------------------------------------------- */ /* Define to the size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* Define to the size of `short', as computed by sizeof. */ #define SIZEOF_SHORT 2 /* Define to the size of `size_t', as computed by sizeof. */ #if defined(_WIN64) # define SIZEOF_SIZE_T 8 #else # define SIZEOF_SIZE_T 4 #endif /* ---------------------------------------------------------------- */ /* STRUCT RELATED */ /* ---------------------------------------------------------------- */ /* Define if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define if you have struct sockaddr_storage. */ #if !defined(__SALFORDC__) && !defined(__BORLANDC__) #define HAVE_STRUCT_SOCKADDR_STORAGE 1 #endif /* Define if you have struct timeval. */ #define HAVE_STRUCT_TIMEVAL 1 /* ---------------------------------------------------------------- */ /* COMPILER SPECIFIC */ /* ---------------------------------------------------------------- */ /* Define to avoid VS2005 complaining about portable C functions. */ #if defined(_MSC_VER) && (_MSC_VER >= 1400) # define _CRT_SECURE_NO_DEPRECATE 1 # define _CRT_NONSTDC_NO_DEPRECATE 1 #endif /* Officially, Microsoft's Windows SDK versions 6.X do not support Windows 2000 as a supported build target. VS2008 default installations provide an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a valid build target for VS2008. Popular belief is that binaries built with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build target are functional. */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) # define VS2008_MIN_TARGET 0x0500 #endif /* When no build target is specified VS2008 default build target is Windows Vista, which leaves out even Winsows XP. If no build target has been given for VS2008 we will target the minimum Officially supported build target, which happens to be Windows XP. */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) # define VS2008_DEF_TARGET 0x0501 #endif /* VS2008 default target settings and minimum build target check. */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) # ifndef _WIN32_WINNT # define _WIN32_WINNT VS2008_DEF_TARGET # endif # ifndef WINVER # define WINVER VS2008_DEF_TARGET # endif # if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET) # error VS2008 does not support Windows build targets prior to Windows 2000 # endif #endif /* When no build target is specified Pelles C 5.00 and later default build target is Windows Vista. We override default target to be Windows 2000. */ #if defined(__POCC__) && (__POCC__ >= 500) # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0500 # endif # ifndef WINVER # define WINVER 0x0500 # endif #endif /* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is quite convoluted, compiler dependent and even build target dependent. */ #if defined(HAVE_WS2TCPIP_H) # if defined(__POCC__) # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETNAMEINFO 1 # elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETNAMEINFO 1 # elif defined(_MSC_VER) && (_MSC_VER >= 1200) # define HAVE_FREEADDRINFO 1 # define HAVE_GETADDRINFO 1 # define HAVE_GETNAMEINFO 1 # endif #endif #if defined(__POCC__) # ifndef _MSC_VER # error Microsoft extensions /Ze compiler option is required # endif # ifndef __POCC__OLDNAMES # error Compatibility names /Go compiler option is required # endif #endif /* ---------------------------------------------------------------- */ /* IPV6 COMPATIBILITY */ /* ---------------------------------------------------------------- */ /* Define if you have address family AF_INET6. */ #ifdef HAVE_WINSOCK2_H #define HAVE_AF_INET6 1 #endif /* Define if you have protocol family PF_INET6. */ #ifdef HAVE_WINSOCK2_H #define HAVE_PF_INET6 1 #endif /* Define if you have struct in6_addr. */ #ifdef HAVE_WS2TCPIP_H #define HAVE_STRUCT_IN6_ADDR 1 #endif /* Define if you have struct sockaddr_in6. */ #ifdef HAVE_WS2TCPIP_H #define HAVE_STRUCT_SOCKADDR_IN6 1 #endif /* Define if you have sockaddr_in6 with scopeid. */ #ifdef HAVE_WS2TCPIP_H #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 #endif /* ---------------------------------------------------------------- */ /* Win CE */ /* ---------------------------------------------------------------- */ /* FIXME: A proper config-win32ce.h should be created to hold these */ /* * System error codes for Windows CE */ #if defined(_WIN32_WCE) && !defined(HAVE_ERRNO_H) # define ENOENT ERROR_FILE_NOT_FOUND # define ESRCH ERROR_PATH_NOT_FOUND # define ENOMEM ERROR_NOT_ENOUGH_MEMORY # define ENOSPC ERROR_INVALID_PARAMETER #endif #endif /* HEADER_CARES_CONFIG_WIN32_H */ node-v4.2.6/deps/cares/src/inet_net_pton.c000644 000766 000024 00000026201 12650222322 020573 0ustar00iojsstaff000000 000000 /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_ipv6.h" #include "ares_nowarn.h" #include "ares_inet_net_pton.h" const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; #ifndef HAVE_INET_NET_PTON /* * static int * inet_net_pton_ipv4(src, dst, size) * convert IPv4 network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not an IPv4 network specification. * note: * network byte order assumed. this means 192.5.5.240/28 has * 0b11110000 in its fourth octet. * note: * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the * errno this funtion sets when returning (-1), not SOCKERRNO. * author: * Paul Vixie (ISC), June 1996 */ static int inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) { static const char xdigits[] = "0123456789abcdef"; static const char digits[] = "0123456789"; int n, ch, tmp = 0, dirty, bits; const unsigned char *odst = dst; ch = *src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') && ISASCII(src[1]) && ISXDIGIT(src[1])) { /* Hexadecimal: Eat nybble string. */ if (!size) goto emsgsize; dirty = 0; src++; /* skip x or X. */ while ((ch = *src++) != '\0' && ISASCII(ch) && ISXDIGIT(ch)) { if (ISUPPER(ch)) ch = tolower(ch); n = aresx_sztosi(strchr(xdigits, ch) - xdigits); if (dirty == 0) tmp = n; else tmp = (tmp << 4) | n; if (++dirty == 2) { if (!size--) goto emsgsize; *dst++ = (unsigned char) tmp; dirty = 0; } } if (dirty) { /* Odd trailing nybble? */ if (!size--) goto emsgsize; *dst++ = (unsigned char) (tmp << 4); } } else if (ISASCII(ch) && ISDIGIT(ch)) { /* Decimal: eat dotted digit string. */ for (;;) { tmp = 0; do { n = aresx_sztosi(strchr(digits, ch) - digits); tmp *= 10; tmp += n; if (tmp > 255) goto enoent; } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch)); if (!size--) goto emsgsize; *dst++ = (unsigned char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; ch = *src++; if (!ISASCII(ch) || !ISDIGIT(ch)) goto enoent; } } else goto enoent; bits = -1; if (ch == '/' && ISASCII(src[0]) && ISDIGIT(src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ ch = *src++; /* Skip over the /. */ bits = 0; do { n = aresx_sztosi(strchr(digits, ch) - digits); bits *= 10; bits += n; if (bits > 32) goto enoent; } while ((ch = *src++) != '\0' && ISASCII(ch) && ISDIGIT(ch)); if (ch != '\0') goto enoent; } /* Firey death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; /* If nothing was written to the destination, we found no address. */ if (dst == odst) goto enoent; /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { if (*odst >= 240) /* Class E */ bits = 32; else if (*odst >= 224) /* Class D */ bits = 8; else if (*odst >= 192) /* Class C */ bits = 24; else if (*odst >= 128) /* Class B */ bits = 16; else /* Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ if (bits < ((dst - odst) * 8)) bits = aresx_sztosi(dst - odst) * 8; /* * If there are no additional bits specified for a class D * address adjust bits to 4. */ if (bits == 8 && *odst == 224) bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { if (!size--) goto emsgsize; *dst++ = '\0'; } return (bits); enoent: SET_ERRNO(ENOENT); return (-1); emsgsize: SET_ERRNO(EMSGSIZE); return (-1); } static int getbits(const char *src, int *bitsp) { static const char digits[] = "0123456789"; int n; int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /* no leading zeros */ return (0); val *= 10; val += aresx_sztosi(pch - digits); if (val > 128) /* range */ return (0); continue; } return (0); } if (n == 0) return (0); *bitsp = val; return (1); } static int getv4(const char *src, unsigned char *dst, int *bitsp) { static const char digits[] = "0123456789"; unsigned char *odst = dst; int n; unsigned int val; char ch; val = 0; n = 0; while ((ch = *src++) != '\0') { const char *pch; pch = strchr(digits, ch); if (pch != NULL) { if (n++ != 0 && val == 0) /* no leading zeros */ return (0); val *= 10; val += aresx_sztoui(pch - digits); if (val > 255) /* range */ return (0); continue; } if (ch == '.' || ch == '/') { if (dst - odst > 3) /* too many octets? */ return (0); *dst++ = (unsigned char)val; if (ch == '/') return (getbits(src, bitsp)); val = 0; n = 0; continue; } return (0); } if (n == 0) return (0); if (dst - odst > 3) /* too many octets? */ return (0); *dst = (unsigned char)val; return 1; } static int inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) { static const char xdigits_l[] = "0123456789abcdef", xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; const char *xdigits, *curtok; int ch, saw_xdigit; unsigned int val; int digits; int bits; size_t bytes; int words; int ipv4; memset((tp = tmp), '\0', NS_IN6ADDRSZ); endp = tp + NS_IN6ADDRSZ; colonp = NULL; /* Leading :: requires some special handling. */ if (*src == ':') if (*++src != ':') goto enoent; curtok = src; saw_xdigit = 0; val = 0; digits = 0; bits = -1; ipv4 = 0; while ((ch = *src++) != '\0') { const char *pch; if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) pch = strchr((xdigits = xdigits_u), ch); if (pch != NULL) { val <<= 4; val |= aresx_sztoui(pch - xdigits); if (++digits > 4) goto enoent; saw_xdigit = 1; continue; } if (ch == ':') { curtok = src; if (!saw_xdigit) { if (colonp) goto enoent; colonp = tp; continue; } else if (*src == '\0') goto enoent; if (tp + NS_INT16SZ > endp) return (0); *tp++ = (unsigned char)((val >> 8) & 0xff); *tp++ = (unsigned char)(val & 0xff); saw_xdigit = 0; digits = 0; val = 0; continue; } if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && getv4(curtok, tp, &bits) > 0) { tp += NS_INADDRSZ; saw_xdigit = 0; ipv4 = 1; break; /* '\0' was seen by inet_pton4(). */ } if (ch == '/' && getbits(src, &bits) > 0) break; goto enoent; } if (saw_xdigit) { if (tp + NS_INT16SZ > endp) goto enoent; *tp++ = (unsigned char)((val >> 8) & 0xff); *tp++ = (unsigned char)(val & 0xff); } if (bits == -1) bits = 128; words = (bits + 15) / 16; if (words < 2) words = 2; if (ipv4) words = 8; endp = tmp + 2 * words; if (colonp != NULL) { /* * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ const ssize_t n = tp - colonp; ssize_t i; if (tp == endp) goto enoent; for (i = 1; i <= n; i++) { *(endp - i) = *(colonp + n - i); *(colonp + n - i) = 0; } tp = endp; } if (tp != endp) goto enoent; bytes = (bits + 7) / 8; if (bytes > size) goto emsgsize; memcpy(dst, tmp, bytes); return (bits); enoent: SET_ERRNO(ENOENT); return (-1); emsgsize: SET_ERRNO(EMSGSIZE); return (-1); } /* * int * inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". * return: * number of bits, either imputed classfully or specified with /CIDR, * or -1 if some failure occurred (check errno). ENOENT means it was * not a valid network specification. * note: * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the * errno this funtion sets when returning (-1), not SOCKERRNO. * author: * Paul Vixie (ISC), June 1996 */ int ares_inet_net_pton(int af, const char *src, void *dst, size_t size) { switch (af) { case AF_INET: return (inet_net_pton_ipv4(src, dst, size)); case AF_INET6: return (inet_net_pton_ipv6(src, dst, size)); default: SET_ERRNO(EAFNOSUPPORT); return (-1); } } #endif /* HAVE_INET_NET_PTON */ #ifndef HAVE_INET_PTON int ares_inet_pton(int af, const char *src, void *dst) { int result; size_t size; if (af == AF_INET) size = sizeof(struct in_addr); else if (af == AF_INET6) size = sizeof(struct ares_in6_addr); else { SET_ERRNO(EAFNOSUPPORT); return -1; } result = ares_inet_net_pton(af, src, dst, size); if (result == -1 && ERRNO == ENOENT) return 0; return (result > -1 ? 1 : -1); } #else /* HAVE_INET_PTON */ int ares_inet_pton(int af, const char *src, void *dst) { /* just relay this to the underlying function */ return inet_pton(af, src, dst); } #endif node-v4.2.6/deps/cares/src/inet_ntop.c000644 000766 000024 00000013404 12650222322 017726 0ustar00iojsstaff000000 000000 /* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "ares_setup.h" #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H # include #endif #ifdef HAVE_ARPA_NAMESER_H # include #else # include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif #include "ares.h" #include "ares_ipv6.h" #ifndef HAVE_INET_NTOP /* * WARNING: Don't even consider trying to compile this on a system where * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. */ static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size); static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); /* char * * inet_ntop(af, src, dst, size) * convert a network format address to presentation format. * return: * pointer to presentation format address (`dst'), or NULL (see errno). * note: * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the * errno this funtion sets when returning NULL, not SOCKERRNO. * author: * Paul Vixie, 1996. */ const char * ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size) { switch (af) { case AF_INET: return (inet_ntop4(src, dst, (size_t)size)); case AF_INET6: return (inet_ntop6(src, dst, (size_t)size)); default: SET_ERRNO(EAFNOSUPPORT); return (NULL); } /* NOTREACHED */ } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a unsigned char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char * inet_ntop4(const unsigned char *src, char *dst, size_t size) { static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof("255.255.255.255")]; if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size) { SET_ERRNO(ENOSPC); return (NULL); } strcpy(dst, tmp); return (dst); } /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char * inet_ntop6(const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; char *tp; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ memset(words, '\0', sizeof(words)); for (i = 0; i < NS_IN6ADDRSZ; i++) words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); best.base = -1; best.len = 0; cur.base = -1; cur.len = 0; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { if (words[i] == 0) { if (cur.base == -1) cur.base = i, cur.len = 1; else cur.len++; } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; cur.base = -1; } } } if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) best = cur; } if (best.base != -1 && best.len < 2) best.base = -1; /* * Format the result. */ tp = tmp; for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { /* Are we inside the best run of 0x00's? */ if (best.base != -1 && i >= best.base && i < (best.base + best.len)) { if (i == best.base) *tp++ = ':'; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) *tp++ = ':'; /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 7 && words[7] != 0x0001) || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) return (NULL); tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { SET_ERRNO(ENOSPC); return (NULL); } strcpy(dst, tmp); return (dst); } #else /* HAVE_INET_NTOP */ const char * ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size) { /* just relay this to the underlying function */ return inet_ntop(af, src, dst, size); } #endif /* HAVE_INET_NTOP */ node-v4.2.6/deps/cares/src/NEWS000644 000766 000024 00000001526 12650222322 016264 0ustar00iojsstaff000000 000000 Major changes since: * see the CHANGES file Major changes in release 1.1.1: * ares should now compile as C++ code (no longer uses reserved word "class"). * Added SRV support to adig test program. * Fixed a few error handling bugs in query processing. Major changes in release 1.1.0: * Added ares_free_string() function so that memory can be freed in the same layer as it is allocated, a desirable feature in some environments. * A few of the ares_dns.h macros are fixed to use the proper bitwise operator. * Fixed a couple of fenceposts fixed in ares_expand_name()'s bounds-checking. * In process_timeouts(), extract query->next before calling next_server() and possibly freeing the query structure. * Casted arguments to ctype macros casted to unsigned char, since not all char values are valid inputs to those macros according to ANSI. node-v4.2.6/deps/cares/src/README000644 000766 000024 00000005003 12650222322 016437 0ustar00iojsstaff000000 000000 c-ares ====== This is c-ares, an asynchronous resolver library. It is intended for applications which need to perform DNS queries without blocking, or need to perform multiple DNS queries in parallel. The primary examples of such applications are servers which communicate with multiple clients and programs with graphical user interfaces. The full source code is available in the 'c-ares' release archives, and in a git repository: http://github.com/bagder/c-ares If you find bugs, correct flaws, have questions or have comments in general in regard to c-ares (or by all means the original ares too), get in touch with us on the c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares c-ares is of course distributed under the same MIT-style license as the original ares. You'll find all c-ares details and news here: http://c-ares.haxx.se/ NOTES FOR C-ARES HACKERS * The distributed ares_build.h file is only intended to be used on systems which can not run the also distributed configure script. * The distributed ares_build.h file is generated as a copy of ares_build.h.dist when the c-ares source code distribution archive file is originally created. * If you check out from git on a non-configure platform, you must run the appropriate buildconf* script to set up ares_build.h and other local files before being able of compiling the library. * On systems capable of running the configure script, the configure process will overwrite the distributed ares_build.h file with one that is suitable and specific to the library being configured and built, this new file is generated from the ares_build.h.in template file. * If you intend to distribute an already compiled c-ares library you _MUST_ also distribute along with it the generated ares_build.h which has been used to compile it. Otherwise the library will be of no use for the users of the library that you have built. It is _your_ responsibility to provide this file. No one at the c-ares project can know how you have built the library. * File ares_build.h includes platform and configuration dependent info, and must not be modified by anyone. Configure script generates it for you. * We cannot assume anything else but very basic compiler features being present. While c-ares requires an ANSI C compiler to build, some of the earlier ANSI compilers clearly can't deal with some preprocessor operators. * Newlines must remain unix-style for older compilers' sake. * Comments must be written in the old-style /* unnested C-fashion */ node-v4.2.6/deps/cares/src/README.cares000644 000766 000024 00000001027 12650222322 017535 0ustar00iojsstaff000000 000000 c-ares ====== This package is based on ares 1.1.1 (written by Greg Hudson). I decided to fork and release a separate project since the ares author didn't want the improvements that were vital for our use of it. This package is dubbed 'c-ares' since I (Daniel Stenberg) wanted this for use within the curl project (hence the letter C) and it makes a nice pun. Also, c-ares is not API compatible with ares: a new name makes that more obvious to the public. The original libares was distributed at athena-dist.mit.edu:pub/ATHENA/ares. node-v4.2.6/deps/cares/src/README.msvc000644 000766 000024 00000012526 12650222322 017416 0ustar00iojsstaff000000 000000 ___ __ _ _ __ ___ ___ / __| ___ / _` | '__/ _ \/ __| | (_ |___| (_| | | | __/\__ \ \___| \__,_|_| \___||___/ How to build c-ares using MSVC or Visual Studio ================================================= How to build using MSVC from the command line --------------------------------------------- Open a command prompt window and ensure that the environment is properly set up in order to use MSVC or Visual Studio compiler tools. Change to c-ares source folder where Makefile.msvc file is located and run: > nmake -f Makefile.msvc This will build all c-ares libraries as well as three sample programs. Once the above command has finished a new folder named MSVCXX will exist below the folder where makefile.msvc is found. The name of the folder depends on the MSVC compiler version being used to build c-ares. Below the MSVCXX folder there will exist four folders named 'cares', 'ahost', 'acountry', and 'adig'. The 'cares' folder is the one that holds the c-ares libraries you have just generated, the other three hold sample programs that use the libraries. The above command builds four versions of the c-ares library, dynamic and static versions and each one in release and debug flavours. Each of these is found in folders named dll-release, dll-debug, lib-release, and lib-debug, which hang from the 'cares' folder mentioned above. Each sample program also has folders with the same names to reflect which library version it is using. How to install using MSVC from the command line ----------------------------------------------- In order to allow easy usage of c-ares libraries it may be convenient to install c-ares libraries and header files to a common subdirectory tree. Once that c-ares libraries have been built using procedure described above, use same command prompt window to define environment variable INSTALL_DIR to designate the top subdirectory where installation of c-ares libraries and header files will be done. > set INSTALL_DIR=c:\c-ares Afterwards, run following command to actually perform the installation: > nmake -f Makefile.msvc install Installation procedure will copy c-ares libraries to subdirectory 'lib' and c-ares header files to subdirectory 'include' below the INSTALL_DIR subdir. When environment variable INSTALL_DIR is not defined, installation is done to c-ares source folder where Makefile.msvc file is located. How to build using Visual Studio 6 IDE -------------------------------------- A VC++ 6.0 reference workspace (vc6aws.dsw) is available within the 'vc' folder to allow proper building of the library and sample programs. 1) Open the vc6aws.dsw workspace with MSVC6's IDE. 2) Select 'Build' from top menu. 3) Select 'Batch Build' from dropdown menu. 4) Make sure that the sixteen project configurations are 'checked'. 5) Click on the 'Build' button. 6) Once the sixteen project configurations are built you are done. Dynamic and static c-ares libraries are built in debug and release flavours, and can be located each one in its own subdirectory, dll-debug, dll-release, lib-debug and lib-release, all of them below the 'vc\cares' subdirectory. In the same way four executable versions of each sample program are built, each using its respective library. The resulting sample executables are located in its own subdirectory, dll-debug, dll-release, lib-debug and lib-release, below the 'vc\acountry', 'vc\adig' and 'vc\ahost'folders. These reference VC++ 6.0 configurations are generated using the dynamic CRT. How to build using Visual Studio 2003 or newer IDE -------------------------------------------------- First you have to convert the VC++ 6.0 reference workspace and project files to the Visual Studio IDE version you are using, following next steps: 1) Open vc\vc6aws.dsw with VS20XX. 2) Allow VS20XX to update all projects and workspaces. 3) Save ALL and close VS20XX. 4) Open vc\vc6aws.sln with VS20XX. 5) Select batch build, check 'all' projects and click 'build' button. Same comments relative to generated files and folders as done above for Visual Studio 6 IDE apply here. Relationship between c-ares library file names and versions ----------------------------------------------------------- c-ares static release library version files: libcares.lib -> static release library c-ares static debug library version files: libcaresd.lib -> static debug library c-ares dynamic release library version files: cares.dll -> dynamic release library cares.lib -> import library for the dynamic release library cares.exp -> export file for the dynamic release library c-ares dynamic debug library version files: caresd.dll -> dynamic debug library caresd.lib -> import library for the dynamic debug library caresd.exp -> export file for the dynamic debug library caresd.pdb -> debug symbol file for the dynamic debug library How to use c-ares static libraries ---------------------------------- When using the c-ares static library in your program, you will have to define preprocessor symbol CARES_STATICLIB while building your program, otherwise you will get errors at linkage stage. Have Fun! node-v4.2.6/deps/cares/src/RELEASE-NOTES000644 000766 000024 00000002447 12650222322 017461 0ustar00iojsstaff000000 000000 c-ares version 1.10.0 Changes: o Added ares_create_query(), to be used instead of ares_mkquery() o ares_inet_ntop() and ares_inet_pton() are now recognized c-ares functions Bug fixes: o include the ares_parse_soa_reply.* files in the tarball o read_udp_packets: bail out loop on bad sockets o get_DNS_AdaptersAddresses: fix IPv6 parsing o adig: perror() doesn't work for socket errors on windows o ares_parse_aaaa_reply: fix memory leak o setup_once.h: HP-UX issue workaround o configure: several fixes o config-dos.h: define strerror() to strerror_s_() for High-C o config-dos.h: define HAVE_CLOSE_S for MSDOS/Watt-32 o ares_build.h.dist: enhance non-configure GCC ABI detection logic o ares.h: stricter CARES_EXTERN linkage decorations logic o ares_cancel(): cancel requests safely o protocol parsing: check input data stricter o library init: be recursive, reference count inits/cleanups o ares_parse_txt_reply: return a ares_txt_reply node for each sub-string o ares_set_servers_csv: fixed IPv6 address parsing o build: fix build on msvc11 Thanks go to these friendly people for their efforts and contributions: Eugeny Gladkih, Yang Tse, Gisle Vanem, Guenter Knauf, Horatiu Popescu, Alexander Klauer, Patrick Valsecchi, Paul Saab, Keith Shaw, Alex Loukissas Have fun! node-v4.2.6/deps/cares/src/setup_once.h000644 000766 000024 00000036007 12650222322 020104 0ustar00iojsstaff000000 000000 #ifndef __SETUP_ONCE_H #define __SETUP_ONCE_H /* Copyright (C) 2004 - 2013 by Daniel Stenberg et al * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. M.I.T. makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. */ /******************************************************************** * NOTICE * * ======== * * * * Content of header files lib/setup_once.h and ares/setup_once.h * * must be kept in sync. Modify the other one if you change this. * * * ********************************************************************/ /* * Inclusion of common header files. */ #include #include #include #include #include #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef NEED_MALLOC_H #include #endif #ifdef NEED_MEMORY_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #ifdef TIME_WITH_SYS_TIME #include #endif #else #ifdef HAVE_TIME_H #include #endif #endif #ifdef WIN32 #include #include #endif #if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T) #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef __hpux # if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) # ifdef _APP32_64BIT_OFF_T # define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T # undef _APP32_64BIT_OFF_T # else # undef OLD_APP32_64BIT_OFF_T # endif # endif #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef __hpux # if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) # ifdef OLD_APP32_64BIT_OFF_T # define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T # undef OLD_APP32_64BIT_OFF_T # endif # endif #endif /* * Definition of timeval struct for platforms that don't have it. */ #ifndef HAVE_STRUCT_TIMEVAL struct timeval { long tv_sec; long tv_usec; }; #endif /* * If we have the MSG_NOSIGNAL define, make sure we use * it as the fourth argument of function send() */ #ifdef HAVE_MSG_NOSIGNAL #define SEND_4TH_ARG MSG_NOSIGNAL #else #define SEND_4TH_ARG 0 #endif #if defined(__minix) /* Minix doesn't support recv on TCP sockets */ #define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ (RECV_TYPE_ARG2)(y), \ (RECV_TYPE_ARG3)(z)) #elif defined(HAVE_RECV) /* * The definitions for the return type and arguments types * of functions recv() and send() belong and come from the * configuration file. Do not define them in any other place. * * HAVE_RECV is defined if you have a function named recv() * which is used to read incoming data from sockets. If your * function has another name then don't define HAVE_RECV. * * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also * be defined. * * HAVE_SEND is defined if you have a function named send() * which is used to write outgoing data on a connected socket. * If yours has another name then don't define HAVE_SEND. * * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2, * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and * SEND_TYPE_RETV must also be defined. */ #if !defined(RECV_TYPE_ARG1) || \ !defined(RECV_TYPE_ARG2) || \ !defined(RECV_TYPE_ARG3) || \ !defined(RECV_TYPE_ARG4) || \ !defined(RECV_TYPE_RETV) /* */ Error Missing_definition_of_return_and_arguments_types_of_recv /* */ #else #define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ (RECV_TYPE_ARG2)(y), \ (RECV_TYPE_ARG3)(z), \ (RECV_TYPE_ARG4)(0)) #endif #else /* HAVE_RECV */ #ifndef sread /* */ Error Missing_definition_of_macro_sread /* */ #endif #endif /* HAVE_RECV */ #if defined(__minix) /* Minix doesn't support send on TCP sockets */ #define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ (SEND_TYPE_ARG2)(y), \ (SEND_TYPE_ARG3)(z)) #elif defined(HAVE_SEND) #if !defined(SEND_TYPE_ARG1) || \ !defined(SEND_QUAL_ARG2) || \ !defined(SEND_TYPE_ARG2) || \ !defined(SEND_TYPE_ARG3) || \ !defined(SEND_TYPE_ARG4) || \ !defined(SEND_TYPE_RETV) /* */ Error Missing_definition_of_return_and_arguments_types_of_send /* */ #else #define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ (SEND_TYPE_ARG2)(y), \ (SEND_TYPE_ARG3)(z), \ (SEND_TYPE_ARG4)(SEND_4TH_ARG)) #endif #else /* HAVE_SEND */ #ifndef swrite /* */ Error Missing_definition_of_macro_swrite /* */ #endif #endif /* HAVE_SEND */ #if 0 #if defined(HAVE_RECVFROM) /* * Currently recvfrom is only used on udp sockets. */ #if !defined(RECVFROM_TYPE_ARG1) || \ !defined(RECVFROM_TYPE_ARG2) || \ !defined(RECVFROM_TYPE_ARG3) || \ !defined(RECVFROM_TYPE_ARG4) || \ !defined(RECVFROM_TYPE_ARG5) || \ !defined(RECVFROM_TYPE_ARG6) || \ !defined(RECVFROM_TYPE_RETV) /* */ Error Missing_definition_of_return_and_arguments_types_of_recvfrom /* */ #else #define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ (RECVFROM_TYPE_ARG2 *)(b), \ (RECVFROM_TYPE_ARG3) (bl), \ (RECVFROM_TYPE_ARG4) (0), \ (RECVFROM_TYPE_ARG5 *)(f), \ (RECVFROM_TYPE_ARG6 *)(fl)) #endif #else /* HAVE_RECVFROM */ #ifndef sreadfrom /* */ Error Missing_definition_of_macro_sreadfrom /* */ #endif #endif /* HAVE_RECVFROM */ #ifdef RECVFROM_TYPE_ARG6_IS_VOID # define RECVFROM_ARG6_T int #else # define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6 #endif #endif /* if 0 */ /* * Function-like macro definition used to close a socket. */ #if defined(HAVE_CLOSESOCKET) # define sclose(x) closesocket((x)) #elif defined(HAVE_CLOSESOCKET_CAMEL) # define sclose(x) CloseSocket((x)) #elif defined(HAVE_CLOSE_S) # define sclose(x) close_s((x)) #else # define sclose(x) close((x)) #endif /* * Uppercase macro versions of ANSI/ISO is*() functions/macros which * avoid negative number inputs with argument byte codes > 127. */ #define ISSPACE(x) (isspace((int) ((unsigned char)x))) #define ISDIGIT(x) (isdigit((int) ((unsigned char)x))) #define ISALNUM(x) (isalnum((int) ((unsigned char)x))) #define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) #define ISGRAPH(x) (isgraph((int) ((unsigned char)x))) #define ISALPHA(x) (isalpha((int) ((unsigned char)x))) #define ISPRINT(x) (isprint((int) ((unsigned char)x))) #define ISUPPER(x) (isupper((int) ((unsigned char)x))) #define ISLOWER(x) (islower((int) ((unsigned char)x))) #define ISASCII(x) (isascii((int) ((unsigned char)x))) #define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ (((unsigned char)x) == '\t')) #define TOLOWER(x) (tolower((int) ((unsigned char)x))) /* * 'bool' stuff compatible with HP-UX headers. */ #if defined(__hpux) && !defined(HAVE_BOOL_T) typedef int bool; # define false 0 # define true 1 # define HAVE_BOOL_T #endif /* * 'bool' exists on platforms with , i.e. C99 platforms. * On non-C99 platforms there's no bool, so define an enum for that. * On C99 platforms 'false' and 'true' also exist. Enum uses a * global namespace though, so use bool_false and bool_true. */ #ifndef HAVE_BOOL_T typedef enum { bool_false = 0, bool_true = 1 } bool; /* * Use a define to let 'true' and 'false' use those enums. There * are currently no use of true and false in libcurl proper, but * there are some in the examples. This will cater for any later * code happening to use true and false. */ # define false bool_false # define true bool_true # define HAVE_BOOL_T #endif /* * Redefine TRUE and FALSE too, to catch current use. With this * change, 'bool found = 1' will give a warning on MIPSPro, but * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro, * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too. */ #ifndef TRUE #define TRUE true #endif #ifndef FALSE #define FALSE false #endif /* * Macro WHILE_FALSE may be used to build single-iteration do-while loops, * avoiding compiler warnings. Mostly intended for other macro definitions. */ #define WHILE_FALSE while(0) #if defined(_MSC_VER) && !defined(__POCC__) # undef WHILE_FALSE # if (_MSC_VER < 1500) # define WHILE_FALSE while(1, 0) # else # define WHILE_FALSE \ __pragma(warning(push)) \ __pragma(warning(disable:4127)) \ while(0) \ __pragma(warning(pop)) # endif #endif /* * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type. */ #ifndef HAVE_SIG_ATOMIC_T typedef int sig_atomic_t; #define HAVE_SIG_ATOMIC_T #endif /* * Convenience SIG_ATOMIC_T definition */ #ifdef HAVE_SIG_ATOMIC_T_VOLATILE #define SIG_ATOMIC_T static sig_atomic_t #else #define SIG_ATOMIC_T static volatile sig_atomic_t #endif /* * Default return type for signal handlers. */ #ifndef RETSIGTYPE #define RETSIGTYPE void #endif /* * Macro used to include code only in debug builds. */ #ifdef DEBUGBUILD #define DEBUGF(x) x #else #define DEBUGF(x) do { } WHILE_FALSE #endif /* * Macro used to include assertion code only in debug builds. */ #if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H) #define DEBUGASSERT(x) assert(x) #else #define DEBUGASSERT(x) do { } WHILE_FALSE #endif /* * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno * (or equivalent) on this platform to hide platform details to code using it. */ #ifdef USE_WINSOCK #define SOCKERRNO ((int)WSAGetLastError()) #define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) #else #define SOCKERRNO (errno) #define SET_SOCKERRNO(x) (errno = (x)) #endif /* * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno * (or equivalent) on this platform to hide platform details to code using it. */ #if defined(WIN32) && !defined(WATT32) #define ERRNO ((int)GetLastError()) #define SET_ERRNO(x) (SetLastError((DWORD)(x))) #else #define ERRNO (errno) #define SET_ERRNO(x) (errno = (x)) #endif /* * Portable error number symbolic names defined to Winsock error codes. */ #ifdef USE_WINSOCK #undef EBADF /* override definition in errno.h */ #define EBADF WSAEBADF #undef EINTR /* override definition in errno.h */ #define EINTR WSAEINTR #undef EINVAL /* override definition in errno.h */ #define EINVAL WSAEINVAL #undef EWOULDBLOCK /* override definition in errno.h */ #define EWOULDBLOCK WSAEWOULDBLOCK #undef EINPROGRESS /* override definition in errno.h */ #define EINPROGRESS WSAEINPROGRESS #undef EALREADY /* override definition in errno.h */ #define EALREADY WSAEALREADY #undef ENOTSOCK /* override definition in errno.h */ #define ENOTSOCK WSAENOTSOCK #undef EDESTADDRREQ /* override definition in errno.h */ #define EDESTADDRREQ WSAEDESTADDRREQ #undef EMSGSIZE /* override definition in errno.h */ #define EMSGSIZE WSAEMSGSIZE #undef EPROTOTYPE /* override definition in errno.h */ #define EPROTOTYPE WSAEPROTOTYPE #undef ENOPROTOOPT /* override definition in errno.h */ #define ENOPROTOOPT WSAENOPROTOOPT #undef EPROTONOSUPPORT /* override definition in errno.h */ #define EPROTONOSUPPORT WSAEPROTONOSUPPORT #define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT #undef EOPNOTSUPP /* override definition in errno.h */ #define EOPNOTSUPP WSAEOPNOTSUPP #define EPFNOSUPPORT WSAEPFNOSUPPORT #undef EAFNOSUPPORT /* override definition in errno.h */ #define EAFNOSUPPORT WSAEAFNOSUPPORT #undef EADDRINUSE /* override definition in errno.h */ #define EADDRINUSE WSAEADDRINUSE #undef EADDRNOTAVAIL /* override definition in errno.h */ #define EADDRNOTAVAIL WSAEADDRNOTAVAIL #undef ENETDOWN /* override definition in errno.h */ #define ENETDOWN WSAENETDOWN #undef ENETUNREACH /* override definition in errno.h */ #define ENETUNREACH WSAENETUNREACH #undef ENETRESET /* override definition in errno.h */ #define ENETRESET WSAENETRESET #undef ECONNABORTED /* override definition in errno.h */ #define ECONNABORTED WSAECONNABORTED #undef ECONNRESET /* override definition in errno.h */ #define ECONNRESET WSAECONNRESET #undef ENOBUFS /* override definition in errno.h */ #define ENOBUFS WSAENOBUFS #undef EISCONN /* override definition in errno.h */ #define EISCONN WSAEISCONN #undef ENOTCONN /* override definition in errno.h */ #define ENOTCONN WSAENOTCONN #define ESHUTDOWN WSAESHUTDOWN #define ETOOMANYREFS WSAETOOMANYREFS #undef ETIMEDOUT /* override definition in errno.h */ #define ETIMEDOUT WSAETIMEDOUT #undef ECONNREFUSED /* override definition in errno.h */ #define ECONNREFUSED WSAECONNREFUSED #undef ELOOP /* override definition in errno.h */ #define ELOOP WSAELOOP #ifndef ENAMETOOLONG /* possible previous definition in errno.h */ #define ENAMETOOLONG WSAENAMETOOLONG #endif #define EHOSTDOWN WSAEHOSTDOWN #undef EHOSTUNREACH /* override definition in errno.h */ #define EHOSTUNREACH WSAEHOSTUNREACH #ifndef ENOTEMPTY /* possible previous definition in errno.h */ #define ENOTEMPTY WSAENOTEMPTY #endif #define EPROCLIM WSAEPROCLIM #define EUSERS WSAEUSERS #define EDQUOT WSAEDQUOT #define ESTALE WSAESTALE #define EREMOTE WSAEREMOTE #endif /* * Actually use __32_getpwuid() on 64-bit VMS builds for getpwuid() */ #if defined(__VMS) && \ defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) #define getpwuid __32_getpwuid #endif /* * Macro argv_item_t hides platform details to code using it. */ #ifdef __VMS #define argv_item_t __char_ptr32 #else #define argv_item_t char * #endif /* * We use this ZERO_NULL to avoid picky compiler warnings, * when assigning a NULL pointer to a function pointer var. */ #define ZERO_NULL 0 #endif /* __SETUP_ONCE_H */ node-v4.2.6/deps/cares/src/TODO000644 000766 000024 00000001327 12650222322 016254 0ustar00iojsstaff000000 000000 TODO ==== ares_reinit() - To allow an app to force a re-read of /etc/resolv.conf etc, pretty much like the res_init() resolver function offers ares_gethostbyname - When built to support IPv6, it needs to also support PF_UNSPEC or similar, so that an application can ask for any protocol and then c-ares would return all known resolves and not just explicitly IPv4 _or_ IPv6 resolves. ares_process - Upon next ABI breakage ares_process() should be changed to return 'int' and return ARES_ENOTINITIALIZED if ares_library_init() has not been called. ares_process_fd - Upon next ABI breakage ares_process_fd() should be changed to return 'int' and return ARES_ENOTINITIALIZED if library has not been initialized. node-v4.2.6/deps/cares/src/windows_port.c000644 000766 000024 00000000623 12650222322 020464 0ustar00iojsstaff000000 000000 #include "ares_setup.h" /* only do the following on windows */ #if (defined(WIN32) || defined(WATT32)) && !defined(MSDOS) #ifdef __WATCOMC__ /* * Watcom needs a DllMain() in order to initialise the clib startup code. */ BOOL WINAPI DllMain (HINSTANCE hnd, DWORD reason, LPVOID reserved) { (void) hnd; (void) reason; (void) reserved; return (TRUE); } #endif #endif /* WIN32 builds only */ node-v4.2.6/deps/cares/include/ares.h000644 000766 000024 00000050022 12650222322 017517 0ustar00iojsstaff000000 000000 /* Copyright 1998 by the Massachusetts Institute of Technology. * Copyright (C) 2007-2013 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose. It is provided "as is" * without express or implied warranty. */ #ifndef ARES__H #define ARES__H #include "ares_version.h" /* c-ares version defines */ /* * Define WIN32 when build target is Win32 API */ #if (defined(_WIN32) || defined(__WIN32__)) && \ !defined(WIN32) && !defined(__SYMBIAN32__) # define WIN32 #endif /* Data type definition of ares_socklen_t. */ typedef unsigned ares_socklen_t; #include /* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish libc5-based Linux systems. Only include it on system that are known to require it! */ #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ defined(ANDROID) || defined(__ANDROID__) #include #endif #if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) #include #endif #if defined(WATT32) # include # include # include #elif defined(_WIN32_WCE) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif # include # include #elif defined(WIN32) # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # endif # include # include # include #else # include # include #endif #ifdef __cplusplus extern "C" { #endif /* ** c-ares external API function linkage decorations. */ #ifdef CARES_STATICLIB # define CARES_EXTERN #elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) # if defined(CARES_BUILDING_LIBRARY) # define CARES_EXTERN __declspec(dllexport) # else # define CARES_EXTERN __declspec(dllimport) # endif #elif defined(CARES_BUILDING_LIBRARY) && defined(CARES_SYMBOL_HIDING) # define CARES_EXTERN CARES_SYMBOL_SCOPE_EXTERN #else # define CARES_EXTERN #endif #define ARES_SUCCESS 0 /* Server error codes (ARES_ENODATA indicates no relevant answer) */ #define ARES_ENODATA 1 #define ARES_EFORMERR 2 #define ARES_ESERVFAIL 3 #define ARES_ENOTFOUND 4 #define ARES_ENOTIMP 5 #define ARES_EREFUSED 6 /* Locally generated error codes */ #define ARES_EBADQUERY 7 #define ARES_EBADNAME 8 #define ARES_EBADFAMILY 9 #define ARES_EBADRESP 10 #define ARES_ECONNREFUSED 11 #define ARES_ETIMEOUT 12 #define ARES_EOF 13 #define ARES_EFILE 14 #define ARES_ENOMEM 15 #define ARES_EDESTRUCTION 16 #define ARES_EBADSTR 17 /* ares_getnameinfo error codes */ #define ARES_EBADFLAGS 18 /* ares_getaddrinfo error codes */ #define ARES_ENONAME 19 #define ARES_EBADHINTS 20 /* Uninitialized library error code */ #define ARES_ENOTINITIALIZED 21 /* introduced in 1.7.0 */ /* ares_library_init error codes */ #define ARES_ELOADIPHLPAPI 22 /* introduced in 1.7.0 */ #define ARES_EADDRGETNETWORKPARAMS 23 /* introduced in 1.7.0 */ /* More error codes */ #define ARES_ECANCELLED 24 /* introduced in 1.7.0 */ /* Flag values */ #define ARES_FLAG_USEVC (1 << 0) #define ARES_FLAG_PRIMARY (1 << 1) #define ARES_FLAG_IGNTC (1 << 2) #define ARES_FLAG_NORECURSE (1 << 3) #define ARES_FLAG_STAYOPEN (1 << 4) #define ARES_FLAG_NOSEARCH (1 << 5) #define ARES_FLAG_NOALIASES (1 << 6) #define ARES_FLAG_NOCHECKRESP (1 << 7) #define ARES_FLAG_EDNS (1 << 8) /* Option mask values */ #define ARES_OPT_FLAGS (1 << 0) #define ARES_OPT_TIMEOUT (1 << 1) #define ARES_OPT_TRIES (1 << 2) #define ARES_OPT_NDOTS (1 << 3) #define ARES_OPT_UDP_PORT (1 << 4) #define ARES_OPT_TCP_PORT (1 << 5) #define ARES_OPT_SERVERS (1 << 6) #define ARES_OPT_DOMAINS (1 << 7) #define ARES_OPT_LOOKUPS (1 << 8) #define ARES_OPT_SOCK_STATE_CB (1 << 9) #define ARES_OPT_SORTLIST (1 << 10) #define ARES_OPT_SOCK_SNDBUF (1 << 11) #define ARES_OPT_SOCK_RCVBUF (1 << 12) #define ARES_OPT_TIMEOUTMS (1 << 13) #define ARES_OPT_ROTATE (1 << 14) #define ARES_OPT_EDNSPSZ (1 << 15) /* Nameinfo flag values */ #define ARES_NI_NOFQDN (1 << 0) #define ARES_NI_NUMERICHOST (1 << 1) #define ARES_NI_NAMEREQD (1 << 2) #define ARES_NI_NUMERICSERV (1 << 3) #define ARES_NI_DGRAM (1 << 4) #define ARES_NI_TCP 0 #define ARES_NI_UDP ARES_NI_DGRAM #define ARES_NI_SCTP (1 << 5) #define ARES_NI_DCCP (1 << 6) #define ARES_NI_NUMERICSCOPE (1 << 7) #define ARES_NI_LOOKUPHOST (1 << 8) #define ARES_NI_LOOKUPSERVICE (1 << 9) /* Reserved for future use */ #define ARES_NI_IDN (1 << 10) #define ARES_NI_IDN_ALLOW_UNASSIGNED (1 << 11) #define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12) /* Addrinfo flag values */ #define ARES_AI_CANONNAME (1 << 0) #define ARES_AI_NUMERICHOST (1 << 1) #define ARES_AI_PASSIVE (1 << 2) #define ARES_AI_NUMERICSERV (1 << 3) #define ARES_AI_V4MAPPED (1 << 4) #define ARES_AI_ALL (1 << 5) #define ARES_AI_ADDRCONFIG (1 << 6) /* Reserved for future use */ #define ARES_AI_IDN (1 << 10) #define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11) #define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12) #define ARES_AI_CANONIDN (1 << 13) #define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \ ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \ ARES_AI_ADDRCONFIG) #define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this many sockets */ #define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num))) #define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \ ARES_GETSOCK_MAXNUM))) /* c-ares library initialization flag values */ #define ARES_LIB_INIT_NONE (0) #define ARES_LIB_INIT_WIN32 (1 << 0) #define ARES_LIB_INIT_ALL (ARES_LIB_INIT_WIN32) /* * Typedef our socket type */ #ifndef ares_socket_typedef #ifdef WIN32 typedef SOCKET ares_socket_t; #define ARES_SOCKET_BAD INVALID_SOCKET #else typedef int ares_socket_t; #define ARES_SOCKET_BAD -1 #endif #define ares_socket_typedef #endif /* ares_socket_typedef */ typedef void (*ares_sock_state_cb)(void *data, ares_socket_t socket_fd, int readable, int writable); struct apattern; /* NOTE about the ares_options struct to users and developers. This struct will remain looking like this. It will not be extended nor shrunk in future releases, but all new options will be set by ares_set_*() options instead of with the ares_init_options() function. Eventually (in a galaxy far far away), all options will be settable by ares_set_*() options and the ares_init_options() function will become deprecated. When new options are added to c-ares, they are not added to this struct. And they are not "saved" with the ares_save_options() function but instead we encourage the use of the ares_dup() function. Needless to say, if you add config options to c-ares you need to make sure ares_dup() duplicates this new option. */ struct ares_options { int flags; int timeout; /* in seconds or milliseconds, depending on options */ int tries; int ndots; unsigned short udp_port; unsigned short tcp_port; int socket_send_buffer_size; int socket_receive_buffer_size; struct in_addr *servers; int nservers; char **domains; int ndomains; char *lookups; ares_sock_state_cb sock_state_cb; void *sock_state_cb_data; struct apattern *sortlist; int nsort; int ednspsz; }; struct hostent; struct timeval; struct sockaddr; struct ares_channeldata; typedef struct ares_channeldata *ares_channel; typedef void (*ares_callback)(void *arg, int status, int timeouts, unsigned char *abuf, int alen); typedef void (*ares_host_callback)(void *arg, int status, int timeouts, struct hostent *hostent); typedef void (*ares_nameinfo_callback)(void *arg, int status, int timeouts, char *node, char *service); typedef int (*ares_sock_create_callback)(ares_socket_t socket_fd, int type, void *data); CARES_EXTERN int ares_library_init(int flags); CARES_EXTERN void ares_library_cleanup(void); CARES_EXTERN const char *ares_version(int *version); CARES_EXTERN int ares_init(ares_channel *channelptr); CARES_EXTERN int ares_init_options(ares_channel *channelptr, struct ares_options *options, int optmask); CARES_EXTERN int ares_save_options(ares_channel channel, struct ares_options *options, int *optmask); CARES_EXTERN void ares_destroy_options(struct ares_options *options); CARES_EXTERN int ares_dup(ares_channel *dest, ares_channel src); CARES_EXTERN void ares_destroy(ares_channel channel); CARES_EXTERN void ares_cancel(ares_channel channel); /* These next 3 configure local binding for the out-going socket * connection. Use these to specify source IP and/or network device * on multi-homed systems. */ CARES_EXTERN void ares_set_local_ip4(ares_channel channel, unsigned int local_ip); /* local_ip6 should be 16 bytes in length */ CARES_EXTERN void ares_set_local_ip6(ares_channel channel, const unsigned char* local_ip6); /* local_dev_name should be null terminated. */ CARES_EXTERN void ares_set_local_dev(ares_channel channel, const char* local_dev_name); CARES_EXTERN void ares_set_socket_callback(ares_channel channel, ares_sock_create_callback callback, void *user_data); CARES_EXTERN void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, ares_callback callback, void *arg); CARES_EXTERN void ares_query(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg); CARES_EXTERN void ares_search(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg); CARES_EXTERN void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg); CARES_EXTERN int ares_gethostbyname_file(ares_channel channel, const char *name, int family, struct hostent **host); CARES_EXTERN void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, int family, ares_host_callback callback, void *arg); CARES_EXTERN void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, ares_socklen_t salen, int flags, ares_nameinfo_callback callback, void *arg); CARES_EXTERN int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds); CARES_EXTERN int ares_getsock(ares_channel channel, ares_socket_t *socks, int numsocks); CARES_EXTERN struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, struct timeval *tv); CARES_EXTERN void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds); CARES_EXTERN void ares_process_fd(ares_channel channel, ares_socket_t read_fd, ares_socket_t write_fd); CARES_EXTERN int ares_create_query(const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen, int max_udp_size); CARES_EXTERN int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen); CARES_EXTERN int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen); CARES_EXTERN int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen); /* * NOTE: before c-ares 1.7.0 we would most often use the system in6_addr * struct below when ares itself was built, but many apps would use this * private version since the header checked a HAVE_* define for it. Starting * with 1.7.0 we always declare and use our own to stop relying on the * system's one. */ struct ares_in6_addr { union { unsigned char _S6_u8[16]; } _S6_un; }; struct ares_addrttl { struct in_addr ipaddr; int ttl; }; struct ares_addr6ttl { struct ares_in6_addr ip6addr; int ttl; }; struct ares_srv_reply { struct ares_srv_reply *next; char *host; unsigned short priority; unsigned short weight; unsigned short port; }; struct ares_mx_reply { struct ares_mx_reply *next; char *host; unsigned short priority; }; struct ares_txt_reply { struct ares_txt_reply *next; unsigned char *txt; size_t length; /* length excludes null termination */ unsigned char record_start; /* 1 - if start of new record * 0 - if a chunk in the same record */ }; struct ares_naptr_reply { struct ares_naptr_reply *next; unsigned char *flags; unsigned char *service; unsigned char *regexp; char *replacement; unsigned short order; unsigned short preference; }; struct ares_soa_reply { char *nsname; char *hostmaster; unsigned int serial; unsigned int refresh; unsigned int retry; unsigned int expire; unsigned int minttl; }; /* ** Parse the buffer, starting at *abuf and of length alen bytes, previously ** obtained from an ares_search call. Put the results in *host, if nonnull. ** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with ** their TTLs in that array, and set *naddrttls to the number of addresses ** so written. */ CARES_EXTERN int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host, struct ares_addrttl *addrttls, int *naddrttls); CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host, struct ares_addr6ttl *addrttls, int *naddrttls); CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host); CARES_EXTERN int ares_parse_ns_reply(const unsigned char *abuf, int alen, struct hostent **host); CARES_EXTERN int ares_parse_srv_reply(const unsigned char* abuf, int alen, struct ares_srv_reply** srv_out); CARES_EXTERN int ares_parse_mx_reply(const unsigned char* abuf, int alen, struct ares_mx_reply** mx_out); CARES_EXTERN int ares_parse_txt_reply(const unsigned char* abuf, int alen, struct ares_txt_reply** txt_out); CARES_EXTERN int ares_parse_naptr_reply(const unsigned char* abuf, int alen, struct ares_naptr_reply** naptr_out); CARES_EXTERN int ares_parse_soa_reply(const unsigned char* abuf, int alen, struct ares_soa_reply** soa_out); CARES_EXTERN void ares_free_string(void *str); CARES_EXTERN void ares_free_hostent(struct hostent *host); CARES_EXTERN void ares_free_data(void *dataptr); CARES_EXTERN const char *ares_strerror(int code); /* TODO: Hold port here as well. */ struct ares_addr_node { struct ares_addr_node *next; int family; union { struct in_addr addr4; struct ares_in6_addr addr6; } addr; }; CARES_EXTERN int ares_set_servers(ares_channel channel, struct ares_addr_node *servers); /* Incomming string format: host[:port][,host[:port]]... */ CARES_EXTERN int ares_set_servers_csv(ares_channel channel, const char* servers); CARES_EXTERN int ares_get_servers(ares_channel channel, struct ares_addr_node **servers); CARES_EXTERN const char *ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size); CARES_EXTERN int ares_inet_pton(int af, const char *src, void *dst); #ifdef __cplusplus } #endif #endif /* ARES__H */ node-v4.2.6/deps/cares/include/ares_version.h000644 000766 000024 00000001214 12650222322 021263 0ustar00iojsstaff000000 000000 #ifndef ARES__VERSION_H #define ARES__VERSION_H /* This is the global package copyright */ #define ARES_COPYRIGHT "2004 - 2013 Daniel Stenberg, ." #define ARES_VERSION_MAJOR 1 #define ARES_VERSION_MINOR 10 #define ARES_VERSION_PATCH 1 #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ (ARES_VERSION_MINOR<<8)|\ (ARES_VERSION_PATCH)) #define ARES_VERSION_STR "1.10.1-DEV" #if (ARES_VERSION >= 0x010700) # define CARES_HAVE_ARES_LIBRARY_INIT 1 # define CARES_HAVE_ARES_LIBRARY_CLEANUP 1 #else # undef CARES_HAVE_ARES_LIBRARY_INIT # undef CARES_HAVE_ARES_LIBRARY_CLEANUP #endif #endif node-v4.2.6/deps/cares/include/nameser.h000644 000766 000024 00000020365 12650222322 020226 0ustar00iojsstaff000000 000000 #ifndef ARES_NAMESER_H #define ARES_NAMESER_H /* header file provided by liren@vivisimo.com */ #ifndef HAVE_ARPA_NAMESER_H #define NS_PACKETSZ 512 /* maximum packet size */ #define NS_MAXDNAME 256 /* maximum domain name */ #define NS_MAXCDNAME 255 /* maximum compressed domain name */ #define NS_MAXLABEL 63 #define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */ #define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */ #define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ #define NS_INT16SZ 2 #define NS_INADDRSZ 4 #define NS_IN6ADDRSZ 16 #define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */ #define NS_DEFAULTPORT 53 /* For both TCP and UDP. */ typedef enum __ns_class { ns_c_invalid = 0, /* Cookie. */ ns_c_in = 1, /* Internet. */ ns_c_2 = 2, /* unallocated/unsupported. */ ns_c_chaos = 3, /* MIT Chaos-net. */ ns_c_hs = 4, /* MIT Hesiod. */ /* Query class values which do not appear in resource records */ ns_c_none = 254, /* for prereq. sections in update requests */ ns_c_any = 255, /* Wildcard match. */ ns_c_max = 65536 } ns_class; typedef enum __ns_type { ns_t_invalid = 0, /* Cookie. */ ns_t_a = 1, /* Host address. */ ns_t_ns = 2, /* Authoritative server. */ ns_t_md = 3, /* Mail destination. */ ns_t_mf = 4, /* Mail forwarder. */ ns_t_cname = 5, /* Canonical name. */ ns_t_soa = 6, /* Start of authority zone. */ ns_t_mb = 7, /* Mailbox domain name. */ ns_t_mg = 8, /* Mail group member. */ ns_t_mr = 9, /* Mail rename name. */ ns_t_null = 10, /* Null resource record. */ ns_t_wks = 11, /* Well known service. */ ns_t_ptr = 12, /* Domain name pointer. */ ns_t_hinfo = 13, /* Host information. */ ns_t_minfo = 14, /* Mailbox information. */ ns_t_mx = 15, /* Mail routing information. */ ns_t_txt = 16, /* Text strings. */ ns_t_rp = 17, /* Responsible person. */ ns_t_afsdb = 18, /* AFS cell database. */ ns_t_x25 = 19, /* X_25 calling address. */ ns_t_isdn = 20, /* ISDN calling address. */ ns_t_rt = 21, /* Router. */ ns_t_nsap = 22, /* NSAP address. */ ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */ ns_t_sig = 24, /* Security signature. */ ns_t_key = 25, /* Security key. */ ns_t_px = 26, /* X.400 mail mapping. */ ns_t_gpos = 27, /* Geographical position (withdrawn). */ ns_t_aaaa = 28, /* Ip6 Address. */ ns_t_loc = 29, /* Location Information. */ ns_t_nxt = 30, /* Next domain (security). */ ns_t_eid = 31, /* Endpoint identifier. */ ns_t_nimloc = 32, /* Nimrod Locator. */ ns_t_srv = 33, /* Server Selection. */ ns_t_atma = 34, /* ATM Address */ ns_t_naptr = 35, /* Naming Authority PoinTeR */ ns_t_kx = 36, /* Key Exchange */ ns_t_cert = 37, /* Certification record */ ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */ ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */ ns_t_sink = 40, /* Kitchen sink (experimentatl) */ ns_t_opt = 41, /* EDNS0 option (meta-RR) */ ns_t_apl = 42, /* Address prefix list (RFC3123) */ ns_t_ds = 43, /* Delegation Signer (RFC4034) */ ns_t_sshfp = 44, /* SSH Key Fingerprint (RFC4255) */ ns_t_rrsig = 46, /* Resource Record Signature (RFC4034) */ ns_t_nsec = 47, /* Next Secure (RFC4034) */ ns_t_dnskey = 48, /* DNS Public Key (RFC4034) */ ns_t_tkey = 249, /* Transaction key */ ns_t_tsig = 250, /* Transaction signature. */ ns_t_ixfr = 251, /* Incremental zone transfer. */ ns_t_axfr = 252, /* Transfer zone of authority. */ ns_t_mailb = 253, /* Transfer mailbox records. */ ns_t_maila = 254, /* Transfer mail agent records. */ ns_t_any = 255, /* Wildcard match. */ ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ ns_t_max = 65536 } ns_type; typedef enum __ns_opcode { ns_o_query = 0, /* Standard query. */ ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */ ns_o_status = 2, /* Name server status query (unsupported). */ /* Opcode 3 is undefined/reserved. */ ns_o_notify = 4, /* Zone change notification. */ ns_o_update = 5, /* Zone update message. */ ns_o_max = 6 } ns_opcode; typedef enum __ns_rcode { ns_r_noerror = 0, /* No error occurred. */ ns_r_formerr = 1, /* Format error. */ ns_r_servfail = 2, /* Server failure. */ ns_r_nxdomain = 3, /* Name error. */ ns_r_notimpl = 4, /* Unimplemented. */ ns_r_refused = 5, /* Operation refused. */ /* these are for BIND_UPDATE */ ns_r_yxdomain = 6, /* Name exists */ ns_r_yxrrset = 7, /* RRset exists */ ns_r_nxrrset = 8, /* RRset does not exist */ ns_r_notauth = 9, /* Not authoritative for zone */ ns_r_notzone = 10, /* Zone of record different from zone section */ ns_r_max = 11, /* The following are TSIG extended errors */ ns_r_badsig = 16, ns_r_badkey = 17, ns_r_badtime = 18 } ns_rcode; #endif /* HAVE_ARPA_NAMESER_H */ #ifndef HAVE_ARPA_NAMESER_COMPAT_H #define PACKETSZ NS_PACKETSZ #define MAXDNAME NS_MAXDNAME #define MAXCDNAME NS_MAXCDNAME #define MAXLABEL NS_MAXLABEL #define HFIXEDSZ NS_HFIXEDSZ #define QFIXEDSZ NS_QFIXEDSZ #define RRFIXEDSZ NS_RRFIXEDSZ #define INDIR_MASK NS_CMPRSFLGS #define NAMESERVER_PORT NS_DEFAULTPORT #define QUERY ns_o_query #define SERVFAIL ns_r_servfail #define NOTIMP ns_r_notimpl #define REFUSED ns_r_refused #undef NOERROR /* it seems this is already defined in winerror.h */ #define NOERROR ns_r_noerror #define FORMERR ns_r_formerr #define NXDOMAIN ns_r_nxdomain #define C_IN ns_c_in #define C_CHAOS ns_c_chaos #define C_HS ns_c_hs #define C_NONE ns_c_none #define C_ANY ns_c_any #define T_A ns_t_a #define T_NS ns_t_ns #define T_MD ns_t_md #define T_MF ns_t_mf #define T_CNAME ns_t_cname #define T_SOA ns_t_soa #define T_MB ns_t_mb #define T_MG ns_t_mg #define T_MR ns_t_mr #define T_NULL ns_t_null #define T_WKS ns_t_wks #define T_PTR ns_t_ptr #define T_HINFO ns_t_hinfo #define T_MINFO ns_t_minfo #define T_MX ns_t_mx #define T_TXT ns_t_txt #define T_RP ns_t_rp #define T_AFSDB ns_t_afsdb #define T_X25 ns_t_x25 #define T_ISDN ns_t_isdn #define T_RT ns_t_rt #define T_NSAP ns_t_nsap #define T_NSAP_PTR ns_t_nsap_ptr #define T_SIG ns_t_sig #define T_KEY ns_t_key #define T_PX ns_t_px #define T_GPOS ns_t_gpos #define T_AAAA ns_t_aaaa #define T_LOC ns_t_loc #define T_NXT ns_t_nxt #define T_EID ns_t_eid #define T_NIMLOC ns_t_nimloc #define T_SRV ns_t_srv #define T_ATMA ns_t_atma #define T_NAPTR ns_t_naptr #define T_KX ns_t_kx #define T_CERT ns_t_cert #define T_A6 ns_t_a6 #define T_DNAME ns_t_dname #define T_SINK ns_t_sink #define T_OPT ns_t_opt #define T_APL ns_t_apl #define T_DS ns_t_ds #define T_SSHFP ns_t_sshfp #define T_RRSIG ns_t_rrsig #define T_NSEC ns_t_nsec #define T_DNSKEY ns_t_dnskey #define T_TKEY ns_t_tkey #define T_TSIG ns_t_tsig #define T_IXFR ns_t_ixfr #define T_AXFR ns_t_axfr #define T_MAILB ns_t_mailb #define T_MAILA ns_t_maila #define T_ANY ns_t_any #endif /* HAVE_ARPA_NAMESER_COMPAT_H */ #endif /* ARES_NAMESER_H */ node-v4.2.6/deps/cares/config/aix/000755 000766 000024 00000000000 12650222322 017020 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/android/000755 000766 000024 00000000000 12650222322 017657 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/cygwin/000755 000766 000024 00000000000 12650222322 017537 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/darwin/000755 000766 000024 00000000000 12650222322 017523 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/freebsd/000755 000766 000024 00000000000 12650222322 017651 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/linux/000755 000766 000024 00000000000 12650222322 017376 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/netbsd/000755 000766 000024 00000000000 12650222322 017516 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/openbsd/000755 000766 000024 00000000000 12650222322 017671 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/sunos/000755 000766 000024 00000000000 12650222322 017406 5ustar00iojsstaff000000 000000 node-v4.2.6/deps/cares/config/sunos/ares_config.h000644 000766 000024 00000034615 12650222322 022047 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ /* #undef CARES_SYMBOL_HIDING */ /* Definition to make a library symbol externally visible. */ /* #undef CARES_SYMBOL_SCOPE_EXTERN */ /* if a /etc/inet dir is being used */ #define ETC_INET 1 /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 5 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE 4096 /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ /* #undef HAVE_IOCTL_FIONBIO */ /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ /* #undef HAVE_IOCTL_SIOCGIFADDR */ /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ /* #undef HAVE_MSG_NOSIGNAL */ /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STROPTS_H 1 /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ #define NEED_REENTRANT 1 /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i386-pc-solaris2.11" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 void /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ #define RECVFROM_TYPE_ARG6_IS_VOID 1 /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/openbsd/ares_config.h000644 000766 000024 00000034670 12650222322 022333 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ /* #undef CARES_SYMBOL_HIDING */ /* Definition to make a library symbol externally visible. */ /* #undef CARES_SYMBOL_SCOPE_EXTERN */ /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 4 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE sizeof(struct servent_data) /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_ARPA_NAMESER_COMPAT_H */ /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ /* #undef HAVE_GETADDRINFO_THREADSAFE */ /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ #define HAVE_INET_NET_PTON 1 /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ /* #undef HAVE_MSG_NOSIGNAL */ /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i386-unknown-openbsd4.7" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/netbsd/ares_config.h000644 000766 000024 00000034670 12650222322 022160 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ /* #undef CARES_SYMBOL_HIDING */ /* Definition to make a library symbol externally visible. */ /* #undef CARES_SYMBOL_SCOPE_EXTERN */ /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 4 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE sizeof(struct servent_data) /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_ARPA_NAMESER_COMPAT_H */ /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ /* #undef HAVE_GETADDRINFO_THREADSAFE */ /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ #define HAVE_INET_NET_PTON 1 /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ /* #undef HAVE_MSG_NOSIGNAL */ /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i386-unknown-openbsd4.7" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/linux/ares_config.h000644 000766 000024 00000034672 12650222322 022042 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 unsigned int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 6 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE 4096 /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #define HAVE_MSG_NOSIGNAL 1 /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STROPTS_H 1 /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i686-pc-linux-gnu" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/freebsd/ares_config.h000644 000766 000024 00000034674 12650222322 022317 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 6 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE 4096 /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ #define HAVE_INET_NET_PTON 1 /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ /* #undef HAVE_MALLOC_H */ /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #define HAVE_MSG_NOSIGNAL 1 /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i386-portbld-freebsd8.0" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/darwin/ares_config.h000644 000766 000024 00000034723 12650222322 022164 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 socklen_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ /* #undef GETSERVBYPORT_R_ARGS */ /* Specifies the size of the buffer to pass to getservbyport_r */ /* #undef GETSERVBYPORT_R_BUFSIZE */ /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ /* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ /* #undef HAVE_GETSERVBYPORT_R */ /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ #define HAVE_INET_NET_PTON 1 /* Define to 1 if inet_net_pton supports IPv6. */ #define HAVE_INET_NET_PTON_IPV6 1 /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ /* #undef HAVE_MALLOC_H */ /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ /* #undef HAVE_MSG_NOSIGNAL */ /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i386-apple-darwin9.8.0" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV ssize_t /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV ssize_t /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV ssize_t /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/cygwin/ares_config.h000644 000766 000024 00000034674 12650222322 022205 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 int /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ /* #undef GETSERVBYPORT_R_ARGS */ /* Specifies the size of the buffer to pass to getservbyport_r */ /* #undef GETSERVBYPORT_R_BUFSIZE */ /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ /* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ /* #undef HAVE_GETADDRINFO_THREADSAFE */ /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ /* #undef HAVE_GETSERVBYPORT_R */ /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #define HAVE_MSG_NOSIGNAL 1 /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ /* #undef HAVE_STROPTS_H */ /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i686-pc-cygwin" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/android/ares_config.h000644 000766 000024 00000034676 12650222322 022327 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ /* #undef ARES_BIG_ENDIAN */ /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 unsigned int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 6 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE 4096 /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ //#define HAVE_ARPA_NAMESER_COMPAT_H 1 /* Define to 1 if you have the header file. */ //#define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ /* #undef HAVE_INET_NET_PTON */ /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #define HAVE_MSG_NOSIGNAL 1 /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STROPTS_H 1 /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ /* #undef NEED_THREAD_SAFE */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "i686-pc-linux-gnu" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV int /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV int /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV int /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE /* # undef _ALL_SOURCE */ #endif /* Number of bits in a file offset, on hosts where this is settable. */ #define _FILE_OFFSET_BITS 64 /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/config/aix/ares_config.h000644 000766 000024 00000035040 12650222322 021452 0ustar00iojsstaff000000 000000 /* ares_config.h. Generated from ares_config.h.in by configure. */ /* ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ /* #undef AC_APPLE_UNIVERSAL_BUILD */ /* define this if ares is built for a big endian system */ #define ARES_BIG_ENDIAN 1 /* when building as static part of libcurl */ /* #undef BUILDING_LIBCURL */ /* when building c-ares library */ /* #undef CARES_BUILDING_LIBRARY */ /* when not building a shared library */ /* #undef CARES_STATICLIB */ /* Define to 1 to enable hiding of library internal symbols. */ #define CARES_SYMBOL_HIDING 1 /* Definition to make a library symbol externally visible. */ #define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default"))) /* if a /etc/inet dir is being used */ /* #undef ETC_INET */ /* Define to the type qualifier of arg 1 for getnameinfo. */ #define GETNAMEINFO_QUAL_ARG1 const /* Define to the type of arg 1 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG1 struct sockaddr * /* Define to the type of arg 2 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG2 socklen_t /* Define to the type of args 4 and 6 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG46 size_t /* Define to the type of arg 7 for getnameinfo. */ #define GETNAMEINFO_TYPE_ARG7 int /* Specifies the number of arguments to getservbyport_r */ #define GETSERVBYPORT_R_ARGS 4 /* Specifies the size of the buffer to pass to getservbyport_r */ #define GETSERVBYPORT_R_BUFSIZE sizeof(struct servent_data) /* Define to 1 if you have AF_INET6. */ #define HAVE_AF_INET6 1 /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_ARPA_NAMESER_COMPAT_H */ /* Define to 1 if you have the header file. */ #define HAVE_ARPA_NAMESER_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ASSERT_H 1 /* Define to 1 if you have the `bitncmp' function. */ /* #undef HAVE_BITNCMP */ /* Define to 1 if bool is an available type. */ #define HAVE_BOOL_T 1 /* Define to 1 if you have the clock_gettime function and monotonic timer. */ #define HAVE_CLOCK_GETTIME_MONOTONIC 1 /* Define to 1 if you have the closesocket function. */ /* #undef HAVE_CLOSESOCKET */ /* Define to 1 if you have the CloseSocket camel case function. */ /* #undef HAVE_CLOSESOCKET_CAMEL */ /* Define to 1 if you have the connect function. */ #define HAVE_CONNECT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define to 1 if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have a working fcntl O_NONBLOCK function. */ #define HAVE_FCNTL_O_NONBLOCK 1 /* Define to 1 if you have the freeaddrinfo function. */ #define HAVE_FREEADDRINFO 1 /* Define to 1 if you have a working getaddrinfo function. */ #define HAVE_GETADDRINFO 1 /* Define to 1 if the getaddrinfo function is threadsafe. */ #define HAVE_GETADDRINFO_THREADSAFE 1 /* Define to 1 if you have the gethostbyaddr function. */ #define HAVE_GETHOSTBYADDR 1 /* Define to 1 if you have the gethostbyname function. */ #define HAVE_GETHOSTBYNAME 1 /* Define to 1 if you have the gethostname function. */ #define HAVE_GETHOSTNAME 1 /* Define to 1 if you have the getnameinfo function. */ #define HAVE_GETNAMEINFO 1 /* Define to 1 if you have the getservbyport_r function. */ #define HAVE_GETSERVBYPORT_R 1 /* Define to 1 if you have the `gettimeofday' function. */ #define HAVE_GETTIMEOFDAY 1 /* Define to 1 if you have the `if_indextoname' function. */ #define HAVE_IF_INDEXTONAME 1 /* Define to 1 if you have the `inet_net_pton' function. */ #define HAVE_INET_NET_PTON 1 /* Define to 1 if inet_net_pton supports IPv6. */ /* #undef HAVE_INET_NET_PTON_IPV6 */ /* Define to 1 if you have a IPv6 capable working inet_ntop function. */ #define HAVE_INET_NTOP 1 /* Define to 1 if you have a IPv6 capable working inet_pton function. */ #define HAVE_INET_PTON 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the ioctl function. */ #define HAVE_IOCTL 1 /* Define to 1 if you have the ioctlsocket function. */ /* #undef HAVE_IOCTLSOCKET */ /* Define to 1 if you have the IoctlSocket camel case function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL */ /* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ /* Define to 1 if you have a working ioctlsocket FIONBIO function. */ /* #undef HAVE_IOCTLSOCKET_FIONBIO */ /* Define to 1 if you have a working ioctl FIONBIO function. */ #define HAVE_IOCTL_FIONBIO 1 /* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ #define HAVE_IOCTL_SIOCGIFADDR 1 /* Define to 1 if you have the `resolve' library (-lresolve). */ /* #undef HAVE_LIBRESOLVE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* if your compiler supports LL */ #define HAVE_LL 1 /* Define to 1 if the compiler supports the 'long long' data type. */ #define HAVE_LONGLONG 1 /* Define to 1 if you have the malloc.h header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the memory.h header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the MSG_NOSIGNAL flag. */ #define HAVE_MSG_NOSIGNAL 1 /* Define to 1 if you have the header file. */ #define HAVE_NETDB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_IN_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NETINET_TCP_H 1 /* Define to 1 if you have the header file. */ #define HAVE_NET_IF_H 1 /* Define to 1 if you have PF_INET6. */ #define HAVE_PF_INET6 1 /* Define to 1 if you have the recv function. */ #define HAVE_RECV 1 /* Define to 1 if you have the recvfrom function. */ #define HAVE_RECVFROM 1 /* Define to 1 if you have the send function. */ #define HAVE_SEND 1 /* Define to 1 if you have the setsockopt function. */ #define HAVE_SETSOCKOPT 1 /* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ /* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ /* Define to 1 if you have the header file. */ #define HAVE_SIGNAL_H 1 /* Define to 1 if sig_atomic_t is an available typedef. */ #define HAVE_SIG_ATOMIC_T 1 /* Define to 1 if sig_atomic_t is already defined as volatile. */ /* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ /* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ #define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 /* Define to 1 if you have the socket function. */ #define HAVE_SOCKET 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SOCKET_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the strcmpi function. */ /* #undef HAVE_STRCMPI */ /* Define to 1 if you have the strdup function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the stricmp function. */ /* #undef HAVE_STRICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the strncasecmp function. */ #define HAVE_STRNCASECMP 1 /* Define to 1 if you have the strncmpi function. */ /* #undef HAVE_STRNCMPI */ /* Define to 1 if you have the strnicmp function. */ /* #undef HAVE_STRNICMP */ /* Define to 1 if you have the header file. */ #define HAVE_STROPTS_H 1 /* Define to 1 if you have struct addrinfo. */ #define HAVE_STRUCT_ADDRINFO 1 /* Define to 1 if you have struct in6_addr. */ #define HAVE_STRUCT_IN6_ADDR 1 /* Define to 1 if you have struct sockaddr_in6. */ #define HAVE_STRUCT_SOCKADDR_IN6 1 /* if struct sockaddr_storage is defined */ #define HAVE_STRUCT_SOCKADDR_STORAGE 1 /* Define to 1 if you have the timeval struct. */ #define HAVE_STRUCT_TIMEVAL 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_PARAM_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SELECT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_SOCKET_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_UIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_TIME_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the windows.h header file. */ /* #undef HAVE_WINDOWS_H */ /* Define to 1 if you have the winsock2.h header file. */ /* #undef HAVE_WINSOCK2_H */ /* Define to 1 if you have the winsock.h header file. */ /* #undef HAVE_WINSOCK_H */ /* Define to 1 if you have the writev function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the ws2tcpip.h header file. */ /* #undef HAVE_WS2TCPIP_H */ /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #define LT_OBJDIR ".libs/" /* Define to 1 if you are building a native Windows target. */ /* #undef NATIVE_WINDOWS */ /* Define to 1 if you need the malloc.h header file even with stdlib.h */ /* #undef NEED_MALLOC_H */ /* Define to 1 if you need the memory.h header file even with stdlib.h */ /* #undef NEED_MEMORY_H */ /* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ /* #undef NEED_REENTRANT */ /* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ #define NEED_THREAD_SAFE 1 /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ /* cpu-machine-OS */ #define OS "rs6000-ibm-aix" /* Name of package */ #define PACKAGE "c-ares" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares" /* Define to the full name of this package. */ #define PACKAGE_NAME "c-ares" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "c-ares 1.7.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "c-ares" /* Define to the home page for this package. */ #define PACKAGE_URL "" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.7.1" /* a suitable file/device to read random data from */ #define RANDOM_FILE "/dev/urandom" /* Define to the type of arg 1 for recvfrom. */ #define RECVFROM_TYPE_ARG1 int /* Define to the type pointed by arg 2 for recvfrom. */ #define RECVFROM_TYPE_ARG2 void /* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ #define RECVFROM_TYPE_ARG2_IS_VOID 1 /* Define to the type of arg 3 for recvfrom. */ #define RECVFROM_TYPE_ARG3 size_t /* Define to the type of arg 4 for recvfrom. */ #define RECVFROM_TYPE_ARG4 int /* Define to the type pointed by arg 5 for recvfrom. */ #define RECVFROM_TYPE_ARG5 struct sockaddr /* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG5_IS_VOID */ /* Define to the type pointed by arg 6 for recvfrom. */ #define RECVFROM_TYPE_ARG6 socklen_t /* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ /* #undef RECVFROM_TYPE_ARG6_IS_VOID */ /* Define to the function return type for recvfrom. */ #define RECVFROM_TYPE_RETV ssize_t /* Define to the type of arg 1 for recv. */ #define RECV_TYPE_ARG1 int /* Define to the type of arg 2 for recv. */ #define RECV_TYPE_ARG2 void * /* Define to the type of arg 3 for recv. */ #define RECV_TYPE_ARG3 size_t /* Define to the type of arg 4 for recv. */ #define RECV_TYPE_ARG4 int /* Define to the function return type for recv. */ #define RECV_TYPE_RETV ssize_t /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void /* Define to the type qualifier of arg 2 for send. */ #define SEND_QUAL_ARG2 const /* Define to the type of arg 1 for send. */ #define SEND_TYPE_ARG1 int /* Define to the type of arg 2 for send. */ #define SEND_TYPE_ARG2 void * /* Define to the type of arg 3 for send. */ #define SEND_TYPE_ARG3 size_t /* Define to the type of arg 4 for send. */ #define SEND_TYPE_ARG4 int /* Define to the function return type for send. */ #define SEND_TYPE_RETV ssize_t /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of `size_t', as computed by sizeof. */ #define SIZEOF_SIZE_T 4 /* The size of `struct in6_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN6_ADDR 16 /* The size of `struct in_addr', as computed by sizeof. */ #define SIZEOF_STRUCT_IN_ADDR 4 /* The size of `time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 4 /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define to 1 if you can safely include both and . */ #define TIME_WITH_SYS_TIME 1 /* Define to disable non-blocking sockets. */ /* #undef USE_BLOCKING_SOCKETS */ /* Version number of package */ #define VERSION "1.7.1" /* Define to avoid automatic inclusion of winsock.h */ /* #undef WIN32_LEAN_AND_MEAN */ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN /* # undef WORDS_BIGENDIAN */ # endif #endif /* Define to 1 if OS is AIX. */ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ #define _LARGE_FILES 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Type to use in place of in_addr_t when system does not provide it. */ /* #undef in_addr_t */ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ /* the signed version of size_t */ /* #undef ssize_t */ #define HAVE_GETENV 1 node-v4.2.6/deps/cares/build/gcc_version.py000644 000766 000024 00000000575 12650222322 020753 0ustar00iojsstaff000000 000000 #!/usr/bin/env python import os import re import subprocess import sys def DoMain(*args): cc = os.environ.get('CC', 'gcc') stdin, stderr = os.pipe() subprocess.call([cc, '-v'], stderr=stderr) output = os.read(stdin, 4096) match = re.search("\ngcc version (\d+\.\d+\.\d+)", output) if match: print(match.group(1)) if __name__ == '__main__': DoMain(*sys.argv) node-v4.2.6/benchmark/arrays/000755 000766 000024 00000000000 12650222322 016175 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/assert/000755 000766 000024 00000000000 12650222322 016175 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/buffers/000755 000766 000024 00000000000 12650222322 016330 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/common.js000644 000766 000024 00000014402 12650222322 016523 0ustar00iojsstaff000000 000000 var assert = require('assert'); var fs = require('fs'); var path = require('path'); var child_process = require('child_process'); var outputFormat = process.env.OUTPUT_FORMAT || (+process.env.NODE_BENCH_SILENT ? 'silent' : false) || 'default'; // verify outputFormat if (['default', 'csv', 'silent'].indexOf(outputFormat) == -1) { throw new Error('OUTPUT_FORMAT set to invalid value'); } exports.PORT = process.env.PORT || 12346; // If this is the main module, then run the benchmarks if (module === require.main) { var type = process.argv[2]; var testFilter = process.argv[3]; if (!type) { console.error('usage:\n ./node benchmark/common.js [testFilter]'); process.exit(1); } var dir = path.join(__dirname, type); var tests = fs.readdirSync(dir); if (testFilter) { var filteredTests = tests.filter(function(item){ if (item.lastIndexOf(testFilter) >= 0) { return item; } }); if (filteredTests.length === 0) { console.error('%s is not found in \n %j', testFilter, tests); return; } tests = filteredTests; } runBenchmarks(); } function hasWrk() { var result = child_process.spawnSync('wrk', ['-h']); if (result.error && result.error.code === 'ENOENT') { console.error('Couldn\'t locate `wrk` which is needed for running ' + 'benchmarks. Check benchmark/README.md for further instructions.'); process.exit(-1); } } function runBenchmarks() { var test = tests.shift(); if (!test) return; if (test.match(/^[\._]/)) return process.nextTick(runBenchmarks); if (outputFormat == 'default') console.error(type + '/' + test); test = path.resolve(dir, test); var a = (process.execArgv || []).concat(test); var child = child_process.spawn(process.execPath, a, { stdio: 'inherit' }); child.on('close', function(code) { if (code) { process.exit(code); } else { console.log(''); runBenchmarks(); } }); } exports.createBenchmark = function(fn, options) { return new Benchmark(fn, options); }; function Benchmark(fn, options) { this.fn = fn; this.options = options; this.config = parseOpts(options); this._name = require.main.filename.split(/benchmark[\/\\]/).pop(); this._start = [0,0]; this._started = false; var self = this; process.nextTick(function() { self._run(); }); } // benchmark an http server. Benchmark.prototype.http = function(p, args, cb) { hasWrk(); var self = this; var regexp = /Requests\/sec:[ \t]+([0-9\.]+)/; var url = 'http://127.0.0.1:' + exports.PORT + p; args = args.concat(url); var out = ''; var child = child_process.spawn('wrk', args); child.stdout.setEncoding('utf8'); child.stdout.on('data', function(chunk) { out += chunk; }); child.on('close', function(code) { if (cb) cb(code); if (code) { console.error('wrk failed with ' + code); process.exit(code) } var match = out.match(regexp); var qps = match && +match[1]; if (!qps) { console.error('%j', out); console.error('wrk produced strange output'); process.exit(1); } self.report(+qps); }); }; Benchmark.prototype._run = function() { if (this.config) return this.fn(this.config); // some options weren't set. // run with all combinations var main = require.main.filename; var settings = []; var queueLen = 1; var options = this.options; var queue = Object.keys(options).reduce(function(set, key) { var vals = options[key]; assert(Array.isArray(vals)); // match each item in the set with each item in the list var newSet = new Array(set.length * vals.length); var j = 0; set.forEach(function(s) { vals.forEach(function(val) { newSet[j++] = s.concat(key + '=' + val); }); }); return newSet; }, [[main]]); // output csv heading if (outputFormat == 'csv') console.log('filename,' + Object.keys(options).join(',') + ',result'); var node = process.execPath; var i = 0; function run() { var argv = queue[i++]; if (!argv) return; argv = process.execArgv.concat(argv); var child = child_process.spawn(node, argv, { stdio: 'inherit' }); child.on('close', function(code, signal) { if (code) console.error('child process exited with code ' + code); else run(); }); } run(); }; function parseOpts(options) { // verify that there's an option provided for each of the options // if they're not *all* specified, then we return null. var keys = Object.keys(options); var num = keys.length; var conf = {}; for (var i = 2; i < process.argv.length; i++) { var match = process.argv[i].match(/^(.+)=(.+)$/); if (!match || !match[1] || !match[2] || !options[match[1]]) { return null; } else { conf[match[1]] = isFinite(match[2]) ? +match[2] : match[2] num--; } } // still go ahead and set whatever WAS set, if it was. if (num !== 0) { Object.keys(conf).forEach(function(k) { options[k] = [conf[k]]; }); } return num === 0 ? conf : null; }; Benchmark.prototype.start = function() { if (this._started) throw new Error('Called start more than once in a single benchmark'); this._started = true; this._start = process.hrtime(); }; Benchmark.prototype.end = function(operations) { var elapsed = process.hrtime(this._start); if (!this._started) throw new Error('called end without start'); if (typeof operations !== 'number') throw new Error('called end() without specifying operation count'); var time = elapsed[0] + elapsed[1]/1e9; var rate = operations/time; this.report(rate); }; Benchmark.prototype.report = function(value) { var heading = this.getHeading(); if (outputFormat == 'default') console.log('%s: %s', heading, value.toFixed(5)); else if (outputFormat == 'csv') console.log('%s,%s', heading, value.toFixed(5)); process.exit(0); }; Benchmark.prototype.getHeading = function() { var conf = this.config; if (outputFormat == 'default') { return this._name + ' ' + Object.keys(conf).map(function(key) { return key + '=' + conf[key]; }).join(' '); } else if (outputFormat == 'csv') { return this._name + ',' + Object.keys(conf).map(function(key) { return conf[key]; }).join(','); } }; node-v4.2.6/benchmark/compare.js000644 000766 000024 00000010115 12650222322 016656 0ustar00iojsstaff000000 000000 var usage = 'node benchmark/compare.js ' + ' ' + '[--html] [--red|-r] [--green|-g] ' + '[-- [testFilter]]'; var show = 'both'; var nodes = []; var html = false; var benchmarks; for (var i = 2; i < process.argv.length; i++) { var arg = process.argv[i]; switch (arg) { case '--red': case '-r': show = show === 'green' ? 'both' : 'red'; break; case '--green': case '-g': show = show === 'red' ? 'both' : 'green'; break; case '--html': html = true; break; case '-h': case '-?': case '--help': console.log(usage); process.exit(0); break; case '--': benchmarks = []; break; default: if (Array.isArray(benchmarks)) benchmarks.push(arg); else nodes.push(arg); break; } } if (!html) { var start = ''; var green = '\033[1;32m'; var red = '\033[1;31m'; var reset = '\033[m'; var end = ''; } else { var start = '
';
  var green = '';
  var red = '';
  var reset = '';
  var end = '
'; } var runBench = process.env.NODE_BENCH || 'bench'; if (nodes.length !== 2) return console.error('usage:\n %s', usage); var spawn = require('child_process').spawn; var results = {}; var toggle = 1; var r = (+process.env.NODE_BENCH_RUNS || 1) * 2; run(); function run() { if (--r < 0) return compare(); toggle = ++toggle % 2; var node = nodes[toggle]; console.error('running %s', node); var env = {}; for (var i in process.env) env[i] = process.env[i]; env.NODE = node; var out = ''; var child; if (Array.isArray(benchmarks) && benchmarks.length) child = spawn(node, ['benchmark/common.js'].concat(benchmarks), { env: env }); else child = spawn('make', [runBench], { env: env }); child.stdout.setEncoding('utf8'); child.stdout.on('data', function(c) { out += c; }); child.stderr.pipe(process.stderr); child.on('close', function(code) { if (code) { console.error('%s exited with code=%d', node, code); process.exit(code); } else { out.trim().split(/\r?\n/).forEach(function(line) { line = line.trim(); if (!line) return; var s = line.split(':'); var num = +s.pop(); if (!num && num !== 0) return; line = s.join(':'); var res = results[line] = results[line] || {}; res[node] = res[node] || []; res[node].push(num); }); run(); } }); } function compare() { // each result is an object with {"foo.js arg=bar":12345,...} // compare each thing, and show which node did the best. // node[0] is shown in green, node[1] shown in red. var maxLen = -Infinity; var util = require('util'); console.log(start); Object.keys(results).map(function(bench) { var res = results[bench]; var n0 = avg(res[nodes[0]]); var n1 = avg(res[nodes[1]]); var pct = ((n0 - n1) / n1 * 100).toFixed(2); var g = n0 > n1 ? green : ''; var r = n0 > n1 ? '' : red; var c = r || g; if (show === 'green' && !g || show === 'red' && !r) return; var r0 = util.format('%s%s: %d%s', g, nodes[0], n0.toPrecision(5), g ? reset : ''); var r1 = util.format('%s%s: %d%s', r, nodes[1], n1.toPrecision(5), r ? reset : ''); var pct = c + pct + '%' + reset; var l = util.format('%s: %s %s', bench, r0, r1); maxLen = Math.max(l.length + pct.length, maxLen); return [l, pct]; }).filter(function(l) { return l; }).forEach(function(line) { var l = line[0]; var pct = line[1]; var dotLen = maxLen - l.length - pct.length + 2; var dots = ' ' + new Array(Math.max(0, dotLen)).join('.') + ' '; console.log(l + dots + pct); }); console.log(end); } function avg(list) { if (list.length >= 3) { list = list.sort(); var q = Math.floor(list.length / 4) || 1; list = list.slice(q, -q); } return list.reduce(function(a, b) { return a + b; }, 0) / list.length; } node-v4.2.6/benchmark/crypto/000755 000766 000024 00000000000 12650222322 016214 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/events/000755 000766 000024 00000000000 12650222322 016200 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/fixtures/000755 000766 000024 00000000000 12650222322 016545 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/fs/000755 000766 000024 00000000000 12650222322 015304 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/fs-write-stream-throughput.js000644 000766 000024 00000004551 12650222322 022477 0ustar00iojsstaff000000 000000 // If there are no args, then this is the root. Run all the benchmarks! if (!process.argv[2]) parent(); else runTest(+process.argv[2], +process.argv[3], process.argv[4]); function parent() { var types = [ 'string', 'buffer' ]; var durs = [ 1, 5 ]; var sizes = [ 1, 10, 100, 2048, 10240 ]; var queue = []; types.forEach(function(t) { durs.forEach(function(d) { sizes.forEach(function(s) { queue.push([__filename, d, s, t]); }); }); }); var spawn = require('child_process').spawn; var node = process.execPath; run(); function run() { var args = queue.shift(); if (!args) return; var child = spawn(node, args, { stdio: 'inherit' }); child.on('close', function(code, signal) { if (code) throw new Error('Benchmark failed: ' + args.slice(1)); run(); }); } } function runTest(dur, size, type) { if (type !== 'string') type = 'buffer'; switch (type) { case 'string': var chunk = new Array(size + 1).join('a'); break; case 'buffer': var chunk = new Buffer(size); chunk.fill('a'); break; } var writes = 0; var fs = require('fs'); try { fs.unlinkSync('write_stream_throughput'); } catch (e) {} var start var end; function done() { var time = end[0] + end[1]/1E9; var written = fs.statSync('write_stream_throughput').size / 1024; var rate = (written / time).toFixed(2); console.log('fs_write_stream_dur_%d_size_%d_type_%s: %d', dur, size, type, rate); try { fs.unlinkSync('write_stream_throughput'); } catch (e) {} } var f = require('fs').createWriteStream('write_stream_throughput'); f.on('drain', write); f.on('open', write); f.on('close', done); // streams2 fs.WriteStreams will let you send a lot of writes into the // buffer before returning false, so capture the *actual* end time when // all the bytes have been written to the disk, indicated by 'finish' f.on('finish', function() { end = process.hrtime(start); }); var ending = false; function write() { // don't try to write after we end, even if a 'drain' event comes. // v0.8 streams are so sloppy! if (ending) return; start = start || process.hrtime(); while (false !== f.write(chunk)); end = process.hrtime(start); if (end[0] >= dur) { ending = true; f.end(); } } } node-v4.2.6/benchmark/http/000755 000766 000024 00000000000 12650222322 015653 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/http-flamegraph.sh000644 000766 000024 00000005454 12650222322 020323 0ustar00iojsstaff000000 000000 #!/bin/bash cd "$(dirname "$(dirname $0)")" node=${NODE:-./node} name=${NAME:-stacks} if type sysctl &>/dev/null; then # darwin and linux sudo sysctl -w net.inet.ip.portrange.first=12000 sudo sysctl -w net.inet.tcp.msl=1000 sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000 elif type /usr/sbin/ndd &>/dev/null; then # sunos /usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000 /usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535 /usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152 /usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576 /usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576 fi ulimit -n 100000 $node benchmark/http_simple.js & nodepid=$! echo "node pid = $nodepid" sleep 1 # has to stay alive until dtrace exits dtrace -n 'profile-97/pid == '$nodepid' && arg1/{ @[jstack(150, 8000)] = count(); } tick-60s { exit(0); }' \ | grep -v _ZN2v88internalL21Builtin_HandleApiCallENS0_12_GLOBAL__N_116BuiltinA \ > "$name".src & dtracepid=$! echo "dtrace pid = $dtracepid" sleep 1 test () { c=$1 t=$2 l=$3 k=$4 ab $k -t 10 -c $c http://127.0.0.1:8000/$t/$l \ 2>&1 | grep Req } #test 100 bytes 1024 #test 10 bytes 100 -k #test 100 bytes 1024 -k #test 100 bytes 1024 -k #test 100 bytes 1024 -k echo 'Keep going until dtrace stops listening...' while pargs $dtracepid &>/dev/null; do test 100 bytes ${LENGTH:-1} -k done kill $nodepid echo 'Turn the stacks into a svg' stackvis dtrace flamegraph-svg < "$name".src > "$name".raw.svg echo 'Prune tiny stacks out of the graph' node -e ' var infile = process.argv[1]; var outfile = process.argv[2]; var output = ""; var fs = require("fs"); var input = fs.readFileSync(infile, "utf8"); input = input.split("id=\"details\" > "); var head = input.shift() + "id=\"details\" > "; input = input.join("id=\"details\" > "); var tail = ""; input = input.split("")[0]; var minyKept = Infinity; var minyOverall = Infinity; var rects = input.trim().split(/\n/).filter(function(rect) { var my = rect.match(/y="([0-9\.]+)"/); if (!my) return false; var y = +my[1]; if (!y) return false; minyOverall = Math.min(minyOverall, y); // pluck off everything that will be less than one pixel. var mw = rect.match(/width="([0-9\.]+)"/) if (mw) { var width = +mw[1]; if (!(width >= 1)) return false; } minyKept = Math.min(minyKept, y); return true; }); // move everything up to the top of the page. var ydiff = minyKept - minyOverall; rects = rects.map(function(rect) { var my = rect.match(/y="([0-9\.]+)"/); var y = +my[1]; var newy = y - ydiff; rect = rect.replace(/y="([0-9\.]+)"/, "y=\"" + newy + "\""); return rect; }); fs.writeFileSync(outfile, head + "\n" + rects.join("\n") + "\n" + tail); ' "$name".raw.svg "$name".svg echo '' echo 'done. Results in '"$name"'.svg' node-v4.2.6/benchmark/http.sh000755 000766 000024 00000002023 12650222322 016207 0ustar00iojsstaff000000 000000 #!/bin/bash cd "$(dirname "$(dirname $0)")" if type sysctl &>/dev/null; then # darwin and linux sudo sysctl -w net.ipv4.ip_local_port_range="12000 65535" sudo sysctl -w net.inet.ip.portrange.first=12000 sudo sysctl -w net.inet.tcp.msl=1000 sudo sysctl -w kern.maxfiles=1000000 kern.maxfilesperproc=1000000 elif type /usr/sbin/ndd &>/dev/null; then # sunos /usr/sbin/ndd -set /dev/tcp tcp_smallest_anon_port 12000 /usr/sbin/ndd -set /dev/tcp tcp_largest_anon_port 65535 /usr/sbin/ndd -set /dev/tcp tcp_max_buf 2097152 /usr/sbin/ndd -set /dev/tcp tcp_xmit_hiwat 1048576 /usr/sbin/ndd -set /dev/tcp tcp_recv_hiwat 1048576 fi ulimit -n 100000 k=${KEEPALIVE} if [ "$k" = "no" ]; then k="" else k="-k" fi node=${NODE:-./node} $node benchmark/http_simple.js & npid=$! sleep 1 if [ "$k" = "-k" ]; then echo "using keepalive" fi for i in a a a a a a a a a a a a a a a a a a a a; do ab $k -t 10 -c 100 http://127.0.0.1:8000/${TYPE:-bytes}/${LENGTH:-1024} \ 2>&1 | grep Req | egrep -o '[0-9\.]+' done kill $npid node-v4.2.6/benchmark/http_bench.js000644 000766 000024 00000005433 12650222322 017355 0ustar00iojsstaff000000 000000 var spawn = require('child_process').spawn; var cluster = require('cluster'); var http = require('http'); var options = { mode: 'master', host: '127.0.0.1', port: 22344, path: '/', servers: 1, clients: 1, clientConcurrentRequests: 2 }; for (var i = 2; i < process.argv.length; ++i) { var args = process.argv[i].split('=', 2); var key = args[0]; var val = args[1]; options[key] = val; } switch (options.mode) { case 'master': startMaster(); break; case 'server': startServer(); break; case 'client': startClient(); break; default: throw new Error('Bad mode: ' + options.mode); } process.title = 'http_bench[' + options.mode + ']'; // monkey-patch the log functions so they include name + pid console.log = patch(console.log); console.trace = patch(console.trace); console.error = patch(console.error); function patch(fun) { var prefix = process.title + '[' + process.pid + '] '; return function() { var args = Array.prototype.slice.call(arguments); args[0] = prefix + args[0]; return fun.apply(console, args); }; } function startMaster() { if (!cluster.isMaster) return startServer(); var forkCount = 0; cluster.on('online', function () { forkCount = forkCount + 1; if (forkCount === ~~options.servers) { var args = [ __filename, 'mode=client', 'clientConcurrentRequests=' + options.clientConcurrentRequests ]; for (var i = ~~options.clients; i > 0; --i) { var cp = spawn(process.execPath, args); cp.stdout.pipe(process.stdout); cp.stderr.pipe(process.stderr); } } }); for (var i = ~~options.servers; i > 0; --i) cluster.fork(); } function startServer() { http.createServer(onRequest).listen(options.port, options.host); var body = Array(1024).join('x'); var headers = {'Content-Length': '' + body.length}; function onRequest(req, res) { req.on('error', onError); res.on('error', onError); res.writeHead(200, headers); res.end(body); } function onError(err) { console.error(err.stack); } } function startClient() { // send off a bunch of concurrent requests for (var i = ~~options.clientConcurrentRequests; i > 0; --i) { sendRequest(); } function sendRequest() { var req = http.request(options, onConnection); req.on('error', onError); req.end(); } // add a little back-off to prevent EADDRNOTAVAIL errors, it's pretty easy // to exhaust the available port range function relaxedSendRequest() { setTimeout(sendRequest, 1); } function onConnection(res) { res.on('error', onError); res.on('data', onData); res.on('end', relaxedSendRequest); } function onError(err) { console.error(err.stack); relaxedSendRequest(); } function onData(data) { // this space intentionally left blank } } node-v4.2.6/benchmark/http_server_lag.js000644 000766 000024 00000000655 12650222322 020430 0ustar00iojsstaff000000 000000 var http = require('http'); var port = parseInt(process.env.PORT, 10) || 8000; var defaultLag = parseInt(process.argv[2], 10) || 100; http.createServer(function(req, res) { res.writeHead(200, { 'content-type': 'text/plain', 'content-length': '2' }); var lag = parseInt(req.url.split("/").pop(), 10) || defaultLag; setTimeout(function() { res.end('ok'); }, lag); }).listen(port, 'localhost'); node-v4.2.6/benchmark/http_simple.js000644 000766 000024 00000005727 12650222322 017575 0ustar00iojsstaff000000 000000 var path = require('path'), exec = require('child_process').exec, http = require('http'); var port = parseInt(process.env.PORT || 8000); var fixed = makeString(20 * 1024, 'C'), storedBytes = {}, storedBuffer = {}, storedUnicode = {}; var useDomains = process.env.NODE_USE_DOMAINS; // set up one global domain. if (useDomains) { var domain = require('domain'); var gdom = domain.create(); gdom.on('error', function(er) { console.error('Error on global domain', er); throw er; }); gdom.enter(); } var server = module.exports = http.createServer(function (req, res) { if (useDomains) { var dom = domain.create(); dom.add(req); dom.add(res); } var commands = req.url.split('/'); var command = commands[1]; var body = ''; var arg = commands[2]; var n_chunks = parseInt(commands[3], 10); var status = 200; if (command == 'bytes') { var n = ~~arg; if (n <= 0) throw new Error('bytes called with n <= 0') if (storedBytes[n] === undefined) { storedBytes[n] = makeString(n, 'C'); } body = storedBytes[n]; } else if (command == 'buffer') { var n = ~~arg; if (n <= 0) throw new Error('buffer called with n <= 0'); if (storedBuffer[n] === undefined) { storedBuffer[n] = new Buffer(n); for (var i = 0; i < n; i++) { storedBuffer[n][i] = 'C'.charCodeAt(0); } } body = storedBuffer[n]; } else if (command == 'unicode') { var n = ~~arg; if (n <= 0) throw new Error('unicode called with n <= 0'); if (storedUnicode[n] === undefined) { storedUnicode[n] = makeString(n, '\u263A'); } body = storedUnicode[n]; } else if (command == 'quit') { res.connection.server.close(); body = 'quitting'; } else if (command == 'fixed') { body = fixed; } else if (command == 'echo') { res.writeHead(200, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' }); req.pipe(res); return; } else { status = 404; body = 'not found\n'; } // example: http://localhost:port/bytes/512/4 // sends a 512 byte body in 4 chunks of 128 bytes if (n_chunks > 0) { res.writeHead(status, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' }); // send body in chunks var len = body.length; var step = Math.floor(len / n_chunks) || 1; for (var i = 0, n = (n_chunks - 1); i < n; ++i) { res.write(body.slice(i * step, i * step + step)); } res.end(body.slice((n_chunks - 1) * step)); } else { var content_length = body.length.toString(); res.writeHead(status, { 'Content-Type': 'text/plain', 'Content-Length': content_length }); res.end(body); } }); function makeString(size, c) { var s = ''; while (s.length < size) { s += c; } return s; } server.listen(port, function () { if (module === require.main) console.error('Listening at http://127.0.0.1:'+port+'/'); }); node-v4.2.6/benchmark/http_simple.rb000644 000766 000024 00000004330 12650222322 017551 0ustar00iojsstaff000000 000000 DIR = File.dirname(__FILE__) def fib(n) return 1 if n <= 1 fib(n-1) + fib(n-2) end def wait(seconds) n = (seconds / 0.01).to_i n.times do sleep(0.01) #File.read(DIR + '/yahoo.html') end end class SimpleApp @@responses = {} def initialize @count = 0 end def deferred?(env) false end def call(env) path = env['PATH_INFO'] || env['REQUEST_URI'] commands = path.split('/') @count += 1 if commands.include?('periodical_activity') and @count % 10 != 1 return [200, {'Content-Type'=>'text/plain'}, "quick response!\r\n"] end if commands.include?('fibonacci') n = commands.last.to_i raise "fibonacci called with n <= 0" if n <= 0 body = (1..n).to_a.map { |i| fib(i).to_s }.join(' ') status = 200 elsif commands.include?('wait') n = commands.last.to_f raise "wait called with n <= 0" if n <= 0 wait(n) body = "waited about #{n} seconds" status = 200 elsif commands.include?('bytes') n = commands.last.to_i raise "bytes called with n <= 0" if n <= 0 body = @@responses[n] || "C"*n status = 200 elsif commands.include?('fixed') n = 20 * 1024; body = @@responses[n] || "C"*n status = 200 elsif commands.include?('test_post_length') input_body = "" while chunk = env['rack.input'].read(512) input_body << chunk end if env['CONTENT_LENGTH'].to_i == input_body.length body = "Content-Length matches input length" status = 200 else body = "Content-Length doesn't matches input length! content_length = #{env['CONTENT_LENGTH'].to_i} input_body.length = #{input_body.length}" status = 500 end else status = 404 body = "Undefined url" end body += "\r\n" headers = {'Content-Type' => 'text/plain', 'Content-Length' => body.length.to_s } [status, headers, [body]] end end if $0 == __FILE__ #require DIR + '/../lib/ebb' require 'rubygems' require 'rack' require 'thin' require 'ebb' # Rack::Handler::Mongrel.run(SimpleApp.new, :Port => 8000) Thin::Server.start("0.0.0.0", 8000, SimpleApp.new) # Ebb::start_server(SimpleApp.new, :port => 8000) end node-v4.2.6/benchmark/http_simple_auto.js000644 000766 000024 00000006346 12650222322 020623 0ustar00iojsstaff000000 000000 // // Usage: // node benchmark/http_simple_auto.js // // Where: // Arguments to pass to `ab`. // Target to benchmark, e.g. `bytes/1024` or `buffer/8192`. // var path = require("path"); var http = require("http"); var spawn = require("child_process").spawn; var port = parseInt(process.env.PORT || 8000); var fixed = "" for (var i = 0; i < 20*1024; i++) { fixed += "C"; } var stored = {}; var storedBuffer = {}; var server = http.createServer(function (req, res) { var commands = req.url.split("/"); var command = commands[1]; var body = ""; var arg = commands[2]; var n_chunks = parseInt(commands[3], 10); var status = 200; if (command == "bytes") { var n = parseInt(arg, 10) if (n <= 0) throw "bytes called with n <= 0" if (stored[n] === undefined) { stored[n] = ""; for (var i = 0; i < n; i++) { stored[n] += "C" } } body = stored[n]; } else if (command == "buffer") { var n = parseInt(arg, 10) if (n <= 0) throw new Error("bytes called with n <= 0"); if (storedBuffer[n] === undefined) { storedBuffer[n] = new Buffer(n); for (var i = 0; i < n; i++) { storedBuffer[n][i] = "C".charCodeAt(0); } } body = storedBuffer[n]; } else if (command == "quit") { res.connection.server.close(); body = "quitting"; } else if (command == "fixed") { body = fixed; } else if (command == "echo") { res.writeHead(200, { "Content-Type": "text/plain", "Transfer-Encoding": "chunked" }); req.pipe(res); return; } else { status = 404; body = "not found\n"; } // example: http://localhost:port/bytes/512/4 // sends a 512 byte body in 4 chunks of 128 bytes if (n_chunks > 0) { res.writeHead(status, { "Content-Type": "text/plain", "Transfer-Encoding": "chunked" }); // send body in chunks var len = body.length; var step = Math.floor(len / n_chunks) || 1; for (var i = 0, n = (n_chunks - 1); i < n; ++i) { res.write(body.slice(i * step, i * step + step)); } res.end(body.slice((n_chunks - 1) * step)); } else { var content_length = body.length.toString(); res.writeHead(status, { "Content-Type": "text/plain", "Content-Length": content_length }); res.end(body); } }); server.listen(port, function () { var url = 'http://127.0.0.1:' + port + '/'; var n = process.argv.length - 1; process.argv[n] = url + process.argv[n]; var cp = spawn('ab', process.argv.slice(2)); cp.stdout.pipe(process.stdout); cp.stderr.pipe(process.stderr); cp.on('exit', function() { server.close(); process.nextTick(dump_mm_stats); }); }); function dump_mm_stats() { if (typeof gc != 'function') return; var before = process.memoryUsage(); for (var i = 0; i < 10; ++i) gc(); var after = process.memoryUsage(); setTimeout(print_stats, 250); // give GC time to settle function print_stats() { console.log('\nBEFORE / AFTER GC'); ['rss', 'heapTotal', 'heapUsed'].forEach(function(key) { var a = before[key] / (1024 * 1024); var b = after[key] / (1024 * 1024); console.log('%sM / %sM %s', a.toFixed(2), b.toFixed(2), key); }); } } node-v4.2.6/benchmark/http_simple_bench.sh000755 000766 000024 00000002676 12650222322 020735 0ustar00iojsstaff000000 000000 #!/bin/bash SERVER=127.0.0.1 PORT=${PORT:=8000} # You may want to configure your TCP settings to make many ports available # to node and ab. On macintosh use: # sudo sysctl -w net.inet.ip.portrange.first=32768 # sudo sysctl -w net.inet.tcp.msl=1000 if [ ! -d benchmark/ ]; then echo "Run this script from the node root directory" exit 1 fi if [ $SERVER == "127.0.0.1" ]; then ./node benchmark/http_simple.js & node_pid=$! sleep 1 fi date=`date "+%Y%m%d%H%M%S"` ab_hello_world() { local type="$1" local ressize="$2" if [ $type == "string" ]; then local uri="bytes/$ressize" else local uri="buffer/$ressize" fi name="ab-hello-world-$type-$ressize" dir=".benchmark_reports/$name/$rev/" if [ ! -d $dir ]; then mkdir -p $dir fi summary_fn="$dir/$date.summary" data_fn="$dir/$date.data" echo "Bench $name starts in 3 seconds..." # let things calm down sleep 3 # hammer that as hard as it can for 10 seconds. ab -g $data_fn -c 100 -t 10 http://$SERVER:$PORT/$uri > $summary_fn # add our data about the server echo >> $summary_fn echo >> $summary_fn echo "webserver-rev: $rev" >> $summary_fn echo "webserver-uname: $uname" >> $summary_fn grep Req $summary_fn echo "Summary: $summary_fn" echo } # 1k ab_hello_world 'string' '1024' ab_hello_world 'buffer' '1024' # 100k ab_hello_world 'string' '102400' ab_hello_world 'buffer' '102400' if [ ! -z $node_pid ]; then kill -9 $node_pid fi node-v4.2.6/benchmark/http_simple_cluster.js000644 000766 000024 00000000404 12650222322 021321 0ustar00iojsstaff000000 000000 var cluster = require('cluster'); var os = require('os'); if (cluster.isMaster) { console.log('master running on pid %d', process.pid); for (var i = 0, n = os.cpus().length; i < n; ++i) cluster.fork(); } else { require(__dirname + '/http_simple.js'); } node-v4.2.6/benchmark/idle_clients.js000644 000766 000024 00000001630 12650222322 017670 0ustar00iojsstaff000000 000000 net = require('net'); var errors = 0, connections = 0; var lastClose = 0; function connect () { process.nextTick(function () { var s = net.Stream(); var gotConnected = false; s.connect(9000); s.on('connect', function () { gotConnected = true; connections++; connect(); }); s.on('close', function () { if (gotConnected) connections--; lastClose = new Date(); }); s.on('error', function () { errors++; }); }); } connect(); var oldConnections, oldErrors; // Try to start new connections every so often setInterval(connect, 5000); setInterval(function () { if (oldConnections != connections) { oldConnections = connections; console.log("CLIENT %d connections: %d", process.pid, connections); } if (oldErrors != errors) { oldErrors = errors; console.log("CLIENT %d errors: %d", process.pid, errors); } }, 1000); node-v4.2.6/benchmark/idle_server.js000644 000766 000024 00000001075 12650222322 017540 0ustar00iojsstaff000000 000000 net = require('net'); connections = 0; var errors = 0; server = net.Server(function (socket) { socket.on('error', function () { errors++; }); }); //server.maxConnections = 128; server.listen(9000); var oldConnections, oldErrors; setInterval(function () { if (oldConnections != server.connections) { oldConnections = server.connections; console.log("SERVER %d connections: %d", process.pid, server.connections); } if (oldErrors != errors) { oldErrors = errors; console.log("SERVER %d errors: %d", process.pid, errors); } }, 1000); node-v4.2.6/benchmark/io.c000644 000766 000024 00000004201 12650222322 015444 0ustar00iojsstaff000000 000000 /** * gcc -o iotest io.c */ #include #include #include #include #include #include #include #include #include static int c = 0; static int tsize = 1000 * 1048576; static const char* path = "/tmp/wt.dat"; static char buf[65536]; static uint64_t now(void) { struct timeval tv; if (gettimeofday(&tv, NULL)) abort(); return tv.tv_sec * 1000000ULL + tv.tv_usec; } static void writetest(int size, size_t bsize) { int i; uint64_t start, end; double elapsed; double mbps; assert(bsize <= sizeof buf); int fd = open(path, O_CREAT|O_WRONLY, 0644); if (fd < 0) { perror("open failed"); exit(254); } start = now(); for (i = 0; i < size; i += bsize) { int rv = write(fd, buf, bsize); if (rv < 0) { perror("write failed"); exit(254); } } #ifndef NSYNC # ifdef __linux__ fdatasync(fd); # else fsync(fd); # endif #endif /* SYNC */ close(fd); end = now(); elapsed = (end - start) / 1e6; mbps = ((tsize/elapsed)) / 1048576; fprintf(stderr, "Wrote %d bytes in %03fs using %ld byte buffers: %03f\n", size, elapsed, bsize, mbps); } void readtest(int size, size_t bsize) { int i; uint64_t start, end; double elapsed; double mbps; assert(bsize <= sizeof buf); int fd = open(path, O_RDONLY, 0644); if (fd < 0) { perror("open failed"); exit(254); } start = now(); for (i = 0; i < size; i += bsize) { int rv = read(fd, buf, bsize); if (rv < 0) { perror("write failed"); exit(254); } } close(fd); end = now(); elapsed = (end - start) / 1e6; mbps = ((tsize/elapsed)) / 1048576; fprintf(stderr, "Read %d bytes in %03fs using %ld byte buffers: %03fmB/s\n", size, elapsed, bsize, mbps); } void cleanup() { unlink(path); } int main(int argc, char** argv) { int i; int bsizes[] = {1024, 4096, 8192, 16384, 32768, 65536, 0}; if (argc > 1) path = argv[1]; for (i = 0; bsizes[i] != 0; i++) { writetest(tsize, bsizes[i]); } for (i = 0; bsizes[i] != 0; i++) { readtest(tsize, bsizes[i]); } atexit(cleanup); return 0; } node-v4.2.6/benchmark/misc/000755 000766 000024 00000000000 12650222322 015627 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/net/000755 000766 000024 00000000000 12650222322 015462 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/path/000755 000766 000024 00000000000 12650222322 015630 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/plot.R000755 000766 000024 00000004237 12650222322 016006 0ustar00iojsstaff000000 000000 #!/usr/bin/env Rscript # To use this script you'll need to install R: http://www.r-project.org/ # and a library for R called ggplot2 # Which can be done by starting R and typing install.packages("ggplot2") # like this: # # shell% R # R version 2.11.0 beta (2010-04-12 r51689) # > install.packages("ggplot2") # (follow prompt) # # Then you can try this script by providing a full path to .data file # outputed from 'make bench' # # > cd ~/src/node # > make bench # ... # > ./benchmark/plot.R .benchmark_reports/ab-hello-world-buffer-1024/ff456b38862de3fd0118c6ac6b3f46edb1fbb87f/20101013162056.data # # This will generate a PNG file which you can view # # # Hopefully these steps will be automated in the future. library(ggplot2) args <- commandArgs(TRUE) ab.load <- function (filename, name) { raw <- data.frame(read.csv(filename, sep="\t", header=T), server=name) raw <- data.frame(raw, time=raw$seconds-min(raw$seconds)) raw <- data.frame(raw, time_s=raw$time/1000000) raw } #ab.tsPoint <- function (d) { # qplot(time_s, ttime, data=d, facets=server~., # geom="point", alpha=I(1/15), ylab="response time (ms)", # xlab="time (s)", main="c=30, res=26kb", # ylim=c(0,100)) #} # #ab.tsLine <- function (d) { # qplot(time_s, ttime, data=d, facets=server~., # geom="line", ylab="response time (ms)", # xlab="time (s)", main="c=30, res=26kb", # ylim=c(0,100)) #} filename <- args[0:1] data <- ab.load(filename, "node") # histogram #hist_png_filename <- gsub(".data", "_hist.png", filename) hist_png_filename <- "hist.png" png(filename = hist_png_filename, width = 480, height = 380, units = "px") qplot(ttime, data=data, geom="histogram", main="xxx", binwidth=1, xlab="response time (ms)", xlim=c(0,100)) print(hist_png_filename) # time series #ts_png_filename <- gsub(".data", "_ts.png", filename) ts_png_filename = "ts.png" png(filename = ts_png_filename, width = 480, height = 380, units = "px") qplot(time, ttime, data=data, facets=server~., geom="point", alpha=I(1/15), ylab="response time (ms)", xlab="time (s)", main="xxx", ylim=c(0,100)) print(ts_png_filename) node-v4.2.6/benchmark/plot_csv.R000755 000766 000024 00000002051 12650222322 016651 0ustar00iojsstaff000000 000000 #!/usr/bin/env Rscript # To use this to graph some benchmarks, install R (http://www.r-project.org/) # and ggplot (http://ggplot2.org/). # # Once installed, you can generate some CSV output with a command like this: # # $ OUTPUT_FORMAT=csv node benchmark/http/client-request-body.js > data.csv # $ ./benchmark/plot_csv.R data.csv data.png bytes type # # Where the 3rd argument to this script is the graph's X coordinate, the 4th is # how the output is grouped, and the Y coordinate defaults to result. library(methods) library(ggplot2) # get info from arguments args <- commandArgs(TRUE) csvFilename <- args[1] graphFilename <- args[2] xCoordinate <- args[3] groupBy <- args[4] # read data data <- read.csv(file = csvFilename, head = TRUE) # plot and save plot <- ggplot(data = data, aes_string(x = xCoordinate, y = 'result', col = groupBy)) + geom_point(size = 5) + ggtitle(data$filename) png(filename = graphFilename, width = 560, height = 480, units = 'px') print(plot) graphics.off() cat(paste('Saved to', graphFilename, '\n')) node-v4.2.6/benchmark/querystring/000755 000766 000024 00000000000 12650222322 017270 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/README.md000644 000766 000024 00000007714 12650222322 016164 0ustar00iojsstaff000000 000000 # Node.js core benchmark tests This folder contains benchmark tests to measure the performance for certain Node.js APIs. ## Prerequisites Most of the http benchmarks require [`wrk`][wrk] and [`ab`][ab] (ApacheBench) being installed. These may be available through your preferred package manager. If they are not available: - `wrk` may easily be built [from source][wrk] via `make`. - `ab` is sometimes bundled in a package called `apache2-utils`. [wrk]: https://github.com/wg/wrk [ab]: http://httpd.apache.org/docs/2.2/programs/ab.html ## How to run tests There are three ways to run benchmark tests: ### Run all tests of a given type For example, buffers: ```bash node benchmark/common.js buffers ``` The above command will find all scripts under `buffers` directory and require each of them as a module. When a test script is required, it creates an instance of `Benchmark` (a class defined in common.js). In the next tick, the `Benchmark` constructor iterates through the configuration object property values and runs the test function with each of the combined arguments in spawned processes. For example, buffers/buffer-read.js has the following configuration: ```js var bench = common.createBenchmark(main, { noAssert: [false, true], buffer: ['fast', 'slow'], type: ['UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE', 'Int8', 'Int16LE', 'Int16BE', 'Int32LE', 'Int32BE', 'FloatLE', 'FloatBE', 'DoubleLE', 'DoubleBE'], millions: [1] }); ``` The runner takes one item from each of the property array value to build a list of arguments to run the main function. The main function will receive the conf object as follows: - first run: ```js { noAssert: false, buffer: 'fast', type: 'UInt8', millions: 1 } ``` - second run: ```js { noAssert: false, buffer: 'fast', type: 'UInt16LE', millions: 1 } ``` ... In this case, the main function will run 2*2*14*1 = 56 times. The console output looks like the following: ``` buffers//buffer-read.js buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 271.83 buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 239.43 buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 244.57 ... ``` The last number is the rate of operations. Higher is better. ### Run an individual test For example, buffer-slice.js: ```bash node benchmark/buffers/buffer-read.js ``` The output: ``` buffers/buffer-read.js noAssert=false buffer=fast type=UInt8 millions=1: 246.79 buffers/buffer-read.js noAssert=false buffer=fast type=UInt16LE millions=1: 240.11 buffers/buffer-read.js noAssert=false buffer=fast type=UInt16BE millions=1: 245.91 ... ``` ### Run tests with options This example will run only the first type of url test, with one iteration. (Note: benchmarks require __many__ iterations to be statistically accurate.) ```bash node benchmark/url/url-parse.js type=one n=1 ``` Output: ``` url/url-parse.js type=one n=1: 1663.74402 ``` ## How to write a benchmark test The benchmark tests are grouped by types. Each type corresponds to a subdirectory, such as `arrays`, `buffers`, or `fs`. Let's add a benchmark test for Buffer.slice function. We first create a file buffers/buffer-slice.js. ### The code snippet ```js var common = require('../common.js'); // Load the test runner var SlowBuffer = require('buffer').SlowBuffer; // Create a benchmark test for function `main` and the configuration variants var bench = common.createBenchmark(main, { type: ['fast', 'slow'], // Two types of buffer n: [512] // Number of times (each unit is 1024) to call the slice API }); function main(conf) { // Read the parameters from the configuration var n = +conf.n; var b = conf.type === 'fast' ? buf : slowBuf; bench.start(); // Start benchmarking for (var i = 0; i < n * 1024; i++) { // Add your test here b.slice(10, 256); } bench.end(n); // End benchmarking } ``` node-v4.2.6/benchmark/report-startup-memory.js000644 000766 000024 00000000050 12650222322 021546 0ustar00iojsstaff000000 000000 console.log(process.memoryUsage().rss); node-v4.2.6/benchmark/static_http_server.js000644 000766 000024 00000001432 12650222322 021146 0ustar00iojsstaff000000 000000 var http = require('http'); var concurrency = 30; var port = 12346; var n = 700; var bytes = 1024*5; var requests = 0; var responses = 0; var body = ''; for (var i = 0; i < bytes; i++) { body += 'C'; } var server = http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': body.length }); res.end(body); }) server.listen(port, function() { var agent = new http.Agent(); agent.maxSockets = concurrency; for (var i = 0; i < n; i++) { var req = http.get({ port: port, path: '/', agent: agent }, function(res) { res.resume(); res.on('end', function() { if (++responses === n) { server.close(); } }); }); req.id = i; requests++; } }); node-v4.2.6/benchmark/tls/000755 000766 000024 00000000000 12650222322 015476 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/url/000755 000766 000024 00000000000 12650222322 015476 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/util/000755 000766 000024 00000000000 12650222322 015651 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/util/inspect.js000644 000766 000024 00000000456 12650222322 017661 0ustar00iojsstaff000000 000000 var util = require('util'); var common = require('../common.js'); var bench = common.createBenchmark(main, {n: [5e6]}); function main(conf) { var n = conf.n | 0; bench.start(); for (var i = 0; i < n; i += 1) { var r = util.inspect({a: 'a', b: 'b', c: 'c', d: 'd'}); } bench.end(n); } node-v4.2.6/benchmark/url/url-parse.js000644 000766 000024 00000002011 12650222322 017740 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var url = require('url'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: 'one two three four five six'.split(' '), n: [25e4] }); function main(conf) { var type = conf.type; var n = conf.n | 0; var inputs = { one: 'http://nodejs.org/docs/latest/api/url.html#url_url_format_urlobj', two: 'http://blog.nodejs.org/', three: 'https://encrypted.google.com/search?q=url&q=site:npmjs.org&hl=en', four: 'javascript:alert("node is awesome");', five: 'some.ran/dom/url.thing?oh=yes#whoo', six: 'https://user:pass@example.com/', }; var input = inputs[type] || ''; // Force-optimize url.parse() so that the benchmark doesn't get // disrupted by the optimizer kicking in halfway through. for (var name in inputs) url.parse(inputs[name]); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(url.parse)'); bench.start(); for (var i = 0; i < n; i += 1) url.parse(input); bench.end(n); } node-v4.2.6/benchmark/url/url-resolve.js000644 000766 000024 00000001403 12650222322 020311 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var url = require('url'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['one'], n: [1e5], }); function main(conf) { var type = conf.type; var n = conf.n | 0; var inputs = { one: ['http://example.com/', '../../../../../etc/passwd'], }; var input = inputs[type] || []; // Force-optimize url.resolve() so that the benchmark doesn't get // disrupted by the optimizer kicking in halfway through. for (var name in inputs) url.resolve(inputs[name][0], inputs[name][1]); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(url.resolve)'); bench.start(); for (var i = 0; i < n; i += 1) url.resolve(input[0], input[1]); bench.end(n); } node-v4.2.6/benchmark/tls/throughput.js000644 000766 000024 00000003324 12650222322 020247 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { dur: [5], type: ['buf', 'asc', 'utf'], size: [2, 1024, 1024 * 1024] }); var dur, type, encoding, size; var server; var path = require('path'); var fs = require('fs'); var cert_dir = path.resolve(__dirname, '../../test/fixtures'); var options; var tls = require('tls'); function main(conf) { dur = +conf.dur; type = conf.type; size = +conf.size; var chunk; switch (type) { case 'buf': chunk = new Buffer(size); chunk.fill('b'); break; case 'asc': chunk = new Array(size + 1).join('a'); encoding = 'ascii'; break; case 'utf': chunk = new Array(size/2 + 1).join('ü'); encoding = 'utf8'; break; default: throw new Error('invalid type'); } options = { key: fs.readFileSync(cert_dir + '/test_key.pem'), cert: fs.readFileSync(cert_dir + '/test_cert.pem'), ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ], ciphers: 'AES256-GCM-SHA384' }; server = tls.createServer(options, onConnection); setTimeout(done, dur * 1000); server.listen(common.PORT, function() { var opt = { port: common.PORT, rejectUnauthorized: false }; var conn = tls.connect(opt, function() { bench.start(); conn.on('drain', write); write(); }); function write() { var i = 0; while (false !== conn.write(chunk, encoding)); } }); var received = 0; function onConnection(conn) { conn.on('data', function(chunk) { received += chunk.length; }); } function done() { var mbits = (received * 8) / (1024 * 1024); bench.end(mbits); conn.destroy(); server.close(); } } node-v4.2.6/benchmark/tls/tls-connect.js000644 000766 000024 00000003177 12650222322 020275 0ustar00iojsstaff000000 000000 var assert = require('assert'), fs = require('fs'), path = require('path'), tls = require('tls'); var common = require('../common.js'); var bench = common.createBenchmark(main, { concurrency: [1, 10], dur: [5] }); var clientConn = 0; var serverConn = 0; var server; var dur; var concurrency; var running = true; function main(conf) { dur = +conf.dur; concurrency = +conf.concurrency; var cert_dir = path.resolve(__dirname, '../../test/fixtures'), options = { key: fs.readFileSync(cert_dir + '/test_key.pem'), cert: fs.readFileSync(cert_dir + '/test_cert.pem'), ca: [ fs.readFileSync(cert_dir + '/test_ca.pem') ], ciphers: 'AES256-GCM-SHA384' }; server = tls.createServer(options, onConnection); server.listen(common.PORT, onListening); } function onListening() { setTimeout(done, dur * 1000); bench.start(); for (var i = 0; i < concurrency; i++) makeConnection(); } function onConnection(conn) { serverConn++; } function makeConnection() { var conn = tls.connect({ port: common.PORT, rejectUnauthorized: false }, function() { clientConn++; conn.on('error', function(er) { console.error('client error', er); throw er; }); conn.end(); if (running) makeConnection(); }); } function done() { running = false; // it's only an established connection if they both saw it. // because we destroy the server somewhat abruptly, these // don't always match. Generally, serverConn will be // the smaller number, but take the min just to be sure. bench.end(Math.min(serverConn, clientConn)); } node-v4.2.6/benchmark/querystring/querystring-parse.js000644 000766 000024 00000001602 12650222322 023331 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var querystring = require('querystring'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['noencode', 'encodemany', 'encodelast'], n: [1e6], }); function main(conf) { var type = conf.type; var n = conf.n | 0; var inputs = { noencode: 'foo=bar&baz=quux&xyzzy=thud', encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d', encodelast: 'foo=bar&baz=quux&xyzzy=thu%64' }; var input = inputs[type]; // Force-optimize querystring.parse() so that the benchmark doesn't get // disrupted by the optimizer kicking in halfway through. for (var name in inputs) querystring.parse(inputs[name]); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(querystring.parse)'); bench.start(); for (var i = 0; i < n; i += 1) querystring.parse(input); bench.end(n); } node-v4.2.6/benchmark/querystring/querystring-stringify.js000644 000766 000024 00000002032 12650222322 024233 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var querystring = require('querystring'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['noencode', 'encodemany', 'encodelast'], n: [1e6], }); function main(conf) { var type = conf.type; var n = conf.n | 0; var inputs = { noencode: { foo: 'bar', baz: 'quux', xyzzy: 'thud' }, encodemany: { '\u0080\u0083\u0089': 'bar', '\u008C\u008E\u0099': 'quux', xyzzy: '\u00A5q\u00A3r' }, encodelast: { foo: 'bar', baz: 'quux', xyzzy: 'thu\u00AC' } }; var input = inputs[type]; // Force-optimize querystring.stringify() so that the benchmark doesn't get // disrupted by the optimizer kicking in halfway through. for (var name in inputs) querystring.stringify(inputs[name]); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(querystring.stringify)'); bench.start(); for (var i = 0; i < n; i += 1) querystring.stringify(input); bench.end(n); } node-v4.2.6/benchmark/path/basename.js000644 000766 000024 00000001235 12650222322 017742 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.basename('/foo/bar/baz/asdf/quux.html'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.basename)'); p.basename('/foo/bar/baz/asdf/quux.html'); bench.start(); for (var i = 0; i < n; i++) { p.basename('/foo/bar/baz/asdf/quux.html'); p.basename('/foo/bar/baz/asdf/quux.html', '.html'); } bench.end(n); } node-v4.2.6/benchmark/path/dirname.js000644 000766 000024 00000001122 12650222322 017601 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.dirname('/foo/bar/baz/asdf/quux'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.dirname)'); p.dirname('/foo/bar/baz/asdf/quux'); bench.start(); for (var i = 0; i < n; i++) { p.dirname('/foo/bar/baz/asdf/quux'); } bench.end(n); } node-v4.2.6/benchmark/path/extname.js000644 000766 000024 00000001106 12650222322 017625 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.extname('index.html'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.extname)'); p.extname('index.html'); bench.start(); for (var i = 0; i < n; i++) { p.extname('index.html'); p.extname('index'); } bench.end(n); } node-v4.2.6/benchmark/path/format.js000644 000766 000024 00000001431 12650222322 017455 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e7], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; var test = conf.type === 'win32' ? { root: 'C:\\', dir: 'C:\\path\\dir', base: 'index.html', ext: '.html', name: 'index' } : { root : '/', dir : '/home/user/dir', base : 'index.html', ext : '.html', name : 'index' }; // Force optimization before starting the benchmark p.format(test); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.format)'); p.format(test); bench.start(); for (var i = 0; i < n; i++) { p.format(test); } bench.end(n); } node-v4.2.6/benchmark/path/isAbsolute.js000644 000766 000024 00000001434 12650222322 020302 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; var tests = conf.type === 'win32' ? ['//server', 'C:\\baz\\..', 'bar\\baz', '.'] : ['/foo/bar', '/baz/..', 'bar/baz', '.']; // Force optimization before starting the benchmark p.isAbsolute(tests[0]); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.isAbsolute)'); p.isAbsolute(tests[0]); bench.start(); for (var i = 0; i < n; i++) { runTests(p, tests); } bench.end(n); } function runTests(p, tests) { for (var i = 0; i < tests.length; i++) { p.isAbsolute(tests[i]); } } node-v4.2.6/benchmark/path/join.js000644 000766 000024 00000001177 12650222322 017133 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.join('/foo', 'bar', '', 'baz/asdf', 'quux', '..'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.join)'); p.join('/foo', 'bar', '', 'baz/asdf', 'quux', '..'); bench.start(); for (var i = 0; i < n; i++) { p.join('/foo', 'bar', '', 'baz/asdf', 'quux', '..'); } bench.end(n); } node-v4.2.6/benchmark/path/normalize.js000644 000766 000024 00000001146 12650222322 020170 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.normalize('/foo/bar//baz/asdf/quux/..'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.normalize)'); p.normalize('/foo/bar//baz/asdf/quux/..'); bench.start(); for (var i = 0; i < n; i++) { p.normalize('/foo/bar//baz/asdf/quux/..'); } bench.end(n); } node-v4.2.6/benchmark/path/parse.js000644 000766 000024 00000001166 12650222322 017304 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; var test = conf.type === 'win32' ? 'C:\\path\\dir\\index.html' : '/home/user/dir/index.html'; // Force optimization before starting the benchmark p.parse(test); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.parse)'); p.parse(test); bench.start(); for (var i = 0; i < n; i++) { p.parse(test); } bench.end(n); } node-v4.2.6/benchmark/path/relative.js000644 000766 000024 00000001415 12650222322 020002 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e5], }); function main(conf) { var n = +conf.n; var runTest = conf.type === 'win32' ? runWin32Test : runPosixTest; // Force optimization before starting the benchmark runTest(); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(path[conf.type].relative)'); runTest(); bench.start(); for (var i = 0; i < n; i++) { runTest(); } bench.end(n); } function runWin32Test() { path.win32.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb'); } function runPosixTest() { path.posix.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb'); } node-v4.2.6/benchmark/path/resolve.js000644 000766 000024 00000001221 12650222322 017641 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var path = require('path'); var v8 = require('v8'); var bench = common.createBenchmark(main, { type: ['win32', 'posix'], n: [1e6], }); function main(conf) { var n = +conf.n; var p = path[conf.type]; // Force optimization before starting the benchmark p.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile'); v8.setFlagsFromString('--allow_natives_syntax'); eval('%OptimizeFunctionOnNextCall(p.resolve)'); p.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile'); bench.start(); for (var i = 0; i < n; i++) { p.resolve('foo/bar', '/tmp/file/', '..', 'a/../subfile'); } bench.end(n); } node-v4.2.6/benchmark/net/dgram.js000644 000766 000024 00000002370 12650222322 017114 0ustar00iojsstaff000000 000000 // test UDP send/recv throughput var common = require('../common.js'); var PORT = common.PORT; // `num` is the number of send requests to queue up each time. // Keep it reasonably high (>10) otherwise you're benchmarking the speed of // event loop cycles more than anything else. var bench = common.createBenchmark(main, { len: [1, 64, 256, 1024], num: [100], type: ['send', 'recv'], dur: [5] }); var dur; var len; var num; var type; var chunk; var encoding; function main(conf) { dur = +conf.dur; len = +conf.len; num = +conf.num; type = conf.type; chunk = new Buffer(len); server(); } var dgram = require('dgram'); function server() { var sent = 0; var received = 0; var socket = dgram.createSocket('udp4'); function onsend() { if (sent++ % num == 0) for (var i = 0; i < num; i++) socket.send(chunk, 0, chunk.length, PORT, '127.0.0.1', onsend); } socket.on('listening', function() { bench.start(); onsend(); setTimeout(function() { var bytes = (type === 'send' ? sent : received) * chunk.length; var gbits = (bytes * 8) / (1024 * 1024 * 1024); bench.end(gbits); }, dur * 1000); }); socket.on('message', function(buf, rinfo) { received++; }); socket.bind(PORT); } node-v4.2.6/benchmark/net/net-c2s.js000644 000766 000024 00000004130 12650222322 017271 0ustar00iojsstaff000000 000000 // test the speed of .pipe() with sockets var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5], }); var dur; var len; var type; var chunk; var encoding; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': encoding = 'utf8'; chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': encoding = 'ascii'; chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } server(); } var net = require('net'); function Writer() { this.received = 0; this.writable = true; } Writer.prototype.write = function(chunk, encoding, cb) { this.received += chunk.length; if (typeof encoding === 'function') encoding(); else if (typeof cb === 'function') cb(); return true; }; // doesn't matter, never emits anything. Writer.prototype.on = function() {}; Writer.prototype.once = function() {}; Writer.prototype.emit = function() {}; function Reader() { this.flow = this.flow.bind(this); this.readable = true; } Reader.prototype.pipe = function(dest) { this.dest = dest; this.flow(); return dest; }; Reader.prototype.flow = function() { var dest = this.dest; var res = dest.write(chunk, encoding); if (!res) dest.once('drain', this.flow); else process.nextTick(this.flow); }; function server() { var reader = new Reader(); var writer = new Writer(); // the actual benchmark. var server = net.createServer(function(socket) { socket.pipe(writer); }); server.listen(PORT, function() { var socket = net.connect(PORT); socket.on('connect', function() { bench.start(); reader.pipe(socket); setTimeout(function() { var bytes = writer.received; var gbits = (bytes * 8) / (1024 * 1024 * 1024); bench.end(gbits); }, dur * 1000); }); }); } node-v4.2.6/benchmark/net/net-pipe.js000644 000766 000024 00000004326 12650222322 017546 0ustar00iojsstaff000000 000000 // test the speed of .pipe() with sockets var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5], }); var dur; var len; var type; var chunk; var encoding; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': encoding = 'utf8'; chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': encoding = 'ascii'; chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } server(); } var net = require('net'); function Writer() { this.received = 0; this.writable = true; } Writer.prototype.write = function(chunk, encoding, cb) { this.received += chunk.length; if (typeof encoding === 'function') encoding(); else if (typeof cb === 'function') cb(); return true; }; // doesn't matter, never emits anything. Writer.prototype.on = function() {}; Writer.prototype.once = function() {}; Writer.prototype.emit = function() {}; function Reader() { this.flow = this.flow.bind(this); this.readable = true; } Reader.prototype.pipe = function(dest) { this.dest = dest; this.flow(); return dest; }; Reader.prototype.flow = function() { var dest = this.dest; var res = dest.write(chunk, encoding); if (!res) dest.once('drain', this.flow); else process.nextTick(this.flow); }; function server() { var reader = new Reader(); var writer = new Writer(); // the actual benchmark. var server = net.createServer(function(socket) { socket.pipe(socket); }); server.listen(PORT, function() { var socket = net.connect(PORT); socket.on('connect', function() { bench.start(); reader.pipe(socket); socket.pipe(writer); setTimeout(function() { // multiply by 2 since we're sending it first one way // then then back again. var bytes = writer.received * 2; var gbits = (bytes * 8) / (1024 * 1024 * 1024); bench.end(gbits); }, dur * 1000); }); }); } node-v4.2.6/benchmark/net/net-s2c.js000644 000766 000024 00000004127 12650222322 017277 0ustar00iojsstaff000000 000000 // test the speed of .pipe() with sockets var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5] }); var dur; var len; var type; var chunk; var encoding; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': encoding = 'utf8'; chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': encoding = 'ascii'; chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } server(); } var net = require('net'); function Writer() { this.received = 0; this.writable = true; } Writer.prototype.write = function(chunk, encoding, cb) { this.received += chunk.length; if (typeof encoding === 'function') encoding(); else if (typeof cb === 'function') cb(); return true; }; // doesn't matter, never emits anything. Writer.prototype.on = function() {}; Writer.prototype.once = function() {}; Writer.prototype.emit = function() {}; function Reader() { this.flow = this.flow.bind(this); this.readable = true; } Reader.prototype.pipe = function(dest) { this.dest = dest; this.flow(); return dest; }; Reader.prototype.flow = function() { var dest = this.dest; var res = dest.write(chunk, encoding); if (!res) dest.once('drain', this.flow); else process.nextTick(this.flow); }; function server() { var reader = new Reader(); var writer = new Writer(); // the actual benchmark. var server = net.createServer(function(socket) { reader.pipe(socket); }); server.listen(PORT, function() { var socket = net.connect(PORT); socket.on('connect', function() { bench.start(); socket.pipe(writer); setTimeout(function() { var bytes = writer.received; var gbits = (bytes * 8) / (1024 * 1024 * 1024); bench.end(gbits); }, dur * 1000); }); }); } node-v4.2.6/benchmark/net/tcp-raw-c2s.js000644 000766 000024 00000006044 12650222322 020066 0ustar00iojsstaff000000 000000 // In this benchmark, we connect a client to the server, and write // as many bytes as we can in the specified time (default = 10s) var common = require('../common.js'); var util = require('util'); // if there are --dur=N and --len=N args, then // run the function with those settings. // if not, then queue up a bunch of child processes. var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5] }); var TCP = process.binding('tcp_wrap').TCP; var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap; var WriteWrap = process.binding('stream_wrap').WriteWrap; var PORT = common.PORT; var dur; var len; var type; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; server(); } function fail(err, syscall) { throw util._errnoException(err, syscall); } function server() { var serverHandle = new TCP(); var err = serverHandle.bind('127.0.0.1', PORT); if (err) fail(err, 'bind'); err = serverHandle.listen(511); if (err) fail(err, 'listen'); serverHandle.onconnection = function(err, clientHandle) { if (err) fail(err, 'connect'); // the meat of the benchmark is right here: bench.start(); var bytes = 0; setTimeout(function() { // report in Gb/sec bench.end((bytes * 8) / (1024 * 1024 * 1024)); }, dur * 1000); clientHandle.onread = function(nread, buffer) { // we're not expecting to ever get an EOF from the client. // just lots of data forever. if (nread < 0) fail(nread, 'read'); // don't slice the buffer. the point of this is to isolate, not // simulate real traffic. bytes += buffer.length; }; clientHandle.readStart(); }; client(); } function client() { var chunk; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } var clientHandle = new TCP(); var connectReq = new TCPConnectWrap(); var err = clientHandle.connect(connectReq, '127.0.0.1', PORT); if (err) fail(err, 'connect'); clientHandle.readStart(); connectReq.oncomplete = function(err) { if (err) fail(err, 'connect'); while (clientHandle.writeQueueSize === 0) write(); }; function write() { var writeReq = new WriteWrap(); writeReq.oncomplete = afterWrite; var err; switch (type) { case 'buf': err = clientHandle.writeBuffer(writeReq, chunk); break; case 'utf': err = clientHandle.writeUtf8String(writeReq, chunk); break; case 'asc': err = clientHandle.writeAsciiString(writeReq, chunk); break; } if (err) fail(err, 'write'); } function afterWrite(err, handle, req) { if (err) fail(err, 'write'); while (clientHandle.writeQueueSize === 0) write(); } } node-v4.2.6/benchmark/net/tcp-raw-pipe.js000644 000766 000024 00000006526 12650222322 020341 0ustar00iojsstaff000000 000000 // In this benchmark, we connect a client to the server, and write // as many bytes as we can in the specified time (default = 10s) var common = require('../common.js'); var util = require('util'); // if there are --dur=N and --len=N args, then // run the function with those settings. // if not, then queue up a bunch of child processes. var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5] }); var TCP = process.binding('tcp_wrap').TCP; var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap; var WriteWrap = process.binding('stream_wrap').WriteWrap; var PORT = common.PORT; var dur; var len; var type; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; server(); } function fail(err, syscall) { throw util._errnoException(err, syscall); } function server() { var serverHandle = new TCP(); var err = serverHandle.bind('127.0.0.1', PORT); if (err) fail(err, 'bind'); err = serverHandle.listen(511); if (err) fail(err, 'listen'); serverHandle.onconnection = function(err, clientHandle) { if (err) fail(err, 'connect'); clientHandle.onread = function(nread, buffer) { // we're not expecting to ever get an EOF from the client. // just lots of data forever. if (nread < 0) fail(nread, 'read'); var writeReq = new WriteWrap(); writeReq.async = false; err = clientHandle.writeBuffer(writeReq, buffer); if (err) fail(err, 'write'); writeReq.oncomplete = function(status, handle, req, err) { if (err) fail(err, 'write'); }; }; clientHandle.readStart(); }; client(); } function client() { var chunk; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } var clientHandle = new TCP(); var connectReq = new TCPConnectWrap(); var err = clientHandle.connect(connectReq, '127.0.0.1', PORT); var bytes = 0; if (err) fail(err, 'connect'); clientHandle.readStart(); clientHandle.onread = function(nread, buffer) { if (nread < 0) fail(nread, 'read'); bytes += buffer.length; }; connectReq.oncomplete = function(err) { if (err) fail(err, 'connect'); bench.start(); setTimeout(function() { // multiply by 2 since we're sending it first one way // then then back again. bench.end(2 * (bytes * 8) / (1024 * 1024 * 1024)); }, dur * 1000); while (clientHandle.writeQueueSize === 0) write(); }; function write() { var writeReq = new WriteWrap(); writeReq.oncomplete = afterWrite; var err; switch (type) { case 'buf': err = clientHandle.writeBuffer(writeReq, chunk); break; case 'utf': err = clientHandle.writeUtf8String(writeReq, chunk); break; case 'asc': err = clientHandle.writeAsciiString(writeReq, chunk); break; } if (err) fail(err, 'write'); } function afterWrite(err, handle, req) { if (err) fail(err, 'write'); while (clientHandle.writeQueueSize === 0) write(); } } node-v4.2.6/benchmark/net/tcp-raw-s2c.js000644 000766 000024 00000006376 12650222322 020076 0ustar00iojsstaff000000 000000 // In this benchmark, we connect a client to the server, and write // as many bytes as we can in the specified time (default = 10s) var common = require('../common.js'); var util = require('util'); // if there are dur=N and len=N args, then // run the function with those settings. // if not, then queue up a bunch of child processes. var bench = common.createBenchmark(main, { len: [102400, 1024 * 1024 * 16], type: ['utf', 'asc', 'buf'], dur: [5] }); var TCP = process.binding('tcp_wrap').TCP; var TCPConnectWrap = process.binding('tcp_wrap').TCPConnectWrap; var WriteWrap = process.binding('stream_wrap').WriteWrap; var PORT = common.PORT; var dur; var len; var type; function main(conf) { dur = +conf.dur; len = +conf.len; type = conf.type; server(); } function fail(err, syscall) { throw util._errnoException(err, syscall); } function server() { var serverHandle = new TCP(); var err = serverHandle.bind('127.0.0.1', PORT); if (err) fail(err, 'bind'); err = serverHandle.listen(511); if (err) fail(err, 'listen'); serverHandle.onconnection = function(err, clientHandle) { if (err) fail(err, 'connect'); var chunk; switch (type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': chunk = new Array(len + 1).join('x'); break; default: throw new Error('invalid type: ' + type); break; } clientHandle.readStart(); while (clientHandle.writeQueueSize === 0) write(); function write() { var writeReq = new WriteWrap(); writeReq.async = false; writeReq.oncomplete = afterWrite; var err; switch (type) { case 'buf': err = clientHandle.writeBuffer(writeReq, chunk); break; case 'utf': err = clientHandle.writeUtf8String(writeReq, chunk); break; case 'asc': err = clientHandle.writeAsciiString(writeReq, chunk); break; } if (err) { fail(err, 'write'); } else if (!writeReq.async) { process.nextTick(function() { afterWrite(null, clientHandle, writeReq); }); } } function afterWrite(status, handle, req, err) { if (err) fail(err, 'write'); while (clientHandle.writeQueueSize === 0) write(); } }; client(); } function client() { var clientHandle = new TCP(); var connectReq = new TCPConnectWrap(); var err = clientHandle.connect(connectReq, '127.0.0.1', PORT); if (err) fail(err, 'connect'); connectReq.oncomplete = function() { var bytes = 0; clientHandle.onread = function(nread, buffer) { // we're not expecting to ever get an EOF from the client. // just lots of data forever. if (nread < 0) fail(nread, 'read'); // don't slice the buffer. the point of this is to isolate, not // simulate real traffic. bytes += buffer.length; }; clientHandle.readStart(); // the meat of the benchmark is right here: bench.start(); setTimeout(function() { // report in Gb/sec bench.end((bytes * 8) / (1024 * 1024 * 1024)); }, dur * 1000); }; } node-v4.2.6/benchmark/misc/child-process-read.js000644 000766 000024 00000001177 12650222322 021643 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { len: [64, 256, 1024, 4096, 32768], dur: [5] }); var spawn = require('child_process').spawn; function main(conf) { bench.start(); var dur = +conf.dur; var len = +conf.len; var msg = '"' + Array(len).join('.') + '"'; var options = { 'stdio': ['ignore', 'ipc', 'ignore'] }; var child = spawn('yes', [msg], options); var bytes = 0; child.on('message', function(msg) { bytes += msg.length; }); setTimeout(function() { child.kill(); var gbits = (bytes * 8) / (1024 * 1024 * 1024); bench.end(gbits); }, dur * 1000); } node-v4.2.6/benchmark/misc/domain-fn-args.js000644 000766 000024 00000001277 12650222322 020776 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var domain = require('domain'); var bench = common.createBenchmark(main, { arguments: [0, 1, 2, 3], n: [10] }); var bdomain = domain.create(); var gargs = [1, 2, 3]; function main(conf) { var args, ret, n = +conf.n; var arguments = gargs.slice(0, conf.arguments); bench.start(); bdomain.enter(); for (var i = 0; i < n; i++) { if (arguments.length >= 2) { args = Array.prototype.slice.call(arguments, 1); ret = fn.apply(this, args); } else { ret = fn.call(this); } } bdomain.exit(); bench.end(n); } function fn(a, b, c) { if (!a) a = 1; if (!b) b = 2; if (!c) c = 3; return a + b + c; }node-v4.2.6/benchmark/misc/function_call/000755 000766 000024 00000000000 12650222322 020447 5ustar00iojsstaff000000 000000 node-v4.2.6/benchmark/misc/module-loader.js000644 000766 000024 00000002440 12650222322 020716 0ustar00iojsstaff000000 000000 var fs = require('fs'); var path = require('path'); var common = require('../common.js'); var packageJson = '{"main": "index.js"}'; var tmpDirectory = path.join(__dirname, '..', 'tmp'); var benchmarkDirectory = path.join(tmpDirectory, 'nodejs-benchmark-module'); var bench = common.createBenchmark(main, { thousands: [50] }); function main(conf) { rmrf(tmpDirectory); try { fs.mkdirSync(tmpDirectory); } catch (e) {} try { fs.mkdirSync(benchmarkDirectory); } catch (e) {} var n = +conf.thousands * 1e3; for (var i = 0; i <= n; i++) { fs.mkdirSync(benchmarkDirectory + i); fs.writeFileSync(benchmarkDirectory + i + '/package.json', '{"main": "index.js"}'); fs.writeFileSync(benchmarkDirectory + i + '/index.js', 'module.exports = "";'); } measure(n); } function measure(n) { bench.start(); for (var i = 0; i <= n; i++) { require(benchmarkDirectory + i); } bench.end(n / 1e3); } function rmrf(location) { try { var things = fs.readdirSync(location); things.forEach(function(thing) { var cur = path.join(location, thing), isDirectory = fs.statSync(cur).isDirectory(); if (isDirectory) { rmrf(cur); return; } fs.unlinkSync(cur); }); fs.rmdirSync(location); } catch (err) { // Ignore error } } node-v4.2.6/benchmark/misc/next-tick-breadth-args.js000644 000766 000024 00000001237 12650222322 022437 0ustar00iojsstaff000000 000000 'use strict'; var common = require('../common.js'); var bench = common.createBenchmark(main, { millions: [2] }); function main(conf) { var N = +conf.millions * 1e6; var n = 0; function cb1(arg1) { n++; if (n === N) bench.end(n / 1e6); } function cb2(arg1, arg2) { n++; if (n === N) bench.end(n / 1e6); } function cb3(arg1, arg2, arg3) { n++; if (n === N) bench.end(n / 1e6); } bench.start(); for (var i = 0; i < N; i++) { if (i % 3 === 0) process.nextTick(cb3, 512, true, null); else if (i % 2 === 0) process.nextTick(cb2, false, 5.1); else process.nextTick(cb1, 0); } } node-v4.2.6/benchmark/misc/next-tick-breadth.js000644 000766 000024 00000000507 12650222322 021504 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { millions: [2] }); function main(conf) { var N = +conf.millions * 1e6; var n = 0; function cb() { n++; if (n === N) bench.end(n / 1e6); } bench.start(); for (var i = 0; i < N; i++) { process.nextTick(cb); } } node-v4.2.6/benchmark/misc/next-tick-depth-args.js000644 000766 000024 00000002105 12650222322 022125 0ustar00iojsstaff000000 000000 'use strict'; var common = require('../common.js'); var bench = common.createBenchmark(main, { millions: [2] }); process.maxTickDepth = Infinity; function main(conf) { var n = +conf.millions * 1e6; function cb3(arg1, arg2, arg3) { if (--n) { if (n % 3 === 0) process.nextTick(cb3, 512, true, null); else if (n % 2 === 0) process.nextTick(cb2, false, 5.1); else process.nextTick(cb1, 0); } else bench.end(+conf.millions); } function cb2(arg1, arg2) { if (--n) { if (n % 3 === 0) process.nextTick(cb3, 512, true, null); else if (n % 2 === 0) process.nextTick(cb2, false, 5.1); else process.nextTick(cb1, 0); } else bench.end(+conf.millions); } function cb1(arg1) { if (--n) { if (n % 3 === 0) process.nextTick(cb3, 512, true, null); else if (n % 2 === 0) process.nextTick(cb2, false, 5.1); else process.nextTick(cb1, 0); } else bench.end(+conf.millions); } bench.start(); process.nextTick(cb1, true); } node-v4.2.6/benchmark/misc/next-tick-depth.js000644 000766 000024 00000000553 12650222322 021200 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { millions: [2] }); process.maxTickDepth = Infinity; function main(conf) { var n = +conf.millions * 1e6; bench.start(); process.nextTick(onNextTick); function onNextTick() { if (--n) process.nextTick(onNextTick); else bench.end(+conf.millions); } } node-v4.2.6/benchmark/misc/spawn-echo.js000644 000766 000024 00000000717 12650222322 020236 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { thousands: [1] }); var spawn = require('child_process').spawn; function main(conf) { var len = +conf.thousands * 1000; bench.start(); go(len, len); } function go(n, left) { if (--left === 0) return bench.end(n); var child = spawn('echo', ['hello']); child.on('exit', function(code) { if (code) process.exit(code); else go(n, left); }); } node-v4.2.6/benchmark/misc/startup.js000644 000766 000024 00000001454 12650222322 017673 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var spawn = require('child_process').spawn; var path = require('path'); var emptyJsFile = path.resolve(__dirname, '../../test/fixtures/semicolon.js'); var starts = 100; var i = 0; var start; var bench = common.createBenchmark(startNode, { dur: [1] }); function startNode(conf) { var dur = +conf.dur; var go = true; var starts = 0; var open = 0; setTimeout(function() { go = false; }, dur * 1000); bench.start(); start(); function start() { var node = spawn(process.execPath || process.argv[0], [emptyJsFile]); node.on('exit', function(exitCode) { if (exitCode !== 0) { throw new Error('Error during node startup'); } starts++; if (go) start(); else bench.end(starts); }); } } node-v4.2.6/benchmark/misc/string-creation.js000644 000766 000024 00000000433 12650222322 021275 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { millions: [100] }) function main(conf) { var n = +conf.millions * 1e6; bench.start(); var s; for (var i = 0; i < n; i++) { s = '01234567890'; s[1] = "a"; } bench.end(n / 1e6); } node-v4.2.6/benchmark/misc/string-decoder.js000644 000766 000024 00000003063 12650222322 021100 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var StringDecoder = require('string_decoder').StringDecoder; var bench = common.createBenchmark(main, { encoding: ['ascii', 'utf8', 'base64-utf8', 'base64-ascii'], inlen: [32, 128, 1024], chunk: [16, 64, 256, 1024], n: [25e4] }); var UTF_ALPHA = 'Blbrsyltety'; var ASC_ALPHA = 'Blueberry jam'; function main(conf) { var encoding = conf.encoding; var inLen = conf.inlen | 0; var chunkLen = conf.chunk | 0; var n = conf.n | 0; var alpha; var chunks = []; var str = ''; var isBase64 = (encoding === 'base64-ascii' || encoding === 'base64-utf8'); if (encoding === 'ascii' || encoding === 'base64-ascii') alpha = ASC_ALPHA; else if (encoding === 'utf8' || encoding === 'base64-utf8') alpha = UTF_ALPHA; else throw new Error('Bad encoding'); var sd = new StringDecoder(isBase64 ? 'base64' : encoding); for (var i = 0; i < inLen; ++i) { if (i > 0 && (i % chunkLen) === 0 && !isBase64) { chunks.push(new Buffer(str, encoding)); str = ''; } str += alpha[i % alpha.length]; } if (str.length > 0 && !isBase64) chunks.push(new Buffer(str, encoding)); if (isBase64) { str = new Buffer(str, 'utf8').toString('base64'); while (str.length > 0) { var len = Math.min(chunkLen, str.length); chunks.push(new Buffer(str.substring(0, len), 'utf8')); str = str.substring(len); } } var nChunks = chunks.length; bench.start(); for (var i = 0; i < n; ++i) { for (var j = 0; j < nChunks; ++j) sd.write(chunks[j]); } bench.end(n); } node-v4.2.6/benchmark/misc/timers.js000644 000766 000024 00000001156 12650222322 017473 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { thousands: [500], type: ['depth', 'breadth'] }); function main(conf) { var n = +conf.thousands * 1e3; if (conf.type === 'breadth') breadth(n); else depth(n); } function depth(N) { var n = 0; bench.start(); setTimeout(cb); function cb() { n++; if (n === N) bench.end(N / 1e3); else setTimeout(cb); } } function breadth(N) { var n = 0; bench.start(); function cb() { n++; if (n === N) bench.end(N / 1e3); } for (var i = 0; i < N; i++) { setTimeout(cb); } } node-v4.2.6/benchmark/misc/url.js000644 000766 000024 00000001724 12650222322 016773 0ustar00iojsstaff000000 000000 var url = require('url') var n = 25 * 100; var urls = [ 'http://nodejs.org/docs/latest/api/url.html#url_url_format_urlobj', 'http://blog.nodejs.org/', 'https://encrypted.google.com/search?q=url&q=site:npmjs.org&hl=en', 'javascript:alert("node is awesome");', 'some.ran/dom/url.thing?oh=yes#whoo' ]; var paths = [ '../foo/bar?baz=boom', 'foo/bar', 'http://nodejs.org', './foo/bar?baz' ]; benchmark('parse()', url.parse); benchmark('format()', url.format); paths.forEach(function(p) { benchmark('resolve("' + p + '")', function(u) { url.resolve(u, p) }); }); function benchmark(name, fun) { var timestamp = process.hrtime(); for (var i = 0; i < n; ++i) { for (var j = 0, k = urls.length; j < k; ++j) fun(urls[j]); } timestamp = process.hrtime(timestamp); var seconds = timestamp[0]; var nanos = timestamp[1]; var time = seconds + nanos / 1e9; var rate = n / time; console.log('misc/url.js %s: %s', name, rate.toPrecision(5)); } node-v4.2.6/benchmark/misc/v8-bench.js000644 000766 000024 00000001264 12650222322 017602 0ustar00iojsstaff000000 000000 // compare with "google-chrome deps/v8/benchmarks/run.html" var fs = require('fs'); var path = require('path'); var vm = require('vm'); var dir = path.join(__dirname, '..', '..', 'deps', 'v8', 'benchmarks'); global.print = function(s) { if (s === '----') return; console.log('misc/v8_bench.js %s', s); }; global.load = function(filename) { var source = fs.readFileSync(path.join(dir, filename), 'utf8'); // deps/v8/benchmarks/regexp.js breaks console.log() because it clobbers // the RegExp global, Restore the original when the script is done. var $RegExp = global.RegExp; vm.runInThisContext(source, { filename: filename }); global.RegExp = $RegExp; }; load('run.js'); node-v4.2.6/benchmark/misc/function_call/.gitignore000644 000766 000024 00000000007 12650222322 022434 0ustar00iojsstaff000000 000000 build/ node-v4.2.6/benchmark/misc/function_call/binding.cc000644 000766 000024 00000000512 12650222322 022366 0ustar00iojsstaff000000 000000 #include #include using namespace v8; static int c = 0; void Hello(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(c++); } extern "C" void init (Local target) { HandleScope scope(Isolate::GetCurrent()); NODE_SET_METHOD(target, "hello", Hello); } NODE_MODULE(binding, init); node-v4.2.6/benchmark/misc/function_call/binding.gyp000644 000766 000024 00000000145 12650222322 022602 0ustar00iojsstaff000000 000000 { 'targets': [ { 'target_name': 'binding', 'sources': [ 'binding.cc' ] } ] } node-v4.2.6/benchmark/misc/function_call/index.js000644 000766 000024 00000001720 12650222322 022114 0ustar00iojsstaff000000 000000 // show the difference between calling a short js function // relative to a comparable C++ function. // Reports millions of calls per second. // Note that JS speed goes up, while cxx speed stays about the same. var assert = require('assert'); var common = require('../../common.js'); // this fails when we try to open with a different version of node, // which is quite common for benchmarks. so in that case, just // abort quietly. try { var binding = require('./build/Release/binding'); } catch (er) { console.error('misc/function_call.js Binding failed to load'); process.exit(0); } var cxx = binding.hello; var c = 0; function js() { return c++; } assert(js() === cxx()); var bench = common.createBenchmark(main, { type: ['js', 'cxx'], millions: [1,10,50] }); function main(conf) { var n = +conf.millions * 1e6; var fn = conf.type === 'cxx' ? cxx : js; bench.start(); for (var i = 0; i < n; i++) { fn(); } bench.end(+conf.millions); } node-v4.2.6/benchmark/misc/function_call/Makefile000644 000766 000024 00000000056 12650222322 022110 0ustar00iojsstaff000000 000000 binding: node-gyp rebuild --nodedir=../../.. node-v4.2.6/benchmark/http/_chunky_http_client.js000644 000766 000024 00000006006 12650222322 022250 0ustar00iojsstaff000000 000000 'use strict'; // test HTTP throughput in fragmented header case var common = require('../common.js'); var net = require('net'); var test = require('../../test/common.js'); var bench = common.createBenchmark(main, { len: [1, 4, 8, 16, 32, 64, 128], num: [5, 50, 500, 2000], type: ['send'], }); function main(conf) { var len = +conf.len; var num = +conf.num; var type = conf.type; var todo = []; var headers = []; // Chose 7 because 9 showed "Connection error" / "Connection closed" // An odd number could result in a better length dispersion. for (var i = 7; i <= 7 * 7 * 7; i *= 7) headers.push(Array(i + 1).join('o')); function WriteHTTPHeaders(channel, has_keep_alive, extra_header_count) { todo = [] todo.push('GET / HTTP/1.1'); todo.push('Host: localhost'); todo.push('Connection: keep-alive'); todo.push('Accept: text/html,application/xhtml+xml,' + 'application/xml;q=0.9,image/webp,*/*;q=0.8'); todo.push('User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' + 'AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Chrome/39.0.2171.71 Safari/537.36'); todo.push('Accept-Encoding: gzip, deflate, sdch'); todo.push('Accept-Language: en-US,en;q=0.8'); for (var i = 0; i < extra_header_count; i++) { // Utilize first three powers of a small integer for an odd cycle and // because the fourth power of some integers overloads the server. todo.push('X-Header-' + i + ': ' + headers[i % 3]); } todo.push(''); todo.push(''); todo = todo.join('\r\n'); // Using odd numbers in many places may increase length coverage. var chunksize = 37; for (i = 0; i < todo.length; i += chunksize) { var cur = todo.slice(i, i + chunksize); channel.write(cur); } } var success = 0; var failure = 0; var min = 10; var size = 0; var mod = 317; var mult = 17; var add = 11; var count = 0; var PIPE = test.PIPE; var socket = net.connect(PIPE, function() { bench.start(); WriteHTTPHeaders(socket, 1, len); socket.setEncoding('utf8') socket.on('data', function(d) { var did = false; var pattern = 'HTTP/1.1 200 OK\r\n'; if ((d.length === pattern.length && d === pattern) || (d.length > pattern.length && d.slice(0, pattern.length) === pattern)) { success += 1; did = true; } else { pattern = 'HTTP/1.1 ' if ((d.length === pattern.length && d === pattern) || (d.length > pattern.length && d.slice(0, pattern.length) === pattern)) { failure += 1; did = true; } } size = (size * mult + add) % mod; if (did) { count += 1; if (count === num) { bench.end(count); } else { WriteHTTPHeaders(socket, 1, min + size); } } }); socket.on('close', function() { console.log('Connection closed'); }); socket.on('error', function() { throw new Error('Connection error'); }); }); } node-v4.2.6/benchmark/http/chunked.js000644 000766 000024 00000002002 12650222322 017624 0ustar00iojsstaff000000 000000 // When calling .end(buffer) right away, this triggers a "hot path" // optimization in http.js, to avoid an extra write call. // // However, the overhead of copying a large buffer is higher than // the overhead of an extra write() call, so the hot path was not // always as hot as it could be. // // Verify that our assumptions are valid. var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { num: [1, 4, 8, 16], size: [1, 64, 256], c: [100] }); function main(conf) { http = require('http'); var chunk = new Buffer(conf.size); chunk.fill('8'); var args = ['-d', '10s', '-t', 8, '-c', conf.c]; var server = http.createServer(function(req, res) { function send(left) { if (left === 0) return res.end(); res.write(chunk); setTimeout(function() { send(left - 1); }, 0); } send(conf.num); }); server.listen(common.PORT, function() { bench.http('/', args, function() { server.close(); }); }); } node-v4.2.6/benchmark/http/client-request-body.js000644 000766 000024 00000002677 12650222322 022124 0ustar00iojsstaff000000 000000 // Measure the time it takes for the HTTP client to send a request body. var common = require('../common.js'); var http = require('http'); var bench = common.createBenchmark(main, { dur: [5], type: ['asc', 'utf', 'buf'], bytes: [32, 256, 1024], method: ['write', 'end'] }); function main(conf) { var dur = +conf.dur; var len = +conf.bytes; var encoding; var chunk; switch (conf.type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': encoding = 'utf8'; chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': chunk = new Array(len + 1).join('a'); break; } var nreqs = 0; var options = { headers: { 'Connection': 'keep-alive', 'Transfer-Encoding': 'chunked' }, agent: new http.Agent({ maxSockets: 1 }), host: '127.0.0.1', port: common.PORT, path: '/', method: 'POST' }; var server = http.createServer(function(req, res) { res.end(); }); server.listen(options.port, options.host, function() { setTimeout(done, dur * 1000); bench.start(); pummel(); }); function pummel() { var req = http.request(options, function(res) { nreqs++; pummel(); // Line up next request. res.resume(); }); if (conf.method === 'write') { req.write(chunk, encoding); req.end(); } else { req.end(chunk, encoding); } } function done() { bench.end(nreqs); } } node-v4.2.6/benchmark/http/cluster.js000644 000766 000024 00000001437 12650222322 017677 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var PORT = common.PORT; var cluster = require('cluster'); if (cluster.isMaster) { var bench = common.createBenchmark(main, { // unicode confuses ab on os x. type: ['bytes', 'buffer'], length: [4, 1024, 102400], c: [50, 500] }); } else { require('../http_simple.js'); } function main(conf) { process.env.PORT = PORT; var workers = 0; var w1 = cluster.fork(); var w2 = cluster.fork(); cluster.on('listening', function() { workers++; if (workers < 2) return; setTimeout(function() { var path = '/' + conf.type + '/' + conf.length; var args = ['-d', '10s', '-t', 8, '-c', conf.c]; bench.http(path, args, function() { w1.destroy(); w2.destroy(); }); }, 100); }); } node-v4.2.6/benchmark/http/end-vs-write-end.js000644 000766 000024 00000002475 12650222322 021311 0ustar00iojsstaff000000 000000 // When calling .end(buffer) right away, this triggers a "hot path" // optimization in http.js, to avoid an extra write call. // // However, the overhead of copying a large buffer is higher than // the overhead of an extra write() call, so the hot path was not // always as hot as it could be. // // Verify that our assumptions are valid. var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { type: ['asc', 'utf', 'buf'], kb: [64, 128, 256, 1024], c: [100], method: ['write', 'end'] }); function main(conf) { http = require('http'); var chunk; var len = conf.kb * 1024; switch (conf.type) { case 'buf': chunk = new Buffer(len); chunk.fill('x'); break; case 'utf': encoding = 'utf8'; chunk = new Array(len / 2 + 1).join('ü'); break; case 'asc': chunk = new Array(len + 1).join('a'); break; } function write(res) { res.write(chunk); res.end(); } function end(res) { res.end(chunk); } var method = conf.method === 'write' ? write : end; var args = ['-d', '10s', '-t', 8, '-c', conf.c]; var server = http.createServer(function(req, res) { method(res); }); server.listen(common.PORT, function() { bench.http('/', args, function() { server.close(); }); }); } node-v4.2.6/benchmark/http/http_server_for_chunky_client.js000644 000766 000024 00000002117 12650222322 024344 0ustar00iojsstaff000000 000000 'use strict'; var path = require('path'); var http = require('http'); var fs = require('fs'); var spawn = require('child_process').spawn; var common = require('../common.js') var test = require('../../test/common.js') var pep = path.dirname(process.argv[1]) + '/_chunky_http_client.js'; var PIPE = test.PIPE; try { fs.accessSync(test.tmpDir, fs.F_OK); } catch (e) { fs.mkdirSync(test.tmpDir); } var server; try { fs.unlinkSync(PIPE); } catch (e) { /* ignore */ } server = http.createServer(function(req, res) { res.writeHead(200, { 'content-type': 'text/plain', 'content-length': '2' }); res.end('ok'); }); server.on('error', function(err) { throw new Error('server error: ' + err); }); try { var child; server.listen(PIPE); child = spawn(process.execPath, [pep], { }); child.on('error', function(err) { throw new Error('spawn error: ' + err ); }); child.stdout.pipe(process.stdout); child.stderr.pipe(process.stderr); child.on('close', function (exitCode) { server.close(); }); } catch(e) { throw new Error('error: ' + e ); } node-v4.2.6/benchmark/http/simple.js000644 000766 000024 00000001221 12650222322 017476 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var PORT = common.PORT; var bench = common.createBenchmark(main, { // unicode confuses ab on os x. type: ['bytes', 'buffer'], length: [4, 1024, 102400], chunks: [0, 1, 4], // chunks=0 means 'no chunked encoding'. c: [50, 500] }); function main(conf) { process.env.PORT = PORT; var spawn = require('child_process').spawn; var server = require('../http_simple.js'); setTimeout(function() { var path = '/' + conf.type + '/' + conf.length + '/' + conf.chunks; var args = ['-d', '10s', '-t', 8, '-c', conf.c]; bench.http(path, args, function() { server.close(); }); }, 2000); } node-v4.2.6/benchmark/fs/read-stream-throughput.js000644 000766 000024 00000003366 12650222322 022265 0ustar00iojsstaff000000 000000 // test the throughput of the fs.WriteStream class. var path = require('path'); var common = require('../common.js'); var filename = path.resolve(__dirname, '.removeme-benchmark-garbage'); var fs = require('fs'); var filesize = 1000 * 1024 * 1024; var assert = require('assert'); var type, encoding, size; var bench = common.createBenchmark(main, { type: ['buf', 'asc', 'utf'], size: [1024, 4096, 65535, 1024*1024] }); function main(conf) { type = conf.type; size = +conf.size; switch (type) { case 'buf': encoding = null; break; case 'asc': encoding = 'ascii'; break; case 'utf': encoding = 'utf8'; break; default: throw new Error('invalid type'); } makeFile(runTest); } function runTest() { assert(fs.statSync(filename).size === filesize); var rs = fs.createReadStream(filename, { highWaterMark: size, encoding: encoding }); rs.on('open', function() { bench.start(); }); var bytes = 0; rs.on('data', function(chunk) { bytes += chunk.length; }); rs.on('end', function() { try { fs.unlinkSync(filename); } catch (e) {} // MB/sec bench.end(bytes / (1024 * 1024)); }); } function makeFile() { var buf = new Buffer(filesize / 1024); if (encoding === 'utf8') { // ü for (var i = 0; i < buf.length; i++) { buf[i] = i % 2 === 0 ? 0xC3 : 0xBC; } } else if (encoding === 'ascii') { buf.fill('a'); } else { buf.fill('x'); } try { fs.unlinkSync(filename); } catch (e) {} var w = 1024; var ws = fs.createWriteStream(filename); ws.on('close', runTest); ws.on('drain', write); write(); function write() { do { w--; } while (false !== ws.write(buf) && w > 0); if (w === 0) ws.end(); } } node-v4.2.6/benchmark/fs/readfile.js000644 000766 000024 00000002074 12650222322 017420 0ustar00iojsstaff000000 000000 // Call fs.readFile over and over again really fast. // Then see how many times it got called. // Yes, this is a silly benchmark. Most benchmarks are silly. var path = require('path'); var common = require('../common.js'); var filename = path.resolve(__dirname, '.removeme-benchmark-garbage'); var fs = require('fs'); var bench = common.createBenchmark(main, { dur: [5], len: [1024, 16 * 1024 * 1024], concurrent: [1, 10] }); function main(conf) { var len = +conf.len; try { fs.unlinkSync(filename); } catch (e) {} var data = new Buffer(len); data.fill('x'); fs.writeFileSync(filename, data); data = null; var reads = 0; bench.start(); setTimeout(function() { bench.end(reads); try { fs.unlinkSync(filename); } catch (e) {} }, +conf.dur * 1000); function read() { fs.readFile(filename, afterRead); } function afterRead(er, data) { if (er) throw er; if (data.length !== len) throw new Error('wrong number of bytes returned'); reads++; read(); } var cur = +conf.concurrent; while (cur--) read(); } node-v4.2.6/benchmark/fs/write-stream-throughput.js000644 000766 000024 00000003221 12650222322 022472 0ustar00iojsstaff000000 000000 // test the throughput of the fs.WriteStream class. var path = require('path'); var common = require('../common.js'); var filename = path.resolve(__dirname, '.removeme-benchmark-garbage'); var fs = require('fs'); var bench = common.createBenchmark(main, { dur: [5], type: ['buf', 'asc', 'utf'], size: [2, 1024, 65535, 1024 * 1024] }); function main(conf) { var dur = +conf.dur; var type = conf.type; var size = +conf.size; var encoding; var chunk; switch (type) { case 'buf': chunk = new Buffer(size); chunk.fill('b'); break; case 'asc': chunk = new Array(size + 1).join('a'); encoding = 'ascii'; break; case 'utf': chunk = new Array(Math.ceil(size/2) + 1).join('ü'); encoding = 'utf8'; break; default: throw new Error('invalid type'); } try { fs.unlinkSync(filename); } catch (e) {} var started = false; var ending = false; var ended = false; setTimeout(function() { ending = true; f.end(); }, dur * 1000); var f = fs.createWriteStream(filename); f.on('drain', write); f.on('open', write); f.on('close', done); f.on('finish', function() { ended = true; var written = fs.statSync(filename).size / 1024; try { fs.unlinkSync(filename); } catch (e) {} bench.end(written / 1024); }); function write() { // don't try to write after we end, even if a 'drain' event comes. // v0.8 streams are so sloppy! if (ending) return; if (!started) { started = true; bench.start(); } while (false !== f.write(chunk, encoding)); } function done() { if (!ended) f.emit('finish'); } } node-v4.2.6/benchmark/events/ee-add-remove.js000644 000766 000024 00000001101 12650222322 021141 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var events = require('events'); var bench = common.createBenchmark(main, {n: [25e4]}); function main(conf) { var n = conf.n | 0; var ee = new events.EventEmitter(); var listeners = []; for (var k = 0; k < 10; k += 1) listeners.push(function() {}); bench.start(); for (var i = 0; i < n; i += 1) { for (var k = listeners.length; --k >= 0; /* empty */) ee.on('dummy', listeners[k]); for (var k = listeners.length; --k >= 0; /* empty */) ee.removeListener('dummy', listeners[k]); } bench.end(n); } node-v4.2.6/benchmark/events/ee-emit-multi-args.js000644 000766 000024 00000000643 12650222322 022150 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var EventEmitter = require('events').EventEmitter; var bench = common.createBenchmark(main, {n: [2e6]}); function main(conf) { var n = conf.n | 0; var ee = new EventEmitter(); var listeners = []; for (var k = 0; k < 10; k += 1) ee.on('dummy', function() {}); bench.start(); for (var i = 0; i < n; i += 1) { ee.emit('dummy', 5, true); } bench.end(n); } node-v4.2.6/benchmark/events/ee-emit.js000644 000766 000024 00000000604 12650222322 020063 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var EventEmitter = require('events').EventEmitter; var bench = common.createBenchmark(main, {n: [2e6]}); function main(conf) { var n = conf.n | 0; var ee = new EventEmitter(); for (var k = 0; k < 10; k += 1) ee.on('dummy', function() {}); bench.start(); for (var i = 0; i < n; i += 1) { ee.emit('dummy'); } bench.end(n); } node-v4.2.6/benchmark/events/ee-listener-count-on-prototype.js000644 000766 000024 00000000625 12650222322 024560 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var EventEmitter = require('events').EventEmitter; var bench = common.createBenchmark(main, {n: [5e7]}); function main(conf) { var n = conf.n | 0; var ee = new EventEmitter(); for (var k = 0; k < 10; k += 1) ee.on('dummy', function() {}); bench.start(); for (var i = 0; i < n; i += 1) { var r = ee.listenerCount('dummy'); } bench.end(n); } node-v4.2.6/benchmark/events/ee-listeners-many.js000644 000766 000024 00000000655 12650222322 022105 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var EventEmitter = require('events').EventEmitter; var bench = common.createBenchmark(main, {n: [5e6]}); function main(conf) { var n = conf.n | 0; var ee = new EventEmitter(); ee.setMaxListeners(101); for (var k = 0; k < 100; k += 1) ee.on('dummy', function() {}); bench.start(); for (var i = 0; i < n; i += 1) { var r = ee.listeners('dummy'); } bench.end(n); } node-v4.2.6/benchmark/events/ee-listeners.js000644 000766 000024 00000000621 12650222322 021134 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var EventEmitter = require('events').EventEmitter; var bench = common.createBenchmark(main, {n: [5e6]}); function main(conf) { var n = conf.n | 0; var ee = new EventEmitter(); for (var k = 0; k < 10; k += 1) ee.on('dummy', function() {}); bench.start(); for (var i = 0; i < n; i += 1) { var r = ee.listeners('dummy'); } bench.end(n); } node-v4.2.6/benchmark/crypto/aes-gcm-throughput.js000644 000766 000024 00000002262 12650222322 022277 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var crypto = require('crypto'); var keylen = {'aes-128-gcm': 16, 'aes-192-gcm': 24, 'aes-256-gcm': 32}; var bench = common.createBenchmark(main, { n: [500], cipher: ['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'], len: [1024, 4 * 1024, 16 * 1024, 64 * 1024, 256 * 1024, 1024 * 1024] }); function main(conf) { var message = (new Buffer(conf.len)).fill('b'); var key = crypto.randomBytes(keylen[conf.cipher]); var iv = crypto.randomBytes(12); var associate_data = (new Buffer(16)).fill('z'); bench.start(); AEAD_Bench(conf.cipher, message, associate_data, key, iv, conf.n, conf.len); } function AEAD_Bench(cipher, message, associate_data, key, iv, n, len) { var written = n * len; var bits = written * 8; var mbits = bits / (1024 * 1024); for (var i = 0; i < n; i++) { var alice = crypto.createCipheriv(cipher, key, iv); alice.setAAD(associate_data); var enc = alice.update(message); alice.final(); var tag = alice.getAuthTag(); var bob = crypto.createDecipheriv(cipher, key, iv); bob.setAuthTag(tag); bob.setAAD(associate_data); var clear = bob.update(enc); bob.final(); } bench.end(mbits); } node-v4.2.6/benchmark/crypto/cipher-stream.js000644 000766 000024 00000005166 12650222322 021325 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { writes: [500], cipher: [ 'AES192', 'AES256' ], type: ['asc', 'utf', 'buf'], len: [2, 1024, 102400, 1024 * 1024], api: ['legacy', 'stream'] }); function main(conf) { var api = conf.api; if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) { console.error('Crypto streams not available until v0.10'); // use the legacy, just so that we can compare them. api = 'legacy'; } var crypto = require('crypto'); var assert = require('assert'); var alice = crypto.getDiffieHellman('modp5'); var bob = crypto.getDiffieHellman('modp5'); alice.generateKeys(); bob.generateKeys(); var pubEnc = /^v0\.[0-8]/.test(process.version) ? 'binary' : null; var alice_secret = alice.computeSecret(bob.getPublicKey(), pubEnc, 'hex'); var bob_secret = bob.computeSecret(alice.getPublicKey(), pubEnc, 'hex'); // alice_secret and bob_secret should be the same assert(alice_secret == bob_secret); var alice_cipher = crypto.createCipher(conf.cipher, alice_secret); var bob_cipher = crypto.createDecipher(conf.cipher, bob_secret); var message; var encoding; switch (conf.type) { case 'asc': message = new Array(conf.len + 1).join('a'); encoding = 'ascii'; break; case 'utf': message = new Array(conf.len / 2 + 1).join('ü'); encoding = 'utf8'; break; case 'buf': message = new Buffer(conf.len); message.fill('b'); break; default: throw new Error('unknown message type: ' + conf.type); } var fn = api === 'stream' ? streamWrite : legacyWrite; // write data as fast as possible to alice, and have bob decrypt. // use old API for comparison to v0.8 bench.start(); fn(alice_cipher, bob_cipher, message, encoding, conf.writes); } function streamWrite(alice, bob, message, encoding, writes) { var written = 0; bob.on('data', function(c) { written += c.length; }); bob.on('end', function() { // Gbits var bits = written * 8; var gbits = bits / (1024 * 1024 * 1024); bench.end(gbits); }); alice.pipe(bob); while (writes-- > 0) alice.write(message, encoding); alice.end(); } function legacyWrite(alice, bob, message, encoding, writes) { var written = 0; for (var i = 0; i < writes; i++) { var enc = alice.update(message, encoding); var dec = bob.update(enc); written += dec.length; } var enc = alice.final(); var dec = bob.update(enc); written += dec.length; dec = bob.final(); written += dec.length; var bits = written * 8; var gbits = written / (1024 * 1024 * 1024); bench.end(gbits); } node-v4.2.6/benchmark/crypto/hash-stream-creation.js000644 000766 000024 00000004154 12650222322 022574 0ustar00iojsstaff000000 000000 // throughput benchmark // creates a single hasher, then pushes a bunch of data through it var common = require('../common.js'); var crypto = require('crypto'); var bench = common.createBenchmark(main, { writes: [500], algo: [ 'sha256', 'md5' ], type: ['asc', 'utf', 'buf'], out: ['hex', 'binary', 'buffer'], len: [2, 1024, 102400, 1024 * 1024], api: ['legacy', 'stream'] }); function main(conf) { var api = conf.api; if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) { console.error('Crypto streams not available until v0.10'); // use the legacy, just so that we can compare them. api = 'legacy'; } var crypto = require('crypto'); var assert = require('assert'); var message; var encoding; switch (conf.type) { case 'asc': message = new Array(conf.len + 1).join('a'); encoding = 'ascii'; break; case 'utf': message = new Array(conf.len / 2 + 1).join('ü'); encoding = 'utf8'; break; case 'buf': message = new Buffer(conf.len); message.fill('b'); break; default: throw new Error('unknown message type: ' + conf.type); } var fn = api === 'stream' ? streamWrite : legacyWrite; bench.start(); fn(conf.algo, message, encoding, conf.writes, conf.len, conf.out); } function legacyWrite(algo, message, encoding, writes, len, outEnc) { var written = writes * len; var bits = written * 8; var gbits = bits / (1024 * 1024 * 1024); while (writes-- > 0) { var h = crypto.createHash(algo); h.update(message, encoding); var res = h.digest(outEnc); // include buffer creation costs for older versions if (outEnc === 'buffer' && typeof res === 'string') res = new Buffer(res, 'binary'); } bench.end(gbits); } function streamWrite(algo, message, encoding, writes, len, outEnc) { var written = writes * len; var bits = written * 8; var gbits = bits / (1024 * 1024 * 1024); while (writes-- > 0) { var h = crypto.createHash(algo); if (outEnc !== 'buffer') h.setEncoding(outEnc); h.write(message, encoding); h.end(); h.read(); } bench.end(gbits); } node-v4.2.6/benchmark/crypto/hash-stream-throughput.js000644 000766 000024 00000003477 12650222322 023210 0ustar00iojsstaff000000 000000 // throughput benchmark // creates a single hasher, then pushes a bunch of data through it var common = require('../common.js'); var crypto = require('crypto'); var bench = common.createBenchmark(main, { writes: [500], algo: ['sha1', 'sha256', 'sha512'], type: ['asc', 'utf', 'buf'], len: [2, 1024, 102400, 1024 * 1024], api: ['legacy', 'stream'] }); function main(conf) { var api = conf.api; if (api === 'stream' && process.version.match(/^v0\.[0-8]\./)) { console.error('Crypto streams not available until v0.10'); // use the legacy, just so that we can compare them. api = 'legacy'; } var crypto = require('crypto'); var assert = require('assert'); var message; var encoding; switch (conf.type) { case 'asc': message = new Array(conf.len + 1).join('a'); encoding = 'ascii'; break; case 'utf': message = new Array(conf.len / 2 + 1).join('ü'); encoding = 'utf8'; break; case 'buf': message = new Buffer(conf.len); message.fill('b'); break; default: throw new Error('unknown message type: ' + conf.type); } var fn = api === 'stream' ? streamWrite : legacyWrite; bench.start(); fn(conf.algo, message, encoding, conf.writes, conf.len); } function legacyWrite(algo, message, encoding, writes, len) { var written = writes * len; var bits = written * 8; var gbits = bits / (1024 * 1024 * 1024); var h = crypto.createHash(algo); while (writes-- > 0) h.update(message, encoding); h.digest(); bench.end(gbits); } function streamWrite(algo, message, encoding, writes, len) { var written = writes * len; var bits = written * 8; var gbits = bits / (1024 * 1024 * 1024); var h = crypto.createHash(algo); while (writes-- > 0) h.write(message, encoding); h.end(); h.read(); bench.end(gbits); } node-v4.2.6/benchmark/crypto/rsa-encrypt-decrypt-throughput.js000644 000766 000024 00000002457 12650222322 024710 0ustar00iojsstaff000000 000000 // throughput benchmark in signing and verifying var common = require('../common.js'); var crypto = require('crypto'); var fs = require('fs'); var path = require('path'); var fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/'); var keylen_list = ['1024', '2048', '4096']; var RSA_PublicPem = {}; var RSA_PrivatePem = {}; keylen_list.forEach(function(key) { RSA_PublicPem[key] = fs.readFileSync(fixtures_keydir + '/rsa_public_' + key + '.pem'); RSA_PrivatePem[key] = fs.readFileSync(fixtures_keydir + '/rsa_private_' + key + '.pem'); }); var bench = common.createBenchmark(main, { n: [500], keylen: keylen_list, len: [16, 32, 64] }); function main(conf) { var crypto = require('crypto'); var message = (new Buffer(conf.len)).fill('b'); bench.start(); StreamWrite(conf.algo, conf.keylen, message, conf.n, conf.len); } function StreamWrite(algo, keylen, message, n, len) { var written = n * len; var bits = written * 8; var kbits = bits / (1024); var privateKey = RSA_PrivatePem[keylen]; var publicKey = RSA_PublicPem[keylen]; for (var i = 0; i < n; i++) { var enc = crypto.privateEncrypt(privateKey, message); var clear = crypto.publicDecrypt(publicKey, enc); } bench.end(kbits); } node-v4.2.6/benchmark/crypto/rsa-sign-verify-throughput.js000644 000766 000024 00000002762 12650222322 024015 0ustar00iojsstaff000000 000000 // throughput benchmark in signing and verifying var common = require('../common.js'); var crypto = require('crypto'); var fs = require('fs'); var path = require('path'); var fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/'); var keylen_list = ['1024', '2048']; var RSA_PublicPem = {}; var RSA_PrivatePem = {}; keylen_list.forEach(function(key) { RSA_PublicPem[key] = fs.readFileSync(fixtures_keydir + '/rsa_public_' + key + '.pem'); RSA_PrivatePem[key] = fs.readFileSync(fixtures_keydir + '/rsa_private_' + key + '.pem'); }); var bench = common.createBenchmark(main, { writes: [500], algo: ['RSA-SHA1', 'RSA-SHA224', 'RSA-SHA256', 'RSA-SHA384', 'RSA-SHA512'], keylen: keylen_list, len: [1024, 102400, 2 * 102400, 3 * 102400, 1024 * 1024] }); function main(conf) { var crypto = require('crypto'); var message = (new Buffer(conf.len)).fill('b'); bench.start(); StreamWrite(conf.algo, conf.keylen, message, conf.writes, conf.len); } function StreamWrite(algo, keylen, message, writes, len) { var written = writes * len; var bits = written * 8; var kbits = bits / (1024); var privateKey = RSA_PrivatePem[keylen]; var publicKey = RSA_PublicPem[keylen]; var s = crypto.createSign(algo); var v = crypto.createVerify(algo); while (writes-- > 0) { s.update(message); v.update(message); } var sign = s.sign(privateKey, 'binary'); s.end(); v.end(); bench.end(kbits); } node-v4.2.6/benchmark/buffers/buffer-base64-decode.js000644 000766 000024 00000000664 12650222322 022450 0ustar00iojsstaff000000 000000 var assert = require('assert'); var common = require('../common.js'); var bench = common.createBenchmark(main, {}); function main(conf) { for (var s = 'abcd'; s.length < 32 << 20; s += s); s.match(/./); // Flatten string. assert.equal(s.length % 4, 0); var b = Buffer(s.length / 4 * 3); b.write(s, 0, s.length, 'base64'); bench.start(); for (var i = 0; i < 32; i += 1) b.base64Write(s, 0, s.length); bench.end(32); } node-v4.2.6/benchmark/buffers/buffer-base64-encode.js000644 000766 000024 00000000601 12650222322 022451 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, {}); function main(conf) { var N = 64 * 1024 * 1024; var b = Buffer(N); var s = ''; for (var i = 0; i < 256; ++i) s += String.fromCharCode(i); for (var i = 0; i < N; i += 256) b.write(s, i, 256, 'ascii'); bench.start(); for (var i = 0; i < 32; ++i) b.toString('base64'); bench.end(64); } node-v4.2.6/benchmark/buffers/buffer-bytelength.js000644 000766 000024 00000002651 12650222322 022306 0ustar00iojsstaff000000 000000 var common = require('../common'); var bench = common.createBenchmark(main, { encoding: ['utf8', 'base64'], len: [1, 2, 4, 16, 64, 256], // x16 n: [5e6] }); // 16 chars each var chars = [ 'hello brendan!!!', // 1 byte 'ΰαβγδεζηθικλμνξο', // 2 bytes '挰挱挲挳挴挵挶挷挸挹挺挻挼挽挾挿', // 3 bytes '𠜎𠜱𠝹𠱓𠱸𠲖𠳏𠳕𠴕𠵼𠵿𠸎𠸏𠹷𠺝𠺢' // 4 bytes ]; function main(conf) { var n = conf.n | 0; var len = conf.len | 0; var encoding = conf.encoding; var strings = []; for (var string of chars) { // Strings must be built differently, depending on encoding var data = buildString(string, len); if (encoding === 'utf8') { strings.push(data); } else if (encoding === 'base64') { // Base64 strings will be much longer than their UTF8 counterparts strings.push(new Buffer(data, 'utf8').toString('base64')); } } // Check the result to ensure it is *properly* optimized var results = strings.map(function(val) { return Buffer.byteLength(val, encoding); }); bench.start(); for (var i = 0; i < n; i++) { var index = n % strings.length; // Go! var r = Buffer.byteLength(strings[index], encoding); if (r !== results[index]) throw Error('incorrect return value'); } bench.end(n); } function buildString(str, times) { if (times == 1) return str; return str + buildString(str, times - 1); } node-v4.2.6/benchmark/buffers/buffer-compare.js000644 000766 000024 00000000720 12650222322 021562 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { size: [16, 512, 1024, 4096, 16386], millions: [1] }); function main(conf) { var iter = (conf.millions >>> 0) * 1e6; var size = (conf.size >>> 0); var b0 = new Buffer(size).fill('a'); var b1 = new Buffer(size).fill('a'); b1[size - 1] = 'b'.charCodeAt(0); bench.start(); for (var i = 0; i < iter; i++) { Buffer.compare(b0, b1); } bench.end(iter / 1e6); } node-v4.2.6/benchmark/buffers/buffer-creation.js000644 000766 000024 00000000633 12650222322 021743 0ustar00iojsstaff000000 000000 SlowBuffer = require('buffer').SlowBuffer; var common = require('../common.js'); var bench = common.createBenchmark(main, { type: ['fast', 'slow'], len: [10, 1024], n: [1024] }); function main(conf) { var len = +conf.len; var n = +conf.n; var clazz = conf.type === 'fast' ? Buffer : SlowBuffer; bench.start(); for (var i = 0; i < n * 1024; i++) { b = new clazz(len); } bench.end(n); } node-v4.2.6/benchmark/buffers/buffer-indexof.js000644 000766 000024 00000002125 12650222322 021571 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var fs = require('fs'); var bench = common.createBenchmark(main, { search: ['@', 'SQ', '10x', '--l', 'Alice', 'Gryphon', 'Panther', 'Ou est ma chatte?', 'found it very', 'among mad people', 'neighbouring pool', 'Soo--oop', 'aaaaaaaaaaaaaaaaa', 'venture to go near the house till she had brought herself down to', ' to the Caterpillar'], encoding: ['undefined', 'utf8', 'ucs2', 'binary'], type: ['buffer', 'string'], iter: [1] }); function main(conf) { var iter = (conf.iter) * 100000; var aliceBuffer = fs.readFileSync(__dirname + '/../fixtures/alice.html'); var search = conf.search; var encoding = conf.encoding; if (encoding === 'undefined') { encoding = undefined; } if (encoding === 'ucs2') { aliceBuffer = new Buffer(aliceBuffer.toString(), encoding); } if (conf.type === 'buffer') { search = new Buffer(new Buffer(search).toString(), encoding); } bench.start(); for (var i = 0; i < iter; i++) { aliceBuffer.indexOf(search, 0, encoding); } bench.end(iter); } node-v4.2.6/benchmark/buffers/buffer-iterate.js000644 000766 000024 00000002207 12650222322 021573 0ustar00iojsstaff000000 000000 var SlowBuffer = require('buffer').SlowBuffer; var common = require('../common.js'); var assert = require('assert'); var bench = common.createBenchmark(main, { size: [16, 512, 1024, 4096, 16386], type: ['fast', 'slow'], method: ['for', 'forOf', 'iterator'], n: [1e3] }); var methods = { 'for': benchFor, 'forOf': benchForOf, 'iterator': benchIterator }; function main(conf) { var len = +conf.size; var clazz = conf.type === 'fast' ? Buffer : SlowBuffer; var buffer = new clazz(len); buffer.fill(0); methods[conf.method](buffer, conf.n); } function benchFor(buffer, n) { bench.start(); for (var k = 0; k < n; k++) for (var i = 0; i < buffer.length; i++) assert(buffer[i] === 0); bench.end(n); } function benchForOf(buffer, n) { bench.start(); for (var k = 0; k < n; k++) for (var b of buffer) assert(b === 0); bench.end(n); } function benchIterator(buffer, n) { bench.start(); for (var k = 0; k < n; k++) { var iter = buffer[Symbol.iterator](); var cur = iter.next(); while (!cur.done) { assert(cur.value === 0); cur = iter.next(); } } bench.end(n); } node-v4.2.6/benchmark/buffers/buffer-read.js000644 000766 000024 00000001565 12650222322 021057 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { noAssert: [false, true], buffer: ['fast', 'slow'], type: ['UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE', 'Int8', 'Int16LE', 'Int16BE', 'Int32LE', 'Int32BE', 'FloatLE', 'FloatBE', 'DoubleLE', 'DoubleBE'], millions: [1] }); function main(conf) { var noAssert = conf.noAssert === 'true'; var len = +conf.millions * 1e6; var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer; var buff = new clazz(8); var fn = 'read' + conf.type; buff.writeDoubleLE(0, 0, noAssert); var testFunction = new Function('buff', [ "for (var i = 0; i !== " + len + "; i++) {", " buff." + fn + "(0, " + JSON.stringify(noAssert) + ");", "}" ].join("\n")); bench.start(); testFunction(buff); bench.end(len / 1e6); } node-v4.2.6/benchmark/buffers/buffer-slice.js000644 000766 000024 00000000652 12650222322 021237 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var SlowBuffer = require('buffer').SlowBuffer; var bench = common.createBenchmark(main, { type: ['fast', 'slow'], n: [1024] }); var buf = new Buffer(1024); var slowBuf = new SlowBuffer(1024); function main(conf) { var n = +conf.n; var b = conf.type === 'fast' ? buf : slowBuf; bench.start(); for (var i = 0; i < n * 1024; i++) { b.slice(10, 256); } bench.end(n); } node-v4.2.6/benchmark/buffers/buffer-tostring.js000644 000766 000024 00000000742 12650222322 022011 0ustar00iojsstaff000000 000000 'use strict'; const common = require('../common.js'); const bench = common.createBenchmark(main, { arg: [true, false], len: [0, 1, 64, 1024], n: [1e7] }); function main(conf) { const arg = conf.arg; const len = conf.len | 0; const n = conf.n | 0; const buf = Buffer(len).fill(42); bench.start(); if (arg) { for (var i = 0; i < n; i += 1) buf.toString('utf8'); } else { for (var i = 0; i < n; i += 1) buf.toString(); } bench.end(n); } node-v4.2.6/benchmark/buffers/buffer-write.js000644 000766 000024 00000003315 12650222322 021271 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { noAssert: [false, true], buffer: ['fast', 'slow'], type: ['UInt8', 'UInt16LE', 'UInt16BE', 'UInt32LE', 'UInt32BE', 'Int8', 'Int16LE', 'Int16BE', 'Int32LE', 'Int32BE', 'FloatLE', 'FloatBE', 'DoubleLE', 'DoubleBE'], millions: [1] }); const INT8 = 0x7f; const INT16 = 0x7fff; const INT32 = 0x7fffffff; const UINT8 = (INT8 * 2) + 1; const UINT16 = (INT16 * 2) + 1; const UINT32 = INT32; var mod = { writeInt8: INT8, writeInt16BE: INT16, writeInt16LE: INT16, writeInt32BE: INT32, writeInt32LE: INT32, writeUInt8: UINT8, writeUInt16BE: UINT16, writeUInt16LE: UINT16, writeUInt32BE: UINT32, writeUInt32LE: UINT32 }; function main(conf) { var noAssert = conf.noAssert === 'true'; var len = +conf.millions * 1e6; var clazz = conf.buf === 'fast' ? Buffer : require('buffer').SlowBuffer; var buff = new clazz(8); var fn = 'write' + conf.type; if (fn.match(/Int/)) benchInt(buff, fn, len, noAssert); else benchFloat(buff, fn, len, noAssert); } function benchInt(buff, fn, len, noAssert) { var m = mod[fn]; var testFunction = new Function('buff', [ "for (var i = 0; i !== " + len + "; i++) {", " buff." + fn + "(i & " + m + ", 0, " + JSON.stringify(noAssert) + ");", "}" ].join("\n")); bench.start(); testFunction(buff); bench.end(len / 1e6); } function benchFloat(buff, fn, len, noAssert) { var testFunction = new Function('buff', [ "for (var i = 0; i !== " + len + "; i++) {", " buff." + fn + "(i, 0, " + JSON.stringify(noAssert) + ");", "}" ].join("\n")); bench.start(); testFunction(buff); bench.end(len / 1e6); } node-v4.2.6/benchmark/buffers/buffer_zero.js000644 000766 000024 00000000440 12650222322 021174 0ustar00iojsstaff000000 000000 'use strict'; const common = require('../common.js'); const bench = common.createBenchmark(main, { n: [1024] }); const zero = new Buffer(0); function main(conf) { var n = +conf.n; bench.start(); for (let i = 0; i < n * 1024; i++) { new Buffer(zero); } bench.end(n); } node-v4.2.6/benchmark/buffers/dataview-set.js000644 000766 000024 00000002301 12650222322 021257 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { type: ['Uint8', 'Uint16LE', 'Uint16BE', 'Uint32LE', 'Uint32BE', 'Int8', 'Int16LE', 'Int16BE', 'Int32LE', 'Int32BE', 'Float32LE', 'Float32BE', 'Float64LE', 'Float64BE'], millions: [1] }); const INT8 = 0x7f; const INT16 = 0x7fff; const INT32 = 0x7fffffff; const UINT8 = INT8 * 2; const UINT16 = INT16 * 2; const UINT32 = INT32 * 2; var mod = { setInt8: INT8, setInt16: INT16, setInt32: INT32, setUint8: UINT8, setUint16: UINT16, setUint32: UINT32 }; function main(conf) { var len = +conf.millions * 1e6; var ab = new ArrayBuffer(8); var dv = new DataView(ab, 0, 8); var le = /LE$/.test(conf.type); var fn = 'set' + conf.type.replace(/[LB]E$/, ''); if (/int/i.test(fn)) benchInt(dv, fn, len, le); else benchFloat(dv, fn, len, le); } function benchInt(dv, fn, len, le) { var m = mod[fn]; bench.start(); for (var i = 0; i < len; i++) { dv[fn](0, i % m, le); } bench.end(len / 1e6); } function benchFloat(dv, fn, len, le) { bench.start(); for (var i = 0; i < len; i++) { dv[fn](0, i * 0.1, le); } bench.end(len / 1e6); } node-v4.2.6/benchmark/assert/deepequal-prims-and-objs-big-array.js000644 000766 000024 00000001215 12650222322 025175 0ustar00iojsstaff000000 000000 'use strict'; var common = require('../common.js'); var assert = require('assert'); var bench = common.createBenchmark(main, { prim: [ null, undefined, 'a', 1, true, {0: 'a'}, [1, 2, 3], new Array([1, 2, 3]) ], n: [25] }); function main(conf) { var prim = conf.prim; var n = +conf.n; var primArray; var primArrayCompare; var x; primArray = new Array(); primArrayCompare = new Array(); for (x = 0; x < (1e5); x++) { primArray.push(prim); primArrayCompare.push(prim); } bench.start(); for (x = 0; x < n; x++) { assert.deepEqual(primArray, primArrayCompare); } bench.end(n); } node-v4.2.6/benchmark/assert/deepequal-prims-and-objs-big-loop.js000644 000766 000024 00000000723 12650222322 025033 0ustar00iojsstaff000000 000000 'use strict'; var common = require('../common.js'); var assert = require('assert'); var bench = common.createBenchmark(main, { prim: [ null, undefined, 'a', 1, true, {0: 'a'}, [1, 2, 3], new Array([1, 2, 3]) ], n: [1e5] }); function main(conf) { var prim = conf.prim; var n = +conf.n; var x; bench.start(); for (x = 0; x < n; x++) { assert.deepEqual(new Array([prim]), new Array([prim])); } bench.end(n); } node-v4.2.6/benchmark/assert/deepequal-typedarrays.js000644 000766 000024 00000001016 12650222322 023043 0ustar00iojsstaff000000 000000 'use strict'; var common = require('../common.js'); var assert = require('assert'); var bench = common.createBenchmark(main, { type: ('Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array ' + 'Float32Array Float64Array Uint8ClampedArray').split(' '), n: [1] }); function main(conf) { var type = conf.type; var clazz = global[type]; var n = +conf.n; bench.start(); var actual = new clazz(n * 1e6); var expected = new clazz(n * 1e6); assert.deepEqual(actual, expected); bench.end(n); } node-v4.2.6/benchmark/arrays/var-int.js000644 000766 000024 00000000774 12650222322 020123 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '), n: [25] }); function main(conf) { var type = conf.type; var clazz = global[type]; var n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); for (var i = 0; i < 10; ++i) { for (var j = 0, k = arr.length; j < k; ++j) { arr[j] = (j ^ k) & 127; } } bench.end(n); } node-v4.2.6/benchmark/arrays/zero-float.js000644 000766 000024 00000000762 12650222322 020622 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '), n: [25] }); function main(conf) { var type = conf.type; var clazz = global[type]; var n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); for (var i = 0; i < 10; ++i) { for (var j = 0, k = arr.length; j < k; ++j) { arr[j] = 0.0; } } bench.end(n); } node-v4.2.6/benchmark/arrays/zero-int.js000644 000766 000024 00000000760 12650222322 020305 0ustar00iojsstaff000000 000000 var common = require('../common.js'); var bench = common.createBenchmark(main, { type: 'Array Buffer Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split(' '), n: [25] }); function main(conf) { var type = conf.type; var clazz = global[type]; var n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); for (var i = 0; i < 10; ++i) { for (var j = 0, k = arr.length; j < k; ++j) { arr[j] = 0; } } bench.end(n); }